WIP variety of name-analysis things.

This commit is contained in:
Jesse Brault 2025-10-27 19:47:57 -05:00
parent 8b374e1066
commit 5721bd1e83
16 changed files with 302 additions and 113 deletions

View File

@ -116,6 +116,7 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
use std::range::Range; use std::range::Range;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use crate::name_analysis::symbol::type_symbol::*;
use crate::name_analysis::symbol::use_symbol::*; use crate::name_analysis::symbol::use_symbol::*;
#(#types)* #(#types)*

View File

@ -1,18 +1,21 @@
use crate::ast::node::{ use crate::ast::node::{
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody, CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
Identifier, Module, ModuleLevelDeclaration, Parameters, ReturnType, TypeUse, UseStatement, GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
UseStatementIdentifier, UseStatementPrefix, PrimitiveType, ReturnType, TypeUse, TypedArray, UseStatement, UseStatementIdentifier,
UseStatementPrefix,
}; };
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol::function_symbol::FunctionSymbol; use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol; use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
use crate::name_analysis::symbol::module_symbol::ModuleSymbol; use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol; use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
use crate::name_analysis::type_use_container::TypeUseContainer; use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error};
use crate::name_analysis::util::handle_insert_error;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -23,13 +26,15 @@ pub fn na_p1_compilation_unit(
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
if let Some(namespace) = compilation_unit.namespace() { if let Some(namespace) = compilation_unit.namespace() {
symbol_table.set_current_fqn( match namespace.identifier_or_fqn() {
&namespace IdentifierOrFqn::Identifier(identifier) => {
.fqn() symbol_table.set_current_fqn(&[identifier.name()])
.identifiers() }
.map(Identifier::name) IdentifierOrFqn::FullyQualifiedName(fqn) => {
.collect::<Vec<_>>(), symbol_table
); .set_current_fqn(&fqn.identifiers().map(Identifier::name).collect::<Vec<_>>());
}
}
} }
symbol_table.push_scope(&format!("FileScope {}", file_name)); symbol_table.push_scope(&format!("FileScope {}", file_name));
@ -214,16 +219,22 @@ fn na_p1_function(
Ok(function_symbol) => { Ok(function_symbol) => {
{ {
let mut as_ref_mut = function_symbol.borrow_mut(); let mut as_ref_mut = function_symbol.borrow_mut();
// generics
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
// parameters
as_ref_mut.set_parameter_symbols(na_p1_parameters( as_ref_mut.set_parameter_symbols(na_p1_parameters(
function.parameters_mut(), function.parameters_mut(),
symbol_table, symbol_table,
diagnostics, diagnostics,
)); ));
as_ref_mut.set_return_type(na_p1_return_type(
function.return_type_mut(), // return type
symbol_table, let return_type =
diagnostics, na_p1_return_type(function.return_type_mut(), symbol_table, diagnostics);
)) if let Some(type_symbol) = return_type {
as_ref_mut.set_return_type(type_symbol);
}
} }
Some(function_symbol) Some(function_symbol)
} }
@ -256,7 +267,7 @@ fn na_p1_return_type(
return_type: &mut ReturnType, return_type: &mut ReturnType,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) -> Rc<RefCell<TypeUseContainer>> { ) -> Option<TypeSymbol> {
na_p1_type_use(return_type.type_use_mut(), symbol_table, diagnostics) na_p1_type_use(return_type.type_use_mut(), symbol_table, diagnostics)
} }
@ -264,13 +275,68 @@ fn na_p1_type_use(
type_use: &mut TypeUse, type_use: &mut TypeUse,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) -> Rc<RefCell<TypeUseContainer>> { ) -> Option<TypeSymbol> {
match type_use { match type_use {
TypeUse::PrimitiveType(primitive_type) => { TypeUse::PrimitiveType(primitive_type) => {
todo!() Some(TypeSymbol::Primitive(match primitive_type {
PrimitiveType::Byte => PrimitiveTypeSymbol::Byte,
PrimitiveType::Short => PrimitiveTypeSymbol::Short,
PrimitiveType::Char => PrimitiveTypeSymbol::Char,
PrimitiveType::Int => PrimitiveTypeSymbol::Int,
PrimitiveType::Long => PrimitiveTypeSymbol::Long,
PrimitiveType::Double => PrimitiveTypeSymbol::Double,
PrimitiveType::Bool => PrimitiveTypeSymbol::Boolean,
PrimitiveType::String => PrimitiveTypeSymbol::String,
PrimitiveType::TypedArray(typed_array) => {
na_p1_typed_array(typed_array, symbol_table, diagnostics)
}
PrimitiveType::Any => PrimitiveTypeSymbol::Any,
PrimitiveType::Void => PrimitiveTypeSymbol::Void,
}))
} }
TypeUse::InterfaceOrClassTypeUse(interface_or_class_type) => { TypeUse::InterfaceOrClassTypeUse(interface_or_class_type) => {
todo!() match interface_or_class_type.identifier_or_fqn() {
IdentifierOrFqn::Identifier(identifier) => {
match symbol_table.lookup_type(identifier.name()) {
Ok(type_symbol) => {
interface_or_class_type.set_type_symbol(type_symbol.clone());
Some(type_symbol)
}
Err(symbol_lookup_error) => {
handle_lookup_error(
symbol_lookup_error,
identifier.name(),
identifier.file_id(),
identifier.range(),
diagnostics,
);
None
}
}
}
IdentifierOrFqn::FullyQualifiedName(fqn) => {
let fqn_parts = fqn
.identifiers()
.map(Identifier::name)
.collect::<Vec<&str>>();
match symbol_table.lookup_type_by_fqn(&fqn_parts) {
Ok(type_symbol) => {
interface_or_class_type.set_type_symbol(type_symbol.clone());
Some(type_symbol)
}
Err(symbol_lookup_error) => {
handle_lookup_error(
symbol_lookup_error,
&format_fqn(&fqn_parts),
fqn.file_id(),
fqn.range(),
diagnostics,
);
None
}
}
}
}
} }
TypeUse::TupleTypeUse(tuple_type) => { TypeUse::TupleTypeUse(tuple_type) => {
todo!() todo!()
@ -281,6 +347,48 @@ fn na_p1_type_use(
} }
} }
fn na_p1_typed_array(
typed_array: &mut TypedArray,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) -> PrimitiveTypeSymbol {
let inner_type_use = typed_array
.generic_arguments_mut()
.type_use_list_mut()
.type_uses_mut()
.next()
.unwrap();
let inner_type_symbol = na_p1_type_use(inner_type_use, symbol_table, diagnostics);
PrimitiveTypeSymbol::TypedArray {
inner_type: inner_type_symbol.map(Box::from),
}
}
fn na_p1_generic_parameters(
generic_parameters: &mut GenericParameters,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for identifier in generic_parameters.identifier_list().identifiers() {
let generic_type_symbol = GenericTypeSymbol::new(
identifier.name(),
Some(SourceDefinition::from_identifier(identifier)),
);
match symbol_table.insert_generic_type_symbol(generic_type_symbol) {
Ok(_) => {}
Err(symbol_insert_error) => {
handle_insert_error(
symbol_insert_error,
identifier.name(),
identifier.file_id(),
identifier.range(),
diagnostics,
);
}
}
}
}
fn na_p1_function_body( fn na_p1_function_body(
function_body: &mut FunctionBody, function_body: &mut FunctionBody,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,

View File

@ -31,11 +31,9 @@ use std::hash::Hash;
// mod resolve; // mod resolve;
mod first_pass; mod first_pass;
mod scope_table;
mod second_pass; mod second_pass;
pub mod symbol; pub mod symbol;
pub mod symbol_table; pub mod symbol_table;
pub mod type_use_container;
mod util; mod util;
pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>( pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(

View File

@ -1,32 +0,0 @@
use crate::ast::node::{FullyQualifiedName, VariableUse};
use std::collections::HashMap;
pub struct ScopeTable<'a> {
variable_use_scopes: HashMap<&'a VariableUse, usize>,
fqn_scopes: HashMap<&'a FullyQualifiedName, usize>,
}
impl<'a> ScopeTable<'a> {
pub fn new() -> Self {
Self {
variable_use_scopes: HashMap::new(),
fqn_scopes: HashMap::new(),
}
}
pub fn insert_variable_use_scope(&mut self, variable_use: &'a VariableUse, scope_id: usize) {
self.variable_use_scopes.insert(variable_use, scope_id);
}
pub fn insert_fqn_scope(&mut self, fqn: &'a FullyQualifiedName, scope_id: usize) {
self.fqn_scopes.insert(fqn, scope_id);
}
pub fn variable_use_scope(&self, variable_use: &'a VariableUse) -> Option<usize> {
self.variable_use_scopes.get(&variable_use).copied()
}
pub fn fqn_scope(&self, fqn: &'a FullyQualifiedName) -> Option<usize> {
self.fqn_scopes.get(&fqn).copied()
}
}

View File

@ -1,7 +1,7 @@
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol::Symbol; use crate::name_analysis::symbol::Symbol;
use crate::name_analysis::type_use_container::TypeUseContainer;
use crate::name_analysis::util::join_fqn_parts; use crate::name_analysis::util::join_fqn_parts;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
@ -13,7 +13,7 @@ pub struct FunctionSymbol {
is_platform: bool, is_platform: bool,
source_definition: Option<SourceDefinition>, source_definition: Option<SourceDefinition>,
parameters: Vec<Rc<RefCell<ParameterSymbol>>>, parameters: Vec<Rc<RefCell<ParameterSymbol>>>,
return_type: Option<Rc<RefCell<TypeUseContainer>>>, // todo: can we use TypeSymbol? return_type: Option<TypeSymbol>,
} }
impl FunctionSymbol { impl FunctionSymbol {
@ -39,7 +39,7 @@ impl FunctionSymbol {
is_platform: bool, is_platform: bool,
source_definition: Option<SourceDefinition>, source_definition: Option<SourceDefinition>,
parameters: &[Rc<RefCell<ParameterSymbol>>], parameters: &[Rc<RefCell<ParameterSymbol>>],
return_type: Option<Rc<RefCell<TypeUseContainer>>>, return_type: Option<TypeSymbol>,
) -> Self { ) -> Self {
Self { Self {
fqn_parts: fqn_parts.to_vec(), fqn_parts: fqn_parts.to_vec(),
@ -79,8 +79,8 @@ impl FunctionSymbol {
self.parameters = parameter_symbols; self.parameters = parameter_symbols;
} }
pub fn set_return_type(&mut self, type_use_container: Rc<RefCell<TypeUseContainer>>) { pub fn set_return_type(&mut self, type_symbol: TypeSymbol) {
self.return_type = Some(type_use_container); self.return_type = Some(type_symbol);
} }
} }

View File

@ -1,16 +1,18 @@
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::Symbol;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::rc::Rc;
#[derive(Clone)] #[derive(Clone)]
pub struct GenericTypeSymbol { pub struct GenericTypeSymbol {
declared_name: String, declared_name: Rc<str>,
source_definition: Option<SourceDefinition>, source_definition: Option<SourceDefinition>,
} }
impl GenericTypeSymbol { impl GenericTypeSymbol {
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self { pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
GenericTypeSymbol { GenericTypeSymbol {
declared_name: declared_name.to_string(), declared_name: Rc::from(declared_name),
source_definition, source_definition,
} }
} }
@ -18,12 +20,22 @@ impl GenericTypeSymbol {
pub fn declared_name(&self) -> &str { pub fn declared_name(&self) -> &str {
&self.declared_name &self.declared_name
} }
pub fn declared_name_owned(&self) -> Rc<str> {
self.declared_name.clone()
}
pub fn source_definition(&self) -> Option<&SourceDefinition> { pub fn source_definition(&self) -> Option<&SourceDefinition> {
self.source_definition.as_ref() self.source_definition.as_ref()
} }
} }
impl Symbol for GenericTypeSymbol {
fn source_definition(&self) -> Option<&SourceDefinition> {
self.source_definition.as_ref()
}
}
impl Debug for GenericTypeSymbol { impl Debug for GenericTypeSymbol {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GenericTypeSymbol") f.debug_struct("GenericTypeSymbol")

View File

@ -1,23 +1,23 @@
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::type_use_container::TypeUseContainer; use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
pub struct ParameterSymbol { pub struct ParameterSymbol {
declared_name: String, declared_name: String,
source_definition: Option<SourceDefinition>, source_definition: Option<SourceDefinition>,
type_use_symbol: Option<TypeUseContainer>, type_symbol: Option<TypeSymbol>,
} }
impl ParameterSymbol { impl ParameterSymbol {
pub fn new( pub fn new(
declared_name: &str, declared_name: &str,
source_definition: Option<SourceDefinition>, source_definition: Option<SourceDefinition>,
type_use_symbol: Option<TypeUseContainer>, type_symbol: Option<TypeSymbol>,
) -> Self { ) -> Self {
ParameterSymbol { ParameterSymbol {
declared_name: declared_name.to_string(), declared_name: declared_name.to_string(),
source_definition, source_definition,
type_use_symbol, type_symbol,
} }
} }

View File

@ -1,4 +1,8 @@
#[derive(Debug)] use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol::Symbol;
#[derive(Debug, Clone)]
pub enum PrimitiveTypeSymbol { pub enum PrimitiveTypeSymbol {
Byte, Byte,
Char, Char,
@ -9,4 +13,13 @@ pub enum PrimitiveTypeSymbol {
Double, Double,
Boolean, Boolean,
String, String,
TypedArray { inner_type: Option<Box<TypeSymbol>> },
Any,
Void,
}
impl Symbol for PrimitiveTypeSymbol {
fn source_definition(&self) -> Option<&SourceDefinition> {
None
}
} }

View File

@ -1,15 +1,35 @@
use std::cell::RefCell;
use crate::name_analysis::symbol::class_symbol::ClassSymbol; use crate::name_analysis::symbol::class_symbol::ClassSymbol;
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol; use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol; use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol; use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
use std::cell::RefCell;
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
use crate::name_analysis::symbol::Symbol;
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum TypeSymbol { pub enum TypeSymbol {
Primitive(PrimitiveTypeSymbol), Primitive(PrimitiveTypeSymbol),
Class(Rc<RefCell<ClassSymbol>>), Class(Rc<RefCell<ClassSymbol>>),
Interface(Rc<RefCell<InterfaceSymbol>>), Interface(Rc<RefCell<InterfaceSymbol>>),
Generic(Rc<RefCell<GenericTypeSymbol>>), Generic(Rc<RefCell<GenericTypeSymbol>>),
} }
impl TypeSymbol {
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
match self {
TypeSymbol::Primitive(primitive_type_symbol) => {
Rc::new(RefCell::new(primitive_type_symbol))
}
TypeSymbol::Class(class_symbol) => {
class_symbol as Rc<RefCell<dyn Symbol>>
}
TypeSymbol::Interface(interface_symbol) => {
interface_symbol as Rc<RefCell<dyn Symbol>>
}
TypeSymbol::Generic(generic_symbol) => {
generic_symbol as Rc<RefCell<dyn Symbol>>
}
}
}
}

View File

@ -1,5 +1,6 @@
use crate::name_analysis::symbol::function_symbol::FunctionSymbol; use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
use crate::name_analysis::symbol::module_symbol::ModuleSymbol; use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol::usable_symbol::UsableSymbol; use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
use crate::name_analysis::symbol::Symbol; use crate::name_analysis::symbol::Symbol;
@ -11,6 +12,7 @@ use std::cell::RefCell;
use std::fmt::Display; use std::fmt::Display;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
pub(self) mod fqn_context; pub(self) mod fqn_context;
mod scope; mod scope;
@ -55,7 +57,6 @@ impl SymbolTable {
id_to_push, id_to_push,
debug_name.to_string(), debug_name.to_string(),
)); ));
self.current_scope_mut().add_child(id_to_push);
self.current_scope_id = id_to_push; self.current_scope_id = id_to_push;
} }
@ -178,6 +179,36 @@ impl SymbolTable {
Ok(inserted) Ok(inserted)
} }
} }
pub fn insert_generic_type_symbol(
&mut self,
generic_type_symbol: GenericTypeSymbol,
) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
if let Some(defined_symbol) = self.current_scope().find_type_symbol(generic_type_symbol.declared_name()) {
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
} else {
let inserted = self.current_scope_mut().insert_generic_type_symbol(generic_type_symbol);
Ok(inserted)
}
}
pub fn lookup_type(&self, declared_name: &str) -> Result<TypeSymbol, SymbolLookupError> {
let mut current_scope: Option<&Scope> = Some(self.current_scope());
while let Some(scope) = current_scope.take() {
if let Some(type_symbol) = scope.find_type_symbol(declared_name) {
return Ok(type_symbol);
} else {
current_scope = scope
.parent()
.and_then(|parent_id| self.scopes.get(parent_id));
}
}
Err(SymbolLookupError::NoDefinition)
}
pub fn lookup_type_by_fqn(&self, fqn_parts: &[&str]) -> Result<TypeSymbol, SymbolLookupError> {
todo!()
}
} }
impl Display for SymbolTable { impl Display for SymbolTable {

View File

@ -1,10 +1,12 @@
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol; use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
use crate::name_analysis::symbol::class_symbol::ClassSymbol; use crate::name_analysis::symbol::class_symbol::ClassSymbol;
use crate::name_analysis::symbol::function_symbol::FunctionSymbol; use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol; use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol; use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
use crate::name_analysis::symbol::module_symbol::ModuleSymbol; use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
use crate::name_analysis::symbol::variable_symbol::VariableSymbol; use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
use std::cell::RefCell; use std::cell::RefCell;
@ -22,6 +24,7 @@ pub struct Scope {
module_symbols: HashMap<Rc<str>, Rc<RefCell<ModuleSymbol>>>, module_symbols: HashMap<Rc<str>, Rc<RefCell<ModuleSymbol>>>,
interface_symbols: HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>, interface_symbols: HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>,
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>, class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>, function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>, parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
variable_symbols: HashMap<Rc<str>, VariableSymbol>, variable_symbols: HashMap<Rc<str>, VariableSymbol>,
@ -48,6 +51,7 @@ impl Scope {
module_symbols: HashMap::new(), module_symbols: HashMap::new(),
interface_symbols: HashMap::new(), interface_symbols: HashMap::new(),
class_symbols: HashMap::new(), class_symbols: HashMap::new(),
generic_symbols: HashMap::new(),
function_symbols: HashMap::new(), function_symbols: HashMap::new(),
parameter_symbols: HashMap::new(), parameter_symbols: HashMap::new(),
variable_symbols: HashMap::new(), variable_symbols: HashMap::new(),
@ -64,15 +68,10 @@ impl Scope {
self.id self.id
} }
pub fn add_child(&mut self, child_id: usize) { pub fn insert_concrete_use_symbol(
self.children.push(child_id); &mut self,
} symbol: ConcreteUseSymbol,
) -> Rc<RefCell<ConcreteUseSymbol>> {
pub fn children(&self) -> Vec<usize> {
self.children.clone()
}
pub fn insert_concrete_use_symbol(&mut self, symbol: ConcreteUseSymbol) -> Rc<RefCell<ConcreteUseSymbol>> {
let key = symbol.declared_name_owned(); let key = symbol.declared_name_owned();
insert_symbol!(self.concrete_use_symbols, symbol, key) insert_symbol!(self.concrete_use_symbols, symbol, key)
} }
@ -126,6 +125,11 @@ impl Scope {
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> { pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
self.class_symbols.get(declared_name) self.class_symbols.get(declared_name)
} }
pub fn insert_generic_type_symbol(&mut self, symbol: GenericTypeSymbol) -> Rc<RefCell<GenericTypeSymbol>> {
let key = symbol.declared_name_owned();
insert_symbol!(self.generic_symbols, symbol, key)
}
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> { pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
self.module_symbols self.module_symbols
@ -148,6 +152,22 @@ impl Scope {
}) })
} }
pub fn find_type_symbol(&self, declared_name: &str) -> Option<TypeSymbol> {
self.interface_symbols
.get(declared_name)
.map(|interface_symbol| TypeSymbol::Interface(interface_symbol.clone()))
.or_else(|| {
self.class_symbols
.get(declared_name)
.map(|class_symbol| TypeSymbol::Class(class_symbol.clone()))
})
.or_else(|| {
self.generic_symbols
.get(declared_name)
.map(|generic_symbol| TypeSymbol::Generic(generic_symbol.clone()))
})
}
pub fn debug_name(&self) -> &str { pub fn debug_name(&self) -> &str {
&self.debug_name &self.debug_name
} }

