Better handling of global imports.
This commit is contained in:
parent
6bcef184eb
commit
da05bb101b
@ -1,8 +1,7 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, Identifier,
|
||||||
, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration
|
IdentifierOrFqn, Module, ModuleLevelDeclaration, PlatformFunction, StarUseStatement,
|
||||||
, StarUseStatement, UseStatement,
|
UseStatement, UseStatementIdentifier, UseStatementPrefix,
|
||||||
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;
|
||||||
@ -11,10 +10,9 @@ use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use crate::name_analysis::util::{
|
use crate::name_analysis::util::{handle_insert_error, join_fqn_parts};
|
||||||
handle_insert_error, join_fqn_parts,
|
|
||||||
};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::process::id;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn na_p1_compilation_unit(
|
pub fn na_p1_compilation_unit(
|
||||||
@ -26,13 +24,26 @@ pub fn na_p1_compilation_unit(
|
|||||||
if let Some(namespace) = compilation_unit.namespace() {
|
if let Some(namespace) = compilation_unit.namespace() {
|
||||||
match namespace.identifier_or_fqn() {
|
match namespace.identifier_or_fqn() {
|
||||||
IdentifierOrFqn::Identifier(identifier) => {
|
IdentifierOrFqn::Identifier(identifier) => {
|
||||||
symbol_table.set_current_fqn(&[identifier.name()])
|
symbol_table.set_current_fqn(&[identifier.name()]);
|
||||||
}
|
}
|
||||||
IdentifierOrFqn::FullyQualifiedName(fqn) => {
|
IdentifierOrFqn::FullyQualifiedName(fqn) => {
|
||||||
symbol_table
|
symbol_table
|
||||||
.set_current_fqn(&fqn.identifiers().map(Identifier::name).collect::<Vec<_>>());
|
.set_current_fqn(&fqn.identifiers().map(Identifier::name).collect::<Vec<_>>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let fqn_parts = match namespace.identifier_or_fqn() {
|
||||||
|
IdentifierOrFqn::Identifier(identifier) => {
|
||||||
|
vec![identifier.name()]
|
||||||
|
}
|
||||||
|
IdentifierOrFqn::FullyQualifiedName(fqn) => {
|
||||||
|
let mut parts = vec![];
|
||||||
|
for identifier in fqn.identifiers() {
|
||||||
|
parts.push(identifier.name());
|
||||||
|
}
|
||||||
|
parts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
symbol_table.register_module(&fqn_parts);
|
||||||
} else {
|
} else {
|
||||||
symbol_table.set_current_fqn(&[]);
|
symbol_table.set_current_fqn(&[]);
|
||||||
}
|
}
|
||||||
@ -187,7 +198,9 @@ fn na_p1_module_level_declaration(
|
|||||||
.map(|function_symbol| ModuleLevelSymbol::Function(function_symbol))
|
.map(|function_symbol| ModuleLevelSymbol::Function(function_symbol))
|
||||||
}
|
}
|
||||||
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
||||||
todo!()
|
na_p1_platform_function(platform_function, symbol_table, diagnostics).map(
|
||||||
|
|platform_function_symbol| ModuleLevelSymbol::Function(platform_function_symbol),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +277,7 @@ fn na_p1_function(
|
|||||||
if maybe_function_symbol.is_some() {
|
if maybe_function_symbol.is_some() {
|
||||||
function.set_function_symbol(maybe_function_symbol.as_ref().unwrap().clone());
|
function.set_function_symbol(maybe_function_symbol.as_ref().unwrap().clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a scope for this function
|
// create a scope for this function
|
||||||
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
||||||
function.set_scope_id(symbol_table.current_scope_id());
|
function.set_scope_id(symbol_table.current_scope_id());
|
||||||
@ -272,3 +285,45 @@ fn na_p1_function(
|
|||||||
|
|
||||||
maybe_function_symbol
|
maybe_function_symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p1_platform_function(
|
||||||
|
platform_function: &mut PlatformFunction,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
|
let to_insert = FunctionSymbol::new(
|
||||||
|
&symbol_table.resolve_fqn(Rc::from(platform_function.identifier().name())),
|
||||||
|
platform_function.is_public(),
|
||||||
|
true,
|
||||||
|
Some(SourceDefinition::from_identifier(
|
||||||
|
platform_function.identifier(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
let maybe_function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
||||||
|
Ok(function_symbol) => Some(function_symbol),
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
platform_function.identifier().name(),
|
||||||
|
platform_function.identifier().file_id(),
|
||||||
|
platform_function.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if maybe_function_symbol.is_some() {
|
||||||
|
platform_function.set_function_symbol(maybe_function_symbol.as_ref().unwrap().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a scope for later
|
||||||
|
symbol_table.push_scope(&format!(
|
||||||
|
"PlatformFunctionScope {}",
|
||||||
|
platform_function.identifier().name()
|
||||||
|
));
|
||||||
|
platform_function.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
|
||||||
|
maybe_function_symbol
|
||||||
|
}
|
||||||
|
|||||||
@ -46,7 +46,9 @@ pub fn analyze_names<
|
|||||||
) -> Vec<DmDiagnostic> {
|
) -> Vec<DmDiagnostic> {
|
||||||
let mut diagnostics = vec![];
|
let mut diagnostics = vec![];
|
||||||
|
|
||||||
// gather symbols
|
// first pass
|
||||||
|
// generally, gather symbols from declarations
|
||||||
|
// don't go into functions
|
||||||
for compilation_unit in compilation_units.iter_mut() {
|
for compilation_unit in compilation_units.iter_mut() {
|
||||||
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
||||||
na_p1_compilation_unit(file_name, compilation_unit, symbol_table, &mut diagnostics);
|
na_p1_compilation_unit(file_name, compilation_unit, symbol_table, &mut diagnostics);
|
||||||
@ -56,7 +58,11 @@ pub fn analyze_names<
|
|||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve symbols
|
// resolve global imports
|
||||||
|
symbol_table.resolve_global_imports();
|
||||||
|
|
||||||
|
// second pass
|
||||||
|
// resolve referenced symbols and go into functions
|
||||||
for compilation_unit in compilation_units.iter_mut() {
|
for compilation_unit in compilation_units.iter_mut() {
|
||||||
na_p2_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
|
na_p2_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
|
||||||
}
|
}
|
||||||
@ -318,12 +324,39 @@ mod tests {
|
|||||||
|
|
||||||
add_std_core_symbols(&mut symbol_table).expect("Failed to add std/core symbols.");
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std/core symbols.");
|
||||||
|
|
||||||
let resolved_std_core_symbols = symbol_table
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
.find_usable_symbols_by_base_fqn(&str_slice_to_rcs(&["std", "core"]))
|
}
|
||||||
.unwrap();
|
|
||||||
global_std_core_star_use
|
#[test]
|
||||||
.borrow_mut()
|
fn with_std_core_source() {
|
||||||
.set_resolved_symbols(resolved_std_core_symbols);
|
let sources = HashMap::from([
|
||||||
|
(
|
||||||
|
"std/core/print.dm",
|
||||||
|
"
|
||||||
|
ns std::core
|
||||||
|
|
||||||
|
pub platform fn println(msg: Any) -> Void
|
||||||
|
|
||||||
|
pub platform fn print(msg: Any) -> Void
|
||||||
|
",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"main.dm",
|
||||||
|
"
|
||||||
|
fn main()
|
||||||
|
println('A line')
|
||||||
|
print('Not a line')
|
||||||
|
end
|
||||||
|
",
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
let global_star_use = symbol_table
|
||||||
|
.insert_star_use_symbol(StarUseSymbol::new(
|
||||||
|
&str_slice_to_rcs(&["std", "core"]),
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
.expect("Failed to insert star use symbol.");
|
||||||
|
|
||||||
assert_no_diagnostics(sources, &mut symbol_table);
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
AssignmentStatement, Call, CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix,
|
AssignmentStatement, BacktickString, Call, CompilationUnit, ConcreteUseStatement,
|
||||||
Expression, ExpressionList, ExpressionStatement, Function, FunctionAliasBody,
|
ConcreteUseStatementSuffix, DString, Expression, ExpressionList, ExpressionStatement, Function,
|
||||||
FunctionBlockBody, FunctionBody, FunctionEqualsBody, GenericParameters, Identifier,
|
FunctionAliasBody, FunctionBlockBody, FunctionBody, FunctionEqualsBody, GenericParameters,
|
||||||
IdentifierExpression, IdentifierOrFqn, LValue, LValueSuffix, ModuleLevelDeclaration,
|
Identifier, IdentifierExpression, IdentifierOrFqn, LValue, LValueSuffix, Literal,
|
||||||
ObjectIndex, Parameter, Parameters, PrimitiveType, ReturnType, StarUseStatement, Statement,
|
ModuleLevelDeclaration, ObjectIndex, Parameter, Parameters, PlatformFunction, PrimitiveType,
|
||||||
SuffixExpression, SuffixOperator, TypeUse, TypedArray, UseStatement, UseStatementIdentifier,
|
ReturnType, StarUseStatement, Statement, SuffixExpression, SuffixOperator, TypeUse, TypedArray,
|
||||||
UseStatementPrefix, VariableDeclaration,
|
UseStatement, UseStatementIdentifier, UseStatementPrefix, VariableDeclaration,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
@ -153,7 +153,7 @@ fn na_p2_module_level_declaration(
|
|||||||
na_p2_function(function, symbol_table, diagnostics);
|
na_p2_function(function, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
||||||
todo!()
|
na_p2_platform_function(platform_function, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +197,44 @@ fn na_p2_function(
|
|||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p2_platform_function(
|
||||||
|
platform_function: &mut PlatformFunction,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
// change to this function's scope
|
||||||
|
symbol_table.set_current_scope(*platform_function.scope_id().unwrap());
|
||||||
|
|
||||||
|
// generics
|
||||||
|
na_p2_generic_parameters(platform_function.generics_mut(), symbol_table, diagnostics);
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
let parameter_symbols = na_p2_parameters(
|
||||||
|
platform_function.parameters_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
platform_function
|
||||||
|
.function_symbol_mut()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parameter_symbols(parameter_symbols);
|
||||||
|
|
||||||
|
// return_type
|
||||||
|
let maybe_return_type_symbol = na_p2_return_type(
|
||||||
|
platform_function.return_type_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
if let Some(return_type_symbol) = maybe_return_type_symbol {
|
||||||
|
platform_function
|
||||||
|
.function_symbol_mut()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.set_return_type(return_type_symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn na_p2_generic_parameters(
|
fn na_p2_generic_parameters(
|
||||||
generic_parameters: &mut GenericParameters,
|
generic_parameters: &mut GenericParameters,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -602,7 +640,7 @@ fn na_p2_expression(
|
|||||||
na_p2_suffix_expression(suffix, symbol_table, diagnostics);
|
na_p2_suffix_expression(suffix, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
Expression::Literal(literal) => {
|
Expression::Literal(literal) => {
|
||||||
todo!()
|
na_p2_literal(literal, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
Expression::Identifier(identifier_expression) => {
|
Expression::Identifier(identifier_expression) => {
|
||||||
na_p2_identifier_expression(identifier_expression, symbol_table, diagnostics);
|
na_p2_identifier_expression(identifier_expression, symbol_table, diagnostics);
|
||||||
@ -726,3 +764,49 @@ fn na_p2_expression_list(
|
|||||||
na_p2_expression(expression, symbol_table, diagnostics);
|
na_p2_expression(expression, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p2_literal(
|
||||||
|
literal: &mut Literal,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match literal {
|
||||||
|
Literal::DString(d_string) => {
|
||||||
|
na_p2_d_string(d_string, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Literal::BacktickString(backtick_string) => {
|
||||||
|
na_p2_backtick_string(backtick_string, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// no-op, nothing to check.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_d_string(
|
||||||
|
d_string: &mut DString,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
for d_string_expression in d_string.expressions_mut() {
|
||||||
|
na_p2_expression(
|
||||||
|
d_string_expression.expression_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_backtick_string(
|
||||||
|
backtick_string: &mut BacktickString,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
for d_string_expression in backtick_string.expressions_mut() {
|
||||||
|
na_p2_expression(
|
||||||
|
d_string_expression.expression_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use crate::name_analysis::symbol::{ExpressibleSymbol, LVSymbol, Symbol};
|
|||||||
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
||||||
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
|
use crate::name_analysis::util::join_fqn_parts;
|
||||||
use scope::Scope;
|
use scope::Scope;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
@ -132,6 +133,45 @@ impl SymbolTable {
|
|||||||
as_rc
|
as_rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_global_imports(&mut self) {
|
||||||
|
let global_scope = &self.scopes[0];
|
||||||
|
for concrete_use_symbol in global_scope.concrete_use_symbols() {
|
||||||
|
match self
|
||||||
|
.symbol_tree
|
||||||
|
.find_usable_symbol(concrete_use_symbol.borrow().fqn_parts())
|
||||||
|
{
|
||||||
|
Ok(usable_symbol) => {
|
||||||
|
concrete_use_symbol.borrow_mut().set_resolved_symbol(usable_symbol);
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
// panic because this is definitely a compiler/configuration error
|
||||||
|
panic!(
|
||||||
|
"{:?}: Cannot resolve global import {}",
|
||||||
|
symbol_lookup_error,
|
||||||
|
join_fqn_parts(concrete_use_symbol.borrow().fqn_parts())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for star_use_symbol in global_scope.star_use_symbols() {
|
||||||
|
let mut star_use_symbol_ref_mut = star_use_symbol.borrow_mut();
|
||||||
|
match self.symbol_tree.find_all_by_base_fqn(star_use_symbol_ref_mut.fqn_parts()) {
|
||||||
|
Ok(usable_symbols) => {
|
||||||
|
star_use_symbol_ref_mut.set_resolved_symbols(usable_symbols);
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
// again, panic because this is a compiler/configuration error
|
||||||
|
panic!(
|
||||||
|
"{:?}: Cannot resolve global star import {}::*",
|
||||||
|
symbol_lookup_error,
|
||||||
|
join_fqn_parts(star_use_symbol.borrow().fqn_parts())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_usable_symbols_by_base_fqn(
|
pub fn find_usable_symbols_by_base_fqn(
|
||||||
&self,
|
&self,
|
||||||
fqn_parts: &[Rc<str>],
|
fqn_parts: &[Rc<str>],
|
||||||
|
|||||||
@ -69,6 +69,14 @@ impl Scope {
|
|||||||
pub fn id(&self) -> usize {
|
pub fn id(&self) -> usize {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn concrete_use_symbols(&self) -> impl Iterator<Item = &Rc<RefCell<ConcreteUseSymbol>>> {
|
||||||
|
self.concrete_use_symbols.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn star_use_symbols(&self) -> impl Iterator<Item = &Rc<RefCell<StarUseSymbol>>> {
|
||||||
|
self.star_use_symbols.values()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_concrete_use_symbol(
|
pub fn insert_concrete_use_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@ -81,8 +81,10 @@ impl SymbolTree {
|
|||||||
panic!("Unable to register module fqn with no parts.")
|
panic!("Unable to register module fqn with no parts.")
|
||||||
}
|
}
|
||||||
if fqn_parts.len() == 1 {
|
if fqn_parts.len() == 1 {
|
||||||
self.children
|
if !self.children.contains_key(&fqn_parts[0]) {
|
||||||
.insert(fqn_parts[0].clone(), SymbolTree::new(fqn_parts[0].as_ref()));
|
self.children
|
||||||
|
.insert(fqn_parts[0].clone(), SymbolTree::new(fqn_parts[0].as_ref()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
||||||
let child = self.children.get_mut(fqn_parts[0].as_ref()).unwrap();
|
let child = self.children.get_mut(fqn_parts[0].as_ref()).unwrap();
|
||||||
@ -154,12 +156,44 @@ impl SymbolTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_usable_symbol(
|
||||||
|
&self,
|
||||||
|
fqn_parts: &[Rc<str>],
|
||||||
|
) -> Result<UsableSymbol, SymbolLookupError> {
|
||||||
|
match fqn_parts.len() {
|
||||||
|
0 => panic!("Cannot resolve a usable symbol with no fqn part."),
|
||||||
|
1 => self
|
||||||
|
.find_interface(fqn_parts)
|
||||||
|
.map(|interface_symbol| UsableSymbol::Interface(interface_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.find_class(fqn_parts)
|
||||||
|
.map(|class_symbol| UsableSymbol::Class(class_symbol.clone()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.find_function(fqn_parts)
|
||||||
|
.map(|function_symbol| UsableSymbol::Function(function_symbol))
|
||||||
|
})
|
||||||
|
.map_or_else(
|
||||||
|
|| Err(SymbolLookupError::NoDefinition),
|
||||||
|
|usable_symbol| Ok(usable_symbol),
|
||||||
|
),
|
||||||
|
_ => {
|
||||||
|
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
||||||
|
let child = self.children.get(fqn_parts[0].as_ref()).unwrap();
|
||||||
|
child.find_usable_symbol(&fqn_parts[1..])
|
||||||
|
} else {
|
||||||
|
Err(SymbolLookupError::NoSuchNamespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FormatAction<'a> {
|
enum FormatAction<'a> {
|
||||||
PrintSymbolTree(&'a SymbolTree),
|
PrintSymbolTree(&'a SymbolTree),
|
||||||
IncreaseIndent,
|
IncreaseIndent,
|
||||||
DecreaseIndent
|
DecreaseIndent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolTree {
|
impl Display for SymbolTree {
|
||||||
@ -168,7 +202,7 @@ impl Display for SymbolTree {
|
|||||||
let mut indent_writer = IndentWriter::new(0, " ", &mut acc);
|
let mut indent_writer = IndentWriter::new(0, " ", &mut acc);
|
||||||
let mut stack: Vec<FormatAction> = vec![];
|
let mut stack: Vec<FormatAction> = vec![];
|
||||||
stack.push(FormatAction::PrintSymbolTree(self));
|
stack.push(FormatAction::PrintSymbolTree(self));
|
||||||
|
|
||||||
while let Some(format_action) = stack.pop() {
|
while let Some(format_action) = stack.pop() {
|
||||||
match format_action {
|
match format_action {
|
||||||
FormatAction::PrintSymbolTree(symbol_tree) => {
|
FormatAction::PrintSymbolTree(symbol_tree) => {
|
||||||
@ -181,7 +215,10 @@ impl Display for SymbolTree {
|
|||||||
// increase for the first child
|
// increase for the first child
|
||||||
stack.push(FormatAction::IncreaseIndent);
|
stack.push(FormatAction::IncreaseIndent);
|
||||||
|
|
||||||
indent_writer.writeln_indented(&format!("SymbolTree(debug_name = {})", symbol_tree.debug_name))?;
|
indent_writer.writeln_indented(&format!(
|
||||||
|
"SymbolTree(debug_name = {})",
|
||||||
|
symbol_tree.debug_name
|
||||||
|
))?;
|
||||||
|
|
||||||
indent_writer.increase_indent();
|
indent_writer.increase_indent();
|
||||||
for interface in symbol_tree.interfaces.values() {
|
for interface in symbol_tree.interfaces.values() {
|
||||||
@ -203,7 +240,7 @@ impl Display for SymbolTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(f, "{}", acc)
|
writeln!(f, "{}", acc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -503,6 +503,12 @@ PlatformFunction:
|
|||||||
- identifier
|
- identifier
|
||||||
- parameters
|
- parameters
|
||||||
- return_type
|
- return_type
|
||||||
|
fields:
|
||||||
|
- function_symbol:
|
||||||
|
kind: FunctionSymbol
|
||||||
|
wrap: rc_ref_cell
|
||||||
|
- scope_id:
|
||||||
|
kind: usize
|
||||||
PlatformOperatorFunction:
|
PlatformOperatorFunction:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
|
|||||||
@ -188,8 +188,8 @@ FullyQualifiedName = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IdentifierOrFqn = {
|
IdentifierOrFqn = {
|
||||||
Identifier
|
FullyQualifiedName
|
||||||
| FullyQualifiedName
|
| Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common lists
|
// Common lists
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user