Work on star-use symbols.
This commit is contained in:
		
							parent
							
								
									5721bd1e83
								
							
						
					
					
						commit
						d653d26e14
					
				@ -1,9 +1,4 @@
 | 
			
		||||
use crate::ast::node::{
 | 
			
		||||
    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
 | 
			
		||||
    GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
 | 
			
		||||
    PrimitiveType, ReturnType, TypeUse, TypedArray, UseStatement, UseStatementIdentifier,
 | 
			
		||||
    UseStatementPrefix,
 | 
			
		||||
};
 | 
			
		||||
use crate::ast::node::{CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody, GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters, PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement, UseStatementIdentifier, UseStatementPrefix};
 | 
			
		||||
use crate::diagnostic::DmDiagnostic;
 | 
			
		||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
 | 
			
		||||
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::source_definition::SourceDefinition;
 | 
			
		||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
 | 
			
		||||
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
 | 
			
		||||
use crate::name_analysis::symbol_table::SymbolTable;
 | 
			
		||||
use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error};
 | 
			
		||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
 | 
			
		||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
 | 
			
		||||
use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts};
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
 | 
			
		||||
@ -60,7 +55,7 @@ fn na_p1_use_statement(
 | 
			
		||||
            na_p1_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
			
		||||
        }
 | 
			
		||||
        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(
 | 
			
		||||
    prefixes: &Vec<Rc<str>>,
 | 
			
		||||
    prefixes: &[Rc<str>],
 | 
			
		||||
    use_statement_identifier: &mut UseStatementIdentifier,
 | 
			
		||||
    symbol_table: &mut SymbolTable,
 | 
			
		||||
    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(
 | 
			
		||||
    module_level_declaration: &mut ModuleLevelDeclaration,
 | 
			
		||||
    symbol_table: &mut SymbolTable,
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
use crate::ast::node::{
 | 
			
		||||
    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier, UseStatement,
 | 
			
		||||
    UseStatementIdentifier, UseStatementPrefix,
 | 
			
		||||
    CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier,
 | 
			
		||||
    StarUseStatement, UseStatement, UseStatementIdentifier, UseStatementPrefix,
 | 
			
		||||
};
 | 
			
		||||
use crate::diagnostic::DmDiagnostic;
 | 
			
		||||
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(
 | 
			
		||||
    compilation_unit: &mut CompilationUnit,
 | 
			
		||||
@ -29,7 +30,7 @@ fn na_p2_use_statement(
 | 
			
		||||
            na_p2_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
 | 
			
		||||
        }
 | 
			
		||||
        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,
 | 
			
		||||
    diagnostics: &mut Vec<DmDiagnostic>,
 | 
			
		||||
) {
 | 
			
		||||
    let base_fqn_parts: Vec<String> = concrete_use_statement
 | 
			
		||||
    let base_fqn_parts = concrete_use_statement
 | 
			
		||||
        .prefixes()
 | 
			
		||||
        .map(UseStatementPrefix::identifier)
 | 
			
		||||
        .map(Identifier::name)
 | 
			
		||||
        .map(ToString::to_string)
 | 
			
		||||
        .collect();
 | 
			
		||||
        .map(Rc::from)
 | 
			
		||||
        .collect::<Vec<Rc<str>>>();
 | 
			
		||||
 | 
			
		||||
    match concrete_use_statement.suffix_mut() {
 | 
			
		||||
        ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
 | 
			
		||||
@ -69,17 +70,14 @@ fn na_p2_concrete_use_statement(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn handle_concrete_use_statement_identifier(
 | 
			
		||||
    base_fqn_parts: &[String],
 | 
			
		||||
    base_fqn_parts: &[Rc<str>],
 | 
			
		||||
    use_statement_identifier: &mut UseStatementIdentifier,
 | 
			
		||||
    symbol_table: &SymbolTable,
 | 
			
		||||
    diagnostics: &mut Vec<DmDiagnostic>,
 | 
			
		||||
) {
 | 
			
		||||
    let fqn_parts = {
 | 
			
		||||
        let mut all_parts: Vec<&str> = vec![];
 | 
			
		||||
        for part in base_fqn_parts {
 | 
			
		||||
            all_parts.push(part);
 | 
			
		||||
        }
 | 
			
		||||
        all_parts.push(use_statement_identifier.identifier().name());
 | 
			
		||||
        let mut all_parts = base_fqn_parts.to_vec();
 | 
			
		||||
        all_parts.push(Rc::from(use_statement_identifier.identifier().name()));
 | 
			
		||||
        all_parts
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -93,10 +91,32 @@ fn handle_concrete_use_statement_identifier(
 | 
			
		||||
    } else {
 | 
			
		||||
        handle_lookup_error(
 | 
			
		||||
            SymbolLookupError::NoDefinition,
 | 
			
		||||
            &fqn_parts.join("::"),
 | 
			
		||||
            &join_fqn_parts(&fqn_parts),
 | 
			
		||||
            use_statement_identifier.identifier().file_id(),
 | 
			
		||||
            use_statement_identifier.identifier().range(),
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
@ -14,7 +14,7 @@ impl SourceDefinition {
 | 
			
		||||
            range: identifier.range(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    pub fn from_operator(operator: &Operator) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            file_id: operator.file_id(),
 | 
			
		||||
@ -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 {
 | 
			
		||||
        self.file_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ use crate::name_analysis::symbol::Symbol;
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum UsableSymbol {
 | 
			
		||||
    Interface(Rc<RefCell<InterfaceSymbol>>),
 | 
			
		||||
    Class(Rc<RefCell<ClassSymbol>>),
 | 
			
		||||
 | 
			
		||||
@ -76,6 +76,7 @@ impl Debug for ConcreteUseSymbol {
 | 
			
		||||
pub struct StarUseSymbol {
 | 
			
		||||
    fqn_parts: Vec<Rc<str>>,
 | 
			
		||||
    source_definition: Option<SourceDefinition>,
 | 
			
		||||
    resolved_symbols: Vec<UsableSymbol>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl StarUseSymbol {
 | 
			
		||||
@ -83,12 +84,21 @@ impl StarUseSymbol {
 | 
			
		||||
        Self {
 | 
			
		||||
            fqn_parts: fqn_parts.to_vec(),
 | 
			
		||||
            source_definition,
 | 
			
		||||
            resolved_symbols: vec![],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    pub fn fqn_parts(&self) -> &[Rc<str>] {
 | 
			
		||||
        &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 {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
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::type_symbol::TypeSymbol;
 | 
			
		||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
 | 
			
		||||
@ -12,7 +13,6 @@ use std::cell::RefCell;
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
use std::ops::Deref;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
 | 
			
		||||
 | 
			
		||||
pub(self) mod fqn_context;
 | 
			
		||||
mod scope;
 | 
			
		||||
@ -25,6 +25,7 @@ pub enum SymbolInsertError {
 | 
			
		||||
 | 
			
		||||
pub enum SymbolLookupError {
 | 
			
		||||
    NoDefinition,
 | 
			
		||||
    NoSuchNamespace,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@ -95,7 +96,7 @@ impl SymbolTable {
 | 
			
		||||
        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
 | 
			
		||||
            .find_interface(fqn_parts)
 | 
			
		||||
            .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 {
 | 
			
		||||
        &self.scopes[self.current_scope_id]
 | 
			
		||||
    }
 | 
			
		||||
@ -179,15 +187,20 @@ impl SymbolTable {
 | 
			
		||||
            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()) {
 | 
			
		||||
        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);
 | 
			
		||||
            let inserted = self
 | 
			
		||||
                .current_scope_mut()
 | 
			
		||||
                .insert_generic_type_symbol(generic_type_symbol);
 | 
			
		||||
            Ok(inserted)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -205,7 +218,7 @@ impl SymbolTable {
 | 
			
		||||
        }
 | 
			
		||||
        Err(SymbolLookupError::NoDefinition)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    pub fn lookup_type_by_fqn(&self, fqn_parts: &[&str]) -> Result<TypeSymbol, SymbolLookupError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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::interface_symbol::InterfaceSymbol;
 | 
			
		||||
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::collections::HashMap;
 | 
			
		||||
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() {
 | 
			
		||||
            0 => None,
 | 
			
		||||
            1 => self.classes.get(fqn_parts[0]).cloned(),
 | 
			
		||||
            1 => self.classes.get(&fqn_parts[0]).cloned(),
 | 
			
		||||
            _ => self
 | 
			
		||||
                .children
 | 
			
		||||
                .get(fqn_parts[0])
 | 
			
		||||
                .get(&fqn_parts[0])
 | 
			
		||||
                .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() {
 | 
			
		||||
            0 => None,
 | 
			
		||||
            1 => self.interfaces.get(fqn_parts[0]).cloned(),
 | 
			
		||||
            1 => self.interfaces.get(&fqn_parts[0]).cloned(),
 | 
			
		||||
            _ => self
 | 
			
		||||
                .children
 | 
			
		||||
                .get(fqn_parts[0])
 | 
			
		||||
                .get(&fqn_parts[0])
 | 
			
		||||
                .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() {
 | 
			
		||||
            0 => None,
 | 
			
		||||
            1 => self.functions.get(fqn_parts[0]).cloned(),
 | 
			
		||||
            1 => self.functions.get(&fqn_parts[0]).cloned(),
 | 
			
		||||
            _ => self
 | 
			
		||||
                .children
 | 
			
		||||
                .get(fqn_parts[0])
 | 
			
		||||
                .get(&fqn_parts[0])
 | 
			
		||||
                .and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -79,15 +81,19 @@ impl SymbolTree {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    pub fn register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>) {
 | 
			
		||||
        let fqn_parts = function_symbol.borrow().fqn_parts_owned();
 | 
			
		||||
        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 {
 | 
			
		||||
            panic!("Unable to register function fqn with no parts.")
 | 
			
		||||
            panic!("Unable to register function fqn with no parts.");
 | 
			
		||||
        }
 | 
			
		||||
        if fqn_parts.len() == 1 {
 | 
			
		||||
            self.functions.insert(fqn_parts[0].clone(), function_symbol);
 | 
			
		||||
@ -100,5 +106,33 @@ 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 {
 | 
			
		||||
        SymbolLookupError::NoDefinition => {
 | 
			
		||||
            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(
 | 
			
		||||
                    Label::primary(error_file_id, error_range).with_message("Symbol used here."),
 | 
			
		||||
                );
 | 
			
		||||
            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:
 | 
			
		||||
          special:
 | 
			
		||||
            kind: range
 | 
			
		||||
    fields:
 | 
			
		||||
      - symbol:
 | 
			
		||||
          kind: StarUseSymbol
 | 
			
		||||
          wrap: rc_ref_cell
 | 
			
		||||
UseStatementPrefix:
 | 
			
		||||
  struct:
 | 
			
		||||
    children:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user