View File

@ -1,20 +0,0 @@
use std::cell::RefCell;
use std::rc::Rc;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
#[derive(Debug)]
pub struct TypeUseContainer {
resolved_type: Option<Rc<RefCell<TypeSymbol>>>
}
impl TypeUseContainer {
pub fn new() -> TypeUseContainer {
Self {
resolved_type: None
}
}
pub fn set_resolved_type(&mut self, type_symbol: Rc<RefCell<TypeSymbol>>) {
self.resolved_type = Some(type_symbol)
}
}

View File

@ -62,6 +62,11 @@ $defs:
description: Traits to derive. description: Traits to derive.
items: items:
type: string type: string
fields:
type: array
description: Fields to add to the struct node.
items:
$ref: "#/$defs/StructField"
required: required:
- children - children
StructChild: StructChild:
@ -209,6 +214,24 @@ $defs:
- kind - kind
required: required:
- special - special
StructField:
type: object
description: Single-key object mapping the field name to its advanced definition.
minProperties: 1
maxProperties: 1
additionalProperties: false
patternProperties:
"^[a-z][a-z0-9_]*$":
type: object
additionalProperties: false
properties:
kind:
type: string
wrap:
enum:
- rc_ref_cell
required:
- kind
# Leaf Struct Node # Leaf Struct Node
LeafStructNodeDefinition: LeafStructNodeDefinition:

