brink_ir/symbols/index.rs
1use std::collections::HashMap;
2
3use brink_format::{DefinitionId, DefinitionTag};
4use rowan::TextRange;
5
6use crate::FileId;
7
8// ─── Symbol index ───────────────────────────────────────────────────
9
10/// The unified symbol table produced by merging per-file manifests and
11/// resolving references.
12#[derive(Debug, Clone, Default)]
13pub struct SymbolIndex {
14 /// All known definitions across all files.
15 pub symbols: HashMap<DefinitionId, SymbolInfo>,
16 /// Reverse index from canonical name to definition IDs.
17 pub by_name: HashMap<String, Vec<DefinitionId>>,
18}
19
20/// Metadata for a resolved symbol.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct SymbolInfo {
23 /// What kind of symbol this is.
24 pub kind: SymbolKind,
25 /// Which file declared it.
26 pub file: FileId,
27 /// Source span of the declaration.
28 pub range: TextRange,
29 /// The tagged definition id.
30 pub id: DefinitionId,
31 /// The canonical/qualified name.
32 pub name: String,
33 /// Parameter names (for knots, stitches, externals).
34 pub params: Vec<ParamInfo>,
35 /// Additional detail (e.g. "function" for function knots).
36 pub detail: Option<String>,
37 /// Scope context — `Some` for locals (params/temps), `None` for globals.
38 pub scope: Option<Scope>,
39 /// For `Param` symbols: ref/divert metadata from the parent declaration.
40 pub param_detail: Option<ParamInfo>,
41}
42
43/// Parameter metadata for hover/signature help.
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct ParamInfo {
46 /// Parameter name.
47 pub name: String,
48 /// `ref` parameter — passed by reference.
49 pub is_ref: bool,
50 /// `->` parameter — divert target.
51 pub is_divert: bool,
52}
53
54/// The kind of a declared symbol.
55#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
56pub enum SymbolKind {
57 Knot,
58 Stitch,
59 Variable,
60 Constant,
61 List,
62 ListItem,
63 External,
64 Label,
65 /// A knot/stitch/function parameter.
66 Param,
67 /// A `~ temp` local variable.
68 Temp,
69}
70
71impl SymbolKind {
72 /// Map a `SymbolKind` to the corresponding `DefinitionTag` for id generation.
73 pub fn definition_tag(self) -> DefinitionTag {
74 match self {
75 Self::Knot | Self::Stitch | Self::Label => DefinitionTag::Address,
76 Self::Variable | Self::Constant => DefinitionTag::GlobalVar,
77 Self::List => DefinitionTag::ListDef,
78 Self::ListItem => DefinitionTag::ListItem,
79 Self::External => DefinitionTag::ExternalFn,
80 Self::Param | Self::Temp => DefinitionTag::LocalVar,
81 }
82 }
83}
84
85// ─── Resolution types ───────────────────────────────────────────────
86
87/// A resolved reference: a use-site that has been matched to a definition.
88#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct ResolvedRef {
90 /// Which file the reference appears in.
91 pub file: FileId,
92 /// Source span of the reference.
93 pub range: TextRange,
94 /// The definition this reference resolves to.
95 pub target: DefinitionId,
96}
97
98/// Maps reference use-sites to their resolved definitions, with file provenance.
99pub type ResolutionMap = Vec<ResolvedRef>;
100
101/// Resolution context — identifies the current knot/stitch for relative
102/// path lookup.
103#[derive(Debug, Clone, Default, PartialEq, Eq)]
104pub struct Scope {
105 /// The current knot name, if any.
106 pub knot: Option<String>,
107 /// The current stitch name, if any.
108 pub stitch: Option<String>,
109}