diff --git a/dmc-lib/src/ast/call.rs b/dmc-lib/src/ast/call.rs index 506edfa..beeb81e 100644 --- a/dmc-lib/src/ast/call.rs +++ b/dmc-lib/src/ast/call.rs @@ -10,10 +10,10 @@ use crate::diagnostic_factories::{ use crate::ir::ir_call::IrCall; use crate::ir::ir_expression::IrExpression; use crate::source_range::SourceRange; +use crate::symbol::Symbol; use crate::symbol::callable_symbol::CallableSymbol; use crate::symbol::class_symbol::ClassSymbol; use crate::symbol::expressible_symbol::ExpressibleSymbol; -use crate::symbol::Symbol; use crate::symbol_table::SymbolTable; use crate::type_info::TypeInfo; use crate::types_table::TypesTable; diff --git a/dmc-lib/src/ast/identifier.rs b/dmc-lib/src/ast/identifier.rs index dd661aa..4b59564 100644 --- a/dmc-lib/src/ast/identifier.rs +++ b/dmc-lib/src/ast/identifier.rs @@ -75,6 +75,7 @@ impl Identifier { (names_table, diagnostics) } + /// Resolves the name inside an initializer for a field *outside* a constructor. pub fn resolve_name_field_init( &self, symbol_table: &SymbolTable, @@ -125,6 +126,7 @@ impl Identifier { (names_table, diagnostics) } + /// Resolves the name as used in a rhs expression in a constructor. pub fn resolve_name_ctor( &self, symbol_table: &SymbolTable, @@ -173,6 +175,7 @@ impl Identifier { (names_table, diagnostics) } + /// Resolves the name as an LValue in a constructor. pub fn resolve_name_ctor_destination( &self, symbol_table: &SymbolTable, @@ -650,3 +653,51 @@ impl Identifier { } } } + +#[cfg(test)] +mod tests { + use crate::ast::identifier::Identifier; + use crate::source_range::SourceRange; + use crate::symbol::Symbol; + use crate::symbol::variable_symbol::VariableSymbol; + use crate::symbol_table::SymbolTable; + use std::rc::Rc; + + #[test] + fn inits_scope_id() { + let mut identifier = Identifier::new(0, "foo", SourceRange::new(0, 0)); + identifier.init_scope_id(42); + assert_eq!(identifier.scope_id(), 42); + } + + #[test] + fn resolves_static_foo() { + let mut identifier = Identifier::new(0, "foo", SourceRange::new(0, 0)); + + let mut symbol_table = SymbolTable::new(); + symbol_table.push_module_scope("foo module"); + symbol_table.push_function_scope("foo function"); + let scope_id = symbol_table.push_block_scope("foo block"); + identifier.init_scope_id(scope_id); + + let variable_symbol = Rc::new(VariableSymbol::new( + &"foo".into(), + &SourceRange::new(0, 0), + false, + scope_id, + )); + symbol_table.insert_variable_symbol(variable_symbol.clone()); + + let (nodes_to_symbols, diagnostics) = identifier.resolve_name_static(&symbol_table); + + assert_eq!(diagnostics.len(), 0); + assert_eq!(nodes_to_symbols.len(), 1); + let symbol = nodes_to_symbols.get(&identifier.node_id()).unwrap(); + match symbol { + Symbol::Variable(matched_variable_symbol) => { + assert_eq!(&variable_symbol, matched_variable_symbol); + } + _ => panic!(), + } + } +} diff --git a/dmc-lib/src/symbol/variable_symbol.rs b/dmc-lib/src/symbol/variable_symbol.rs index 0196ea1..ca16ca6 100644 --- a/dmc-lib/src/symbol/variable_symbol.rs +++ b/dmc-lib/src/symbol/variable_symbol.rs @@ -1,4 +1,5 @@ use crate::source_range::SourceRange; +use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; use std::rc::Rc; @@ -59,3 +60,13 @@ impl Hash for VariableSymbol { self.scope_id.hash(state); } } + +impl Debug for VariableSymbol { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "VariableSymbol({:?}, {})", + self.declared_name, self.scope_id + ) + } +}