View File

@ -59,10 +59,21 @@ FullyQualifiedName:
- identifiers: - identifiers:
vec: vec:
rule: Identifier rule: Identifier
- file_id:
special:
kind: file_id
- range:
special:
kind: range
derive: derive:
- PartialEq - PartialEq
- Eq - Eq
- Hash - Hash
IdentifierOrFqn:
tree_enum:
rules:
- Identifier
- FullyQualifiedName
# Lists # Lists
TypeUseList: TypeUseList:
@ -126,13 +137,14 @@ TypedArray:
InterfaceOrClassTypeUse: InterfaceOrClassTypeUse:
struct: struct:
children: children:
- fully_qualified_name - identifier_or_fqn
- generic_arguments: - generic_arguments:
member: member:
rule: GenericArguments rule: GenericArguments
build: optional: true
node: fields:
or_else_default: true - type_symbol:
kind: TypeSymbol
TupleTypeUse: TupleTypeUse:
struct: struct:
children: children:
@ -227,9 +239,7 @@ Namespace:
- ns_kw: - ns_kw:
skip: skip:
rule: Ns rule: Ns
- fqn: - identifier_or_fqn
member:
rule: FullyQualifiedName
UseStatement: UseStatement:
tree_enum: tree_enum:
rules: rules:

View File

