Work on star-use symbols.
This commit is contained in:
		
							parent
							
								
									5721bd1e83
								
							
						
					
					
						commit
						d653d26e14
					
				@ -1,9 +1,4 @@
 | 
				
			|||||||
use crate::ast::node::{
 | 
					use crate::ast::node::{CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody, GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters, PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement, UseStatementIdentifier, UseStatementPrefix};
 | 
				
			||||||
    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
 | 
					 | 
				
			||||||
    GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
 | 
					 | 
				
			||||||
    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::generic_type_symbol::GenericTypeSymbol;
 | 
				
			||||||
@ -13,9 +8,9 @@ use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
 | 
				
			|||||||
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
 | 
					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::type_symbol::TypeSymbol;
 | 
				
			||||||
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
 | 
					use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
 | 
				
			||||||
use crate::name_analysis::symbol_table::SymbolTable;
 | 
					use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
 | 
				
			||||||
use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error};
 | 
					use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts};
 | 
				
			||||||
use std::cell::RefCell;
 | 
					use std::cell::RefCell;
 | 
				
			||||||
use std::rc::Rc;
 | 
					use std::rc::Rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,7 +55,7 @@ fn na_p1_use_statement(
 | 
				
			|||||||
            na_p1_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
					            na_p1_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        UseStatement::StarUseStatement(star_use_statement) => {
 | 
					        UseStatement::StarUseStatement(star_use_statement) => {
 | 
				
			||||||
            todo!()
 | 
					            na_p1_star_use_statement(star_use_statement, symbol_table, diagnostics);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -100,7 +95,7 @@ fn na_p1_concrete_use_statement(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_concrete_use_statement_identifier(
 | 
					fn handle_concrete_use_statement_identifier(
 | 
				
			||||||
    prefixes: &Vec<Rc<str>>,
 | 
					    prefixes: &[Rc<str>],
 | 
				
			||||||
    use_statement_identifier: &mut UseStatementIdentifier,
 | 
					    use_statement_identifier: &mut UseStatementIdentifier,
 | 
				
			||||||
    symbol_table: &mut SymbolTable,
 | 
					    symbol_table: &mut SymbolTable,
 | 
				
			||||||
    diagnostics: &mut Vec<DmDiagnostic>,
 | 
					    diagnostics: &mut Vec<DmDiagnostic>,
 | 
				
			||||||
@ -134,6 +129,38 @@ fn handle_concrete_use_statement_identifier(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn na_p1_star_use_statement(
 | 
				
			||||||
 | 
					    star_use_statement: &mut StarUseStatement,
 | 
				
			||||||
 | 
					    symbol_table: &mut SymbolTable,
 | 
				
			||||||
 | 
					    diagnostics: &mut Vec<DmDiagnostic>,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    let fqn_parts = star_use_statement
 | 
				
			||||||
 | 
					        .prefixes()
 | 
				
			||||||
 | 
					        .map(UseStatementPrefix::identifier)
 | 
				
			||||||
 | 
					        .map(Identifier::name)
 | 
				
			||||||
 | 
					        .map(|name| Rc::from(name))
 | 
				
			||||||
 | 
					        .collect::<Vec<Rc<str>>>();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let to_insert = StarUseSymbol::new(
 | 
				
			||||||
 | 
					        &fqn_parts,
 | 
				
			||||||
 | 
					        Some(SourceDefinition::from_star_use_statement(star_use_statement))
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    match symbol_table.insert_star_use_symbol(to_insert) {
 | 
				
			||||||
 | 
					        Ok(star_use_symbol) => {
 | 
				
			||||||
 | 
					            star_use_statement.set_symbol(star_use_symbol);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Err(symbol_insert_error) => {
 | 
				
			||||||
 | 
					            handle_insert_error(
 | 
				
			||||||
 | 
					                symbol_insert_error,
 | 
				
			||||||
 | 
					                &join_fqn_parts(&fqn_parts),
 | 
				
			||||||
 | 
					                star_use_statement.file_id(),
 | 
				
			||||||
 | 
					                star_use_statement.range(),
 | 
				
			||||||
 | 
					                diagnostics,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn na_p1_module_level_declaration(
 | 
					fn na_p1_module_level_declaration(
 | 
				
			||||||
    module_level_declaration: &mut ModuleLevelDeclaration,
 | 
					    module_level_declaration: &mut ModuleLevelDeclaration,
 | 
				
			||||||
    symbol_table: &mut SymbolTable,
 | 
					    symbol_table: &mut SymbolTable,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
use crate::ast::node::{
 | 
					use crate::ast::node::{
 | 
				
			||||||
    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier, UseStatement,
 | 
					    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier,
 | 
				
			||||||
    UseStatementIdentifier, UseStatementPrefix,
 | 
					    StarUseStatement, UseStatement, UseStatementIdentifier, UseStatementPrefix,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use crate::diagnostic::DmDiagnostic;
 | 
					use crate::diagnostic::DmDiagnostic;
 | 
				
			||||||
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
 | 
					use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
 | 
				
			||||||
use crate::name_analysis::util::handle_lookup_error;
 | 
					use crate::name_analysis::util::{handle_lookup_error, join_fqn_parts};
 | 
				
			||||||
 | 
					use std::rc::Rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn na_p2_compilation_unit(
 | 
					pub fn na_p2_compilation_unit(
 | 
				
			||||||
    compilation_unit: &mut CompilationUnit,
 | 
					    compilation_unit: &mut CompilationUnit,
 | 
				
			||||||
@ -29,7 +30,7 @@ fn na_p2_use_statement(
 | 
				
			|||||||
            na_p2_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
					            na_p2_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        UseStatement::StarUseStatement(star_use_statement) => {
 | 
					        UseStatement::StarUseStatement(star_use_statement) => {
 | 
				
			||||||
            todo!()
 | 
					            na_p2_star_use_statement(star_use_statement, symbol_table, diagnostics);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -39,12 +40,12 @@ fn na_p2_concrete_use_statement(
 | 
				
			|||||||
    symbol_table: &SymbolTable,
 | 
					    symbol_table: &SymbolTable,
 | 
				
			||||||
    diagnostics: &mut Vec<DmDiagnostic>,
 | 
					    diagnostics: &mut Vec<DmDiagnostic>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let base_fqn_parts: Vec<String> = concrete_use_statement
 | 
					    let base_fqn_parts = concrete_use_statement
 | 
				
			||||||
        .prefixes()
 | 
					        .prefixes()
 | 
				
			||||||
        .map(UseStatementPrefix::identifier)
 | 
					        .map(UseStatementPrefix::identifier)
 | 
				
			||||||
        .map(Identifier::name)
 | 
					        .map(Identifier::name)
 | 
				
			||||||
        .map(ToString::to_string)
 | 
					        .map(Rc::from)
 | 
				
			||||||
        .collect();
 | 
					        .collect::<Vec<Rc<str>>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match concrete_use_statement.suffix_mut() {
 | 
					    match concrete_use_statement.suffix_mut() {
 | 
				
			||||||
        ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
 | 
					        ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
 | 
				
			||||||
@ -69,17 +70,14 @@ fn na_p2_concrete_use_statement(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_concrete_use_statement_identifier(
 | 
					fn handle_concrete_use_statement_identifier(
 | 
				
			||||||
    base_fqn_parts: &[String],
 | 
					    base_fqn_parts: &[Rc<str>],
 | 
				
			||||||
    use_statement_identifier: &mut UseStatementIdentifier,
 | 
					    use_statement_identifier: &mut UseStatementIdentifier,
 | 
				
			||||||
    symbol_table: &SymbolTable,
 | 
					    symbol_table: &SymbolTable,
 | 
				
			||||||
    diagnostics: &mut Vec<DmDiagnostic>,
 | 
					    diagnostics: &mut Vec<DmDiagnostic>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let fqn_parts = {
 | 
					    let fqn_parts = {
 | 
				
			||||||
        let mut all_parts: Vec<&str> = vec![];
 | 
					        let mut all_parts = base_fqn_parts.to_vec();
 | 
				
			||||||
        for part in base_fqn_parts {
 | 
					        all_parts.push(Rc::from(use_statement_identifier.identifier().name()));
 | 
				
			||||||
            all_parts.push(part);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        all_parts.push(use_statement_identifier.identifier().name());
 | 
					 | 
				
			||||||
        all_parts
 | 
					        all_parts
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,10 +91,32 @@ fn handle_concrete_use_statement_identifier(
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        handle_lookup_error(
 | 
					        handle_lookup_error(
 | 
				
			||||||
            SymbolLookupError::NoDefinition,
 | 
					            SymbolLookupError::NoDefinition,
 | 
				
			||||||
            &fqn_parts.join("::"),
 | 
					            &join_fqn_parts(&fqn_parts),
 | 
				
			||||||
            use_statement_identifier.identifier().file_id(),
 | 
					            use_statement_identifier.identifier().file_id(),
 | 
				
			||||||
            use_statement_identifier.identifier().range(),
 | 
					            use_statement_identifier.identifier().range(),
 | 
				
			||||||
            diagnostics,
 | 
					            diagnostics,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn na_p2_star_use_statement(
 | 
				
			||||||
 | 
					    star_use_statement: &mut StarUseStatement,
 | 
				
			||||||
 | 
					    symbol_table: &SymbolTable,
 | 
				
			||||||
 | 
					    diagnostics: &mut Vec<DmDiagnostic>,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    let mut symbol_ref_mut = star_use_statement.symbol().unwrap().borrow_mut();
 | 
				
			||||||
 | 
					    match symbol_table.find_usable_symbols_by_base_fqn(symbol_ref_mut.fqn_parts()) {
 | 
				
			||||||
 | 
					        Ok(usable_symbols) => {
 | 
				
			||||||
 | 
					            symbol_ref_mut.set_resolved_symbols(usable_symbols);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Err(symbol_lookup_error) => {
 | 
				
			||||||
 | 
					            handle_lookup_error(
 | 
				
			||||||
 | 
					                symbol_lookup_error,
 | 
				
			||||||
 | 
					                &join_fqn_parts(symbol_ref_mut.fqn_parts()),
 | 
				
			||||||
 | 
					                star_use_statement.file_id(),
 | 
				
			||||||
 | 
					                star_use_statement.range(),
 | 
				
			||||||
 | 
					                diagnostics,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
use crate::ast::node::{Identifier, Operator};
 | 
					use crate::ast::node::{Identifier, Operator, StarUseStatement};
 | 
				
			||||||
use std::range::Range;
 | 
					use std::range::Range;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug)]
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
@ -22,6 +22,13 @@ impl SourceDefinition {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn from_star_use_statement(star_use_statement: &StarUseStatement) -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            file_id: star_use_statement.file_id(),
 | 
				
			||||||
 | 
					            range: star_use_statement.range(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn file_id(&self) -> usize {
 | 
					    pub fn file_id(&self) -> usize {
 | 
				
			||||||
        self.file_id
 | 
					        self.file_id
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ use crate::name_analysis::symbol::Symbol;
 | 
				
			|||||||
use std::cell::RefCell;
 | 
					use std::cell::RefCell;
 | 
				
			||||||
use std::rc::Rc;
 | 
					use std::rc::Rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub enum UsableSymbol {
 | 
					pub enum UsableSymbol {
 | 
				
			||||||
    Interface(Rc<RefCell<InterfaceSymbol>>),
 | 
					    Interface(Rc<RefCell<InterfaceSymbol>>),
 | 
				
			||||||
    Class(Rc<RefCell<ClassSymbol>>),
 | 
					    Class(Rc<RefCell<ClassSymbol>>),
 | 
				
			||||||
 | 
				
			|||||||
@ -76,6 +76,7 @@ impl Debug for ConcreteUseSymbol {
 | 
				
			|||||||
pub struct StarUseSymbol {
 | 
					pub struct StarUseSymbol {
 | 
				
			||||||
    fqn_parts: Vec<Rc<str>>,
 | 
					    fqn_parts: Vec<Rc<str>>,
 | 
				
			||||||
    source_definition: Option<SourceDefinition>,
 | 
					    source_definition: Option<SourceDefinition>,
 | 
				
			||||||
 | 
					    resolved_symbols: Vec<UsableSymbol>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl StarUseSymbol {
 | 
					impl StarUseSymbol {
 | 
				
			||||||
@ -83,12 +84,21 @@ impl StarUseSymbol {
 | 
				
			|||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            fqn_parts: fqn_parts.to_vec(),
 | 
					            fqn_parts: fqn_parts.to_vec(),
 | 
				
			||||||
            source_definition,
 | 
					            source_definition,
 | 
				
			||||||
 | 
					            resolved_symbols: vec![],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    pub fn fqn_parts(&self) -> &[Rc<str>] {
 | 
					    pub fn fqn_parts(&self) -> &[Rc<str>] {
 | 
				
			||||||
        &self.fqn_parts
 | 
					        &self.fqn_parts
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pub fn resolved_symbols(&self) -> &[UsableSymbol] {
 | 
				
			||||||
 | 
					        &self.resolved_symbols
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pub fn set_resolved_symbols(&mut self, symbols: Vec<UsableSymbol>) {
 | 
				
			||||||
 | 
					        self.resolved_symbols = symbols;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Symbol for StarUseSymbol {
 | 
					impl Symbol for StarUseSymbol {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
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_symbol::ModuleSymbol;
 | 
					use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
 | 
				
			||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
 | 
					use crate::name_analysis::symbol::type_symbol::TypeSymbol;
 | 
				
			||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
 | 
					use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
 | 
				
			||||||
@ -12,7 +13,6 @@ 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;
 | 
				
			||||||
@ -25,6 +25,7 @@ pub enum SymbolInsertError {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub enum SymbolLookupError {
 | 
					pub enum SymbolLookupError {
 | 
				
			||||||
    NoDefinition,
 | 
					    NoDefinition,
 | 
				
			||||||
 | 
					    NoSuchNamespace,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
@ -95,7 +96,7 @@ impl SymbolTable {
 | 
				
			|||||||
        parts
 | 
					        parts
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn find_usable_symbol(&self, fqn_parts: &[&str]) -> Option<UsableSymbol> {
 | 
					    pub fn find_usable_symbol(&self, fqn_parts: &[Rc<str>]) -> Option<UsableSymbol> {
 | 
				
			||||||
        self.symbol_tree
 | 
					        self.symbol_tree
 | 
				
			||||||
            .find_interface(fqn_parts)
 | 
					            .find_interface(fqn_parts)
 | 
				
			||||||
            .map(|interface_symbol| UsableSymbol::Interface(interface_symbol))
 | 
					            .map(|interface_symbol| UsableSymbol::Interface(interface_symbol))
 | 
				
			||||||
@ -111,6 +112,13 @@ impl SymbolTable {
 | 
				
			|||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn find_usable_symbols_by_base_fqn(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        fqn_parts: &[Rc<str>],
 | 
				
			||||||
 | 
					    ) -> Result<Vec<UsableSymbol>, SymbolLookupError> {
 | 
				
			||||||
 | 
					        self.symbol_tree.find_all_by_base_fqn(fqn_parts)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn current_scope(&self) -> &Scope {
 | 
					    fn current_scope(&self) -> &Scope {
 | 
				
			||||||
        &self.scopes[self.current_scope_id]
 | 
					        &self.scopes[self.current_scope_id]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -184,10 +192,15 @@ impl SymbolTable {
 | 
				
			|||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        generic_type_symbol: GenericTypeSymbol,
 | 
					        generic_type_symbol: GenericTypeSymbol,
 | 
				
			||||||
    ) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
 | 
					    ) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
 | 
				
			||||||
        if let Some(defined_symbol) = self.current_scope().find_type_symbol(generic_type_symbol.declared_name()) {
 | 
					        if let Some(defined_symbol) = self
 | 
				
			||||||
 | 
					            .current_scope()
 | 
				
			||||||
 | 
					            .find_type_symbol(generic_type_symbol.declared_name())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
 | 
					            Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let inserted = self.current_scope_mut().insert_generic_type_symbol(generic_type_symbol);
 | 
					            let inserted = self
 | 
				
			||||||
 | 
					                .current_scope_mut()
 | 
				
			||||||
 | 
					                .insert_generic_type_symbol(generic_type_symbol);
 | 
				
			||||||
            Ok(inserted)
 | 
					            Ok(inserted)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@ 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::interface_symbol::InterfaceSymbol;
 | 
					use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
 | 
				
			||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
 | 
					use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
 | 
				
			||||||
 | 
					use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
 | 
				
			||||||
 | 
					use crate::name_analysis::symbol_table::SymbolLookupError;
 | 
				
			||||||
use std::cell::RefCell;
 | 
					use std::cell::RefCell;
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::rc::Rc;
 | 
					use std::rc::Rc;
 | 
				
			||||||
@ -24,35 +26,35 @@ impl SymbolTree {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn find_class(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<ClassSymbol>>> {
 | 
					    pub fn find_class(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<ClassSymbol>>> {
 | 
				
			||||||
        match fqn_parts.len() {
 | 
					        match fqn_parts.len() {
 | 
				
			||||||
            0 => None,
 | 
					            0 => None,
 | 
				
			||||||
            1 => self.classes.get(fqn_parts[0]).cloned(),
 | 
					            1 => self.classes.get(&fqn_parts[0]).cloned(),
 | 
				
			||||||
            _ => self
 | 
					            _ => self
 | 
				
			||||||
                .children
 | 
					                .children
 | 
				
			||||||
                .get(fqn_parts[0])
 | 
					                .get(&fqn_parts[0])
 | 
				
			||||||
                .and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
 | 
					                .and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn find_interface(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
 | 
					    pub fn find_interface(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
 | 
				
			||||||
        match fqn_parts.len() {
 | 
					        match fqn_parts.len() {
 | 
				
			||||||
            0 => None,
 | 
					            0 => None,
 | 
				
			||||||
            1 => self.interfaces.get(fqn_parts[0]).cloned(),
 | 
					            1 => self.interfaces.get(&fqn_parts[0]).cloned(),
 | 
				
			||||||
            _ => self
 | 
					            _ => self
 | 
				
			||||||
                .children
 | 
					                .children
 | 
				
			||||||
                .get(fqn_parts[0])
 | 
					                .get(&fqn_parts[0])
 | 
				
			||||||
                .and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
 | 
					                .and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn find_function(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<FunctionSymbol>>> {
 | 
					    pub fn find_function(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<FunctionSymbol>>> {
 | 
				
			||||||
        match fqn_parts.len() {
 | 
					        match fqn_parts.len() {
 | 
				
			||||||
            0 => None,
 | 
					            0 => None,
 | 
				
			||||||
            1 => self.functions.get(fqn_parts[0]).cloned(),
 | 
					            1 => self.functions.get(&fqn_parts[0]).cloned(),
 | 
				
			||||||
            _ => self
 | 
					            _ => self
 | 
				
			||||||
                .children
 | 
					                .children
 | 
				
			||||||
                .get(fqn_parts[0])
 | 
					                .get(&fqn_parts[0])
 | 
				
			||||||
                .and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
 | 
					                .and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -85,9 +87,13 @@ impl SymbolTree {
 | 
				
			|||||||
        self.recurse_register_function(function_symbol, &fqn_parts);
 | 
					        self.recurse_register_function(function_symbol, &fqn_parts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn recurse_register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>, fqn_parts: &[Rc<str>]) {
 | 
					    fn recurse_register_function(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        function_symbol: Rc<RefCell<FunctionSymbol>>,
 | 
				
			||||||
 | 
					        fqn_parts: &[Rc<str>],
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        if fqn_parts.len() == 0 {
 | 
					        if fqn_parts.len() == 0 {
 | 
				
			||||||
            panic!("Unable to register function fqn with no parts.")
 | 
					            panic!("Unable to register function fqn with no parts.");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if fqn_parts.len() == 1 {
 | 
					        if fqn_parts.len() == 1 {
 | 
				
			||||||
            self.functions.insert(fqn_parts[0].clone(), function_symbol);
 | 
					            self.functions.insert(fqn_parts[0].clone(), function_symbol);
 | 
				
			||||||
@ -101,4 +107,32 @@ impl SymbolTree {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn find_all_by_base_fqn(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        fqn_parts: &[Rc<str>],
 | 
				
			||||||
 | 
					    ) -> Result<Vec<UsableSymbol>, SymbolLookupError> {
 | 
				
			||||||
 | 
					        match fqn_parts.len() {
 | 
				
			||||||
 | 
					            0 => {
 | 
				
			||||||
 | 
					                let mut all_symbols: Vec<UsableSymbol> = vec![];
 | 
				
			||||||
 | 
					                for interface_symbol in self.interfaces.values() {
 | 
				
			||||||
 | 
					                    all_symbols.push(UsableSymbol::Interface(interface_symbol.clone()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                for class_symbol in self.classes.values() {
 | 
				
			||||||
 | 
					                    all_symbols.push(UsableSymbol::Class(class_symbol.clone()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                for function_symbol in self.functions.values() {
 | 
				
			||||||
 | 
					                    all_symbols.push(UsableSymbol::Function(function_symbol.clone()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Ok(all_symbols)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            _ => {
 | 
				
			||||||
 | 
					                if self.children.contains_key(fqn_parts[0].as_ref()) {
 | 
				
			||||||
 | 
					                    let child = self.children.get(fqn_parts[0].as_ref()).unwrap();
 | 
				
			||||||
 | 
					                    child.find_all_by_base_fqn(fqn_parts)
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    Err(SymbolLookupError::NoSuchNamespace)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -45,11 +45,19 @@ pub fn handle_lookup_error(
 | 
				
			|||||||
    match err {
 | 
					    match err {
 | 
				
			||||||
        SymbolLookupError::NoDefinition => {
 | 
					        SymbolLookupError::NoDefinition => {
 | 
				
			||||||
            let diagnostic = Diagnostic::error()
 | 
					            let diagnostic = Diagnostic::error()
 | 
				
			||||||
                .with_message(format!("No such symbol '{}' in scope.", error_symbol_name,))
 | 
					                .with_message(format!("No such symbol '{}' in scope.", error_symbol_name))
 | 
				
			||||||
                .with_label(
 | 
					                .with_label(
 | 
				
			||||||
                    Label::primary(error_file_id, error_range).with_message("Symbol used here."),
 | 
					                    Label::primary(error_file_id, error_range).with_message("Symbol used here."),
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            diagnostics.push(diagnostic);
 | 
					            diagnostics.push(diagnostic);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        SymbolLookupError::NoSuchNamespace => {
 | 
				
			||||||
 | 
					            let diagnostic = Diagnostic::error()
 | 
				
			||||||
 | 
					                .with_message(format!("No such namespace '{}' found", error_symbol_name))
 | 
				
			||||||
 | 
					                .with_label(
 | 
				
			||||||
 | 
					                    Label::primary(error_file_id, error_range).with_message("Namespace used here.")
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            diagnostics.push(diagnostic);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -281,6 +281,10 @@ StarUseStatement:
 | 
				
			|||||||
      - range:
 | 
					      - range:
 | 
				
			||||||
          special:
 | 
					          special:
 | 
				
			||||||
            kind: range
 | 
					            kind: range
 | 
				
			||||||
 | 
					    fields:
 | 
				
			||||||
 | 
					      - symbol:
 | 
				
			||||||
 | 
					          kind: StarUseSymbol
 | 
				
			||||||
 | 
					          wrap: rc_ref_cell
 | 
				
			||||||
UseStatementPrefix:
 | 
					UseStatementPrefix:
 | 
				
			||||||
  struct:
 | 
					  struct:
 | 
				
			||||||
    children:
 | 
					    children:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user