From e578250ee652b5f00f71700464070edd0484cefd Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 2 Oct 2025 10:08:03 -0500 Subject: [PATCH] WIP name analysis. --- src/name_analysis/gather.rs | 80 +++++++++++++++---- .../{symbol.rs => symbol/mod.rs} | 36 +-------- src/name_analysis/symbol/source_definition.rs | 42 ++++++++++ src/name_analysis/symbol/use_symbol.rs | 28 +++++++ 4 files changed, 139 insertions(+), 47 deletions(-) rename src/name_analysis/{symbol.rs => symbol/mod.rs} (94%) create mode 100644 src/name_analysis/symbol/source_definition.rs create mode 100644 src/name_analysis/symbol/use_symbol.rs diff --git a/src/name_analysis/gather.rs b/src/name_analysis/gather.rs index b19390b..e753f74 100644 --- a/src/name_analysis/gather.rs +++ b/src/name_analysis/gather.rs @@ -1,25 +1,62 @@ -use std::collections::HashMap; -use crate::ast::ast_node::AstNodeRef; -use crate::ast::node::{CompilationUnit, Identifier}; -use crate::ast::walk::walk_depth_first; +use crate::ast::ast_node::{AstNode, AstNodeRef}; +use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix}; use crate::diagnostic::DmDiagnostic; +use crate::name_analysis::symbol::source_definition::SourceDefinition; +use crate::name_analysis::symbol::use_symbol::StarUseStatementSymbol; +use crate::name_analysis::symbol::UseStatementSymbol; use crate::name_analysis::symbol_table::SymbolTable; +use std::collections::HashMap; -fn gather_identifier(identifier: &Identifier, symbol_table: &SymbolTable, identifier_scope_ids: &mut HashMap) { +fn gather_identifier( + identifier: &Identifier, + symbol_table: &SymbolTable, + identifier_scope_ids: &mut HashMap, +) { identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id()); } -pub fn gather_compilation_unit( - compilation_unit: &mut CompilationUnit, +fn gather_use_statement( + use_statement: &UseStatement, symbol_table: &mut SymbolTable, - identifier_scope_ids: &mut HashMap, diagnostics: &mut Vec, ) { - walk_depth_first(compilation_unit, &mut |child| match child { - AstNodeRef::Operator(_) => {} - AstNodeRef::Identifier(identifier) => { - gather_identifier(&identifier, symbol_table, identifier_scope_ids); + let mut fully_qualified_name = String::new(); + for prefix in use_statement.prefixes() { + fully_qualified_name.push_str(&format!("{}::", prefix.identifier().name())); + } + match use_statement.suffix() { + UseStatementSuffix::Identifier(identifier) => {} + UseStatementSuffix::Star => { + let symbol_inner = StarUseStatementSymbol::new( + &fully_qualified_name, + Some(SourceDefinition::from_use_statement(use_statement)), + ); + let symbol = UseStatementSymbol::Star(symbol_inner); + symbol_table.insert_use_statement_symbol(symbol); + todo!() } + UseStatementSuffix::UseList(use_list) => {} + } +} + +fn gather_node_children( + node: &impl AstNode, + symbol_table: &mut SymbolTable, + diagnostics: &mut Vec, +) { + for child in node.children() { + gather_node(child, symbol_table, diagnostics); + } +} + +fn gather_node( + node: AstNodeRef, + symbol_table: &mut SymbolTable, + diagnostics: &mut Vec, +) { + match node { + AstNodeRef::Operator(_) => {} + AstNodeRef::Identifier(_) => {} AstNodeRef::FullyQualifiedName(_) => {} AstNodeRef::TypeUseList(_) => {} AstNodeRef::IdentifierList(_) => {} @@ -37,9 +74,13 @@ pub fn gather_compilation_unit( AstNodeRef::Parameters(_) => {} AstNodeRef::Parameter(_) => {} AstNodeRef::ReturnType(_) => {} - AstNodeRef::CompilationUnit(_) => {} + AstNodeRef::CompilationUnit(compilation_unit) => { + gather_node_children(compilation_unit, symbol_table, diagnostics); + } AstNodeRef::ParentMod(_) => {} - AstNodeRef::UseStatement(_) => {} + AstNodeRef::UseStatement(use_statement) => { + gather_use_statement(use_statement, symbol_table, diagnostics); + } AstNodeRef::UseStatementPrefix(_) => {} AstNodeRef::UseStatementSuffix(_) => {} AstNodeRef::UseList(_) => {} @@ -111,5 +152,14 @@ pub fn gather_compilation_unit( AstNodeRef::DString(_) => {} AstNodeRef::DStringExpression(_) => {} AstNodeRef::BacktickString(_) => {} - }); + } +} + +pub fn gather_compilation_unit( + compilation_unit: &mut CompilationUnit, + symbol_table: &mut SymbolTable, + identifier_scope_ids: &mut HashMap, + diagnostics: &mut Vec, +) { + gather_node(compilation_unit.as_node_ref(), symbol_table, diagnostics); } diff --git a/src/name_analysis/symbol.rs b/src/name_analysis/symbol/mod.rs similarity index 94% rename from src/name_analysis/symbol.rs rename to src/name_analysis/symbol/mod.rs index 351f1ed..b13e2ef 100644 --- a/src/name_analysis/symbol.rs +++ b/src/name_analysis/symbol/mod.rs @@ -1,41 +1,13 @@ +pub(super) mod source_definition; +pub(super) mod use_symbol; + use crate::ast::node::Identifier; +use source_definition::SourceDefinition; use std::cell::RefCell; use std::fmt::{Debug, Display, Formatter}; use std::ops::Deref; -use std::range::Range; use std::rc::Rc; -#[derive(Clone, Debug)] -pub struct SourceDefinition { - file_id: usize, - range: Range, -} - -impl SourceDefinition { - pub fn from_identifier(identifier: &Identifier) -> Self { - SourceDefinition { - file_id: identifier.file_id(), - range: identifier.range(), - } - } - - pub fn from_identifier_rc(identifier: Rc>) -> Self { - let borrowed = identifier.borrow(); - SourceDefinition { - file_id: borrowed.file_id(), - range: borrowed.range(), - } - } - - pub fn file_id(&self) -> usize { - self.file_id - } - - pub fn range(&self) -> Range { - self.range.clone() - } -} - pub trait SymbolInner { fn declared_name(&self) -> &str; fn definition(&self) -> Option; diff --git a/src/name_analysis/symbol/source_definition.rs b/src/name_analysis/symbol/source_definition.rs new file mode 100644 index 0000000..60aeb0f --- /dev/null +++ b/src/name_analysis/symbol/source_definition.rs @@ -0,0 +1,42 @@ +use std::cell::RefCell; +use std::range::Range; +use std::rc::Rc; +use crate::ast::node::{Identifier, UseStatement}; + +#[derive(Clone, Debug)] +pub struct SourceDefinition { + file_id: usize, + range: Range, +} + +impl SourceDefinition { + pub fn from_identifier(identifier: &Identifier) -> Self { + SourceDefinition { + file_id: identifier.file_id(), + range: identifier.range(), + } + } + + pub fn from_identifier_rc(identifier: Rc>) -> Self { + let borrowed = identifier.borrow(); + SourceDefinition { + file_id: borrowed.file_id(), + range: borrowed.range(), + } + } + + pub fn from_use_statement(use_statement: &UseStatement) -> Self { + Self { + file_id: use_statement.file_id(), + range: use_statement.range(), + } + } + + pub fn file_id(&self) -> usize { + self.file_id + } + + pub fn range(&self) -> Range { + self.range.clone() + } +} \ No newline at end of file diff --git a/src/name_analysis/symbol/use_symbol.rs b/src/name_analysis/symbol/use_symbol.rs new file mode 100644 index 0000000..c6c6610 --- /dev/null +++ b/src/name_analysis/symbol/use_symbol.rs @@ -0,0 +1,28 @@ +use crate::name_analysis::symbol::source_definition::SourceDefinition; + +pub enum UseStatementSymbol { + Concrete, + Star(StarUseStatementSymbol), +} + +pub struct StarUseStatementSymbol { + base_fqn: String, + source_definition: Option, +} + +impl StarUseStatementSymbol { + pub fn new(base_fqn: &str, source_definition: Option) -> Self { + Self { + base_fqn: base_fqn.to_string(), + source_definition, + } + } + + pub fn base_fqn(&self) -> &str { + &self.base_fqn + } + + pub fn source_definition(&self) -> Option<&SourceDefinition> { + self.source_definition.as_ref() + } +}