@ -184,7 +184,12 @@ IdentifierChar = {
FullyQualifiedName = { FullyQualifiedName = {
Identifier Identifier
~ ( "::" ~ Identifier )* ~ ( "::" ~ Identifier )+
}
IdentifierOrFqn = {
Identifier
| FullyQualifiedName
} }
// Common lists // Common lists
@ -238,7 +243,7 @@ TypedArray = {
} }
InterfaceOrClassTypeUse = { InterfaceOrClassTypeUse = {
FullyQualifiedName IdentifierOrFqn
~ GenericArguments? ~ GenericArguments?
} }
@ -318,7 +323,7 @@ CompilationUnit = {
Namespace = { Namespace = {
Ns Ns
~ FullyQualifiedName ~ IdentifierOrFqn
} }
UseStatement = { UseStatement = {

View File

@ -1,17 +1,17 @@
use crate::name_analysis::symbol::function_symbol::FunctionSymbol; use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
use crate::name_analysis::type_use_container::TypeUseContainer;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
symbol_table.set_current_fqn(&vec!["std", "core"]); symbol_table.set_current_fqn(&vec!["std", "core"]);
let mut println_msg_symbol_type_use = TypeUseContainer::new(); let println_msg_symbol = ParameterSymbol::new("msg", None, Some(
println_msg_symbol_type_use.set_resolved_type(todo!()); TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)
));
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(TypeUseContainer::new()));
let println_symbol = FunctionSymbol::with_parameters_and_return_type( let println_symbol = FunctionSymbol::with_parameters_and_return_type(
&symbol_table.resolve_fqn(Rc::from("println")), &symbol_table.resolve_fqn(Rc::from("println")),