This commit is contained in:
bQUARKz 2026-02-04 19:22:45 +00:00
parent 737780d7d5
commit bb1372aa65
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
2 changed files with 16 additions and 24 deletions

View File

@ -1,15 +1,16 @@
use crate::common::diagnostics::Diagnostic; use crate::common::diagnostics::Diagnostic;
use crate::frontends::pbs::ast::{AstArena, NodeKind}; use crate::frontends::pbs::ast::{AstArena, NodeKind};
use crate::analysis::symbols::{Symbol, SymbolArena, SymbolKind, DefIndex, DefKey, Namespace}; use crate::analysis::symbols::{Symbol, SymbolArena, SymbolKind, DefIndex, DefKey, Namespace, NodeToSymbol};
use prometeu_analysis::NameInterner; use prometeu_analysis::NameInterner;
pub fn build_def_index( pub fn build_def_index(
arena: &AstArena, arena: &AstArena,
module: u32, module: u32,
_interner: &NameInterner, _interner: &NameInterner,
) -> (SymbolArena, DefIndex, Vec<Diagnostic>) { ) -> (SymbolArena, DefIndex, NodeToSymbol, Vec<Diagnostic>) {
let mut symbols = SymbolArena::new(); let mut symbols = SymbolArena::new();
let mut index = DefIndex::new(); let mut index = DefIndex::new();
let mut node_to_symbol = NodeToSymbol::new();
let mut diagnostics = Vec::new(); let mut diagnostics = Vec::new();
// No PBS, o root costuma ser um NodeKind::File que contém imports e decls. // No PBS, o root costuma ser um NodeKind::File que contém imports e decls.
@ -50,6 +51,7 @@ pub fn build_def_index(
}; };
let symbol_id = symbols.insert(symbol); let symbol_id = symbols.insert(symbol);
node_to_symbol.bind_node(decl_id, symbol_id);
let key = DefKey { let key = DefKey {
module, module,
name, name,
@ -65,7 +67,7 @@ pub fn build_def_index(
} }
} }
(symbols, index, diagnostics) (symbols, index, node_to_symbol, diagnostics)
} }
#[cfg(test)] #[cfg(test)]
@ -108,7 +110,7 @@ mod tests {
arena.roots.push(file_id); arena.roots.push(file_id);
let (symbols, index, diagnostics) = build_def_index(&arena, 1, &interner); let (symbols, index, _node_to_symbol, diagnostics) = build_def_index(&arena, 1, &interner);
assert!(diagnostics.is_empty()); assert!(diagnostics.is_empty());
assert_eq!(symbols.symbols.len(), 2); assert_eq!(symbols.symbols.len(), 2);
@ -158,7 +160,7 @@ mod tests {
arena.roots.push(file_id); arena.roots.push(file_id);
let (_symbols, _index, diagnostics) = build_def_index(&arena, 1, &interner); let (_symbols, _index, _node_to_symbol, diagnostics) = build_def_index(&arena, 1, &interner);
assert_eq!(diagnostics.len(), 1); assert_eq!(diagnostics.len(), 1);
assert_eq!(diagnostics[0].code, Some("E_RESOLVE_DUPLICATE_SYMBOL".to_string())); assert_eq!(diagnostics[0].code, Some("E_RESOLVE_DUPLICATE_SYMBOL".to_string()));
@ -166,41 +168,31 @@ mod tests {
} }
#[test] #[test]
fn test_deterministic_order() { fn test_node_to_symbol_binding() {
let mut arena = AstArena::default(); let mut arena = AstArena::default();
let mut interner = NameInterner::new(); let mut interner = NameInterner::new();
let name_a = interner.intern("a"); let name = interner.intern("bound_func");
let name_b = interner.intern("b"); let decl_id = arena.push(NodeKind::FnDecl(FnDeclNodeArena {
let decl_a = arena.push(NodeKind::FnDecl(FnDeclNodeArena {
vis: None, vis: None,
name: name_a, name,
params: vec![], params: vec![],
ret: None, ret: None,
else_fallback: None, else_fallback: None,
body: NodeId(0), body: NodeId(0),
}), Span::new(0, 10, 20)); }), Span::new(0, 10, 20));
let decl_b = arena.push(NodeKind::FnDecl(FnDeclNodeArena {
vis: None,
name: name_b,
params: vec![],
ret: None,
else_fallback: None,
body: NodeId(0),
}), Span::new(0, 30, 40));
let file_id = arena.push(NodeKind::File(FileNodeArena { let file_id = arena.push(NodeKind::File(FileNodeArena {
imports: vec![], imports: vec![],
decls: vec![decl_a, decl_b], decls: vec![decl_id],
}), Span::new(0, 0, 100)); }), Span::new(0, 0, 100));
arena.roots.push(file_id); arena.roots.push(file_id);
let (symbols, _, _) = build_def_index(&arena, 1, &interner); let (symbols, _index, node_to_symbol, _diagnostics) = build_def_index(&arena, 1, &interner);
assert_eq!(symbols.symbols[0].name, name_a); let symbol_id = node_to_symbol.get(decl_id).expect("Node should be bound to a symbol");
assert_eq!(symbols.symbols[1].name, name_b); let symbol = symbols.get(symbol_id);
assert_eq!(symbol.name, name);
} }
} }