WIP on name-analysis gather.
This commit is contained in:
parent
36e28ae4a9
commit
d5ac6dfc2d
@ -1,4 +1,4 @@
|
|||||||
pub(super) struct FqnContext {
|
pub struct FqnContext {
|
||||||
stack: Vec<String>,
|
stack: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,20 @@
|
|||||||
use crate::ast::ast_node::{AstNode, AstNodeRef};
|
use crate::ast::ast_node::{AstNode, AstNodeRef};
|
||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Statement,
|
Class, CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Interface,
|
||||||
UseStatement, UseStatementSuffix, VariableDeclaration,
|
Module, Namespace, Statement, UseStatement, UseStatementSuffix, VariableDeclaration,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
|
use crate::name_analysis::fqn_context::FqnContext;
|
||||||
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::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::{
|
||||||
|
ConcreteTypeSymbol, ConcreteTypeSymbolKind, 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 crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
|
||||||
fn handle_insert_error(
|
fn handle_insert_error(
|
||||||
@ -45,165 +49,28 @@ fn handle_insert_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_identifier(
|
|
||||||
identifier: &Identifier,
|
|
||||||
symbol_table: &SymbolTable,
|
|
||||||
identifier_scope_ids: &mut HashMap<Identifier, usize>,
|
|
||||||
) {
|
|
||||||
identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_concrete_use_symbol(
|
|
||||||
base_fqn: &str,
|
|
||||||
identifier: &Identifier,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let symbol = ConcreteUseSymbol::new(
|
|
||||||
base_fqn,
|
|
||||||
identifier.name(),
|
|
||||||
Some(SourceDefinition::from_identifier(identifier)),
|
|
||||||
);
|
|
||||||
if let Err(insert_error) = symbol_table.insert_concrete_use_symbol(symbol) {
|
|
||||||
handle_insert_error(
|
|
||||||
insert_error,
|
|
||||||
&base_fqn,
|
|
||||||
identifier.file_id(),
|
|
||||||
identifier.range(),
|
|
||||||
"Use Statement",
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_use_statement(
|
|
||||||
use_statement: &UseStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let base_fqn = use_statement
|
|
||||||
.prefixes()
|
|
||||||
.map(|prefix| prefix.identifier().name())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("::");
|
|
||||||
|
|
||||||
match use_statement.suffix() {
|
|
||||||
UseStatementSuffix::Identifier(identifier) => {
|
|
||||||
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
UseStatementSuffix::Star => {
|
|
||||||
let symbol = StarUseSymbol::new(
|
|
||||||
&base_fqn,
|
|
||||||
Some(SourceDefinition::from_use_statement(use_statement)),
|
|
||||||
);
|
|
||||||
let insert_result = symbol_table.insert_star_use_symbol(symbol);
|
|
||||||
if let Err(error) = insert_result {
|
|
||||||
handle_insert_error(
|
|
||||||
error,
|
|
||||||
&base_fqn,
|
|
||||||
use_statement.file_id(),
|
|
||||||
use_statement.range(),
|
|
||||||
"Use Statement",
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementSuffix::UseList(use_list) => {
|
|
||||||
for identifier in use_list.identifiers() {
|
|
||||||
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_function(
|
|
||||||
function: &Function,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
|
||||||
"",
|
|
||||||
function.identifier().name(),
|
|
||||||
function.is_public(),
|
|
||||||
false,
|
|
||||||
Some(SourceDefinition::from_identifier(function.identifier())),
|
|
||||||
);
|
|
||||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
|
||||||
handle_insert_error(
|
|
||||||
insert_error,
|
|
||||||
function.identifier().name(),
|
|
||||||
function.identifier().file_id(),
|
|
||||||
function.identifier().range(),
|
|
||||||
"Function",
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gather_node(
|
|
||||||
AstNodeRef::FunctionBody(function.function_body()),
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_function_block_body(
|
|
||||||
function_block_body: &FunctionBlockBody,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
symbol_table.push_scope("FunctionBlockBody");
|
|
||||||
gather_node_children(function_block_body, symbol_table, diagnostics);
|
|
||||||
symbol_table.pop_scope();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_variable_declaration(
|
|
||||||
variable_declaration: &VariableDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let variable_symbol = VariableSymbol::new(
|
|
||||||
variable_declaration.identifier().name(),
|
|
||||||
variable_declaration.is_mut(),
|
|
||||||
Some(SourceDefinition::from_identifier(
|
|
||||||
variable_declaration.identifier(),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
if let Err(insert_error) = symbol_table.insert_variable_symbol(variable_symbol) {
|
|
||||||
handle_insert_error(
|
|
||||||
insert_error,
|
|
||||||
variable_declaration.identifier().name(),
|
|
||||||
variable_declaration.identifier().file_id(),
|
|
||||||
variable_declaration.identifier().range(),
|
|
||||||
"Variable",
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(expression) = variable_declaration.expression() {
|
|
||||||
gather_node(
|
|
||||||
AstNodeRef::Expression(expression),
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_node_children(
|
fn gather_node_children(
|
||||||
node: &impl AstNode,
|
node: &impl AstNode,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
gather_node(child, symbol_table, diagnostics);
|
gather_node(child, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_node(
|
fn gather_node(
|
||||||
node: AstNodeRef,
|
node: AstNodeRef,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match node {
|
match node {
|
||||||
AstNodeRef::Operator(_) => {}
|
AstNodeRef::Operator(_) => {}
|
||||||
AstNodeRef::Identifier(_) => {}
|
AstNodeRef::Identifier(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
AstNodeRef::FullyQualifiedName(_) => {}
|
AstNodeRef::FullyQualifiedName(_) => {}
|
||||||
AstNodeRef::TypeUseList(_) => {}
|
AstNodeRef::TypeUseList(_) => {}
|
||||||
AstNodeRef::IdentifierList(_) => {}
|
AstNodeRef::IdentifierList(_) => {}
|
||||||
@ -222,26 +89,58 @@ fn gather_node(
|
|||||||
AstNodeRef::Parameter(_) => {}
|
AstNodeRef::Parameter(_) => {}
|
||||||
AstNodeRef::ReturnType(_) => {}
|
AstNodeRef::ReturnType(_) => {}
|
||||||
AstNodeRef::CompilationUnit(compilation_unit) => {
|
AstNodeRef::CompilationUnit(compilation_unit) => {
|
||||||
gather_node_children(compilation_unit, symbol_table, diagnostics);
|
gather_node_children(compilation_unit, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
AstNodeRef::Namespace(namespace) => {
|
||||||
|
gather_namespace(namespace, fqn_context);
|
||||||
}
|
}
|
||||||
AstNodeRef::ParentMod(_) => {}
|
|
||||||
AstNodeRef::UseStatement(use_statement) => {
|
AstNodeRef::UseStatement(use_statement) => {
|
||||||
gather_use_statement(use_statement, symbol_table, diagnostics);
|
gather_use_statement(use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
AstNodeRef::UseStatementPrefix(_) => {}
|
AstNodeRef::UseStatementPrefix(_) => {
|
||||||
AstNodeRef::UseStatementSuffix(_) => {}
|
unreachable!()
|
||||||
AstNodeRef::UseList(_) => {}
|
}
|
||||||
AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => {
|
AstNodeRef::UseStatementSuffix(_) => {
|
||||||
gather_node_children(module_level_declaration, symbol_table, diagnostics);
|
unreachable!()
|
||||||
|
}
|
||||||
|
AstNodeRef::UseList(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => {
|
||||||
|
gather_node_children(
|
||||||
|
module_level_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AstNodeRef::InterfaceLevelDeclaration(interface_level_declaration) => {
|
||||||
|
gather_node_children(
|
||||||
|
interface_level_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AstNodeRef::ClassLevelDeclaration(class_level_declaration) => {
|
||||||
|
gather_node_children(
|
||||||
|
class_level_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AstNodeRef::Module(module) => {
|
||||||
|
gather_module(module, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
AstNodeRef::Interface(interface) => {
|
||||||
|
gather_interface(interface, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
AstNodeRef::Class(class) => {
|
||||||
|
gather_class(class, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
AstNodeRef::InterfaceLevelDeclaration(_) => {}
|
|
||||||
AstNodeRef::ClassLevelDeclaration(_) => {}
|
|
||||||
AstNodeRef::Module(_) => {}
|
|
||||||
AstNodeRef::CompanionModule(_) => {}
|
|
||||||
AstNodeRef::Interface(_) => {}
|
|
||||||
AstNodeRef::Class(_) => {}
|
|
||||||
AstNodeRef::Function(function) => {
|
AstNodeRef::Function(function) => {
|
||||||
gather_function(function, symbol_table, diagnostics);
|
gather_function(function, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
AstNodeRef::OperatorFunction(_) => {}
|
AstNodeRef::OperatorFunction(_) => {}
|
||||||
AstNodeRef::PlatformFunction(_) => {}
|
AstNodeRef::PlatformFunction(_) => {}
|
||||||
@ -251,25 +150,45 @@ fn gather_node(
|
|||||||
AstNodeRef::InterfaceDefaultOperatorFunction(_) => {}
|
AstNodeRef::InterfaceDefaultOperatorFunction(_) => {}
|
||||||
AstNodeRef::FunctionBody(function_body) => match function_body {
|
AstNodeRef::FunctionBody(function_body) => match function_body {
|
||||||
FunctionBody::FunctionAliasBody(alias_body) => {
|
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||||
gather_node(alias_body.as_node_ref(), symbol_table, diagnostics);
|
gather_node(
|
||||||
|
alias_body.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
FunctionBody::FunctionEqualsBody(equals_body) => {
|
FunctionBody::FunctionEqualsBody(equals_body) => {
|
||||||
gather_node(equals_body.as_node_ref(), symbol_table, diagnostics);
|
gather_node(
|
||||||
|
equals_body.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
FunctionBody::FunctionBlockBody(block_body) => {
|
FunctionBody::FunctionBlockBody(block_body) => {
|
||||||
gather_node(block_body.as_node_ref(), symbol_table, diagnostics);
|
gather_node(
|
||||||
|
block_body.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AstNodeRef::FunctionEqualsBody(_) => {}
|
AstNodeRef::FunctionEqualsBody(_) => {}
|
||||||
AstNodeRef::FunctionAliasBody(_) => {}
|
AstNodeRef::FunctionAliasBody(_) => {}
|
||||||
AstNodeRef::FunctionBlockBody(block_body) => {
|
AstNodeRef::FunctionBlockBody(block_body) => {
|
||||||
gather_function_block_body(block_body, symbol_table, diagnostics);
|
gather_function_block_body(block_body, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
AstNodeRef::ClassConstructor(_) => {}
|
AstNodeRef::ClassConstructor(_) => {}
|
||||||
AstNodeRef::Member(_) => {}
|
AstNodeRef::Member(_) => {}
|
||||||
AstNodeRef::Statement(statement) => match statement {
|
AstNodeRef::Statement(statement) => match statement {
|
||||||
Statement::VariableDeclaration(variable_declaration) => {
|
Statement::VariableDeclaration(variable_declaration) => {
|
||||||
gather_variable_declaration(variable_declaration, symbol_table, diagnostics);
|
gather_node(
|
||||||
|
variable_declaration.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Statement::AssignmentStatement(_) => {}
|
Statement::AssignmentStatement(_) => {}
|
||||||
Statement::ExpressionStatement(_) => {}
|
Statement::ExpressionStatement(_) => {}
|
||||||
@ -332,10 +251,282 @@ pub fn gather_compilation_unit(
|
|||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
identifier_scope_ids: &mut HashMap<Identifier, usize>,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
|
let mut fqn_context = FqnContext::new();
|
||||||
symbol_table.push_scope(&format!("FileScope {}", file_name));
|
symbol_table.push_scope(&format!("FileScope {}", file_name));
|
||||||
gather_node(compilation_unit.as_node_ref(), symbol_table, diagnostics);
|
gather_node(
|
||||||
|
compilation_unit.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
&mut fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gather_namespace(namespace: &Namespace, fqn_context: &mut FqnContext) {
|
||||||
|
for identifier in namespace.fqn().identifiers() {
|
||||||
|
fqn_context.push(identifier.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_use_statement(
|
||||||
|
use_statement: &UseStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let base_fqn = use_statement
|
||||||
|
.prefixes()
|
||||||
|
.map(|prefix| prefix.identifier().name())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("::");
|
||||||
|
|
||||||
|
match use_statement.suffix() {
|
||||||
|
UseStatementSuffix::Identifier(identifier) => {
|
||||||
|
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
UseStatementSuffix::Star => {
|
||||||
|
let symbol = StarUseSymbol::new(
|
||||||
|
&base_fqn,
|
||||||
|
Some(SourceDefinition::from_use_statement(use_statement)),
|
||||||
|
);
|
||||||
|
let insert_result = symbol_table.insert_star_use_symbol(symbol);
|
||||||
|
if let Err(error) = insert_result {
|
||||||
|
handle_insert_error(
|
||||||
|
error,
|
||||||
|
&base_fqn,
|
||||||
|
use_statement.file_id(),
|
||||||
|
use_statement.range(),
|
||||||
|
"Use Statement",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UseStatementSuffix::UseList(use_list) => {
|
||||||
|
for identifier in use_list.identifiers() {
|
||||||
|
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_concrete_use_symbol(
|
||||||
|
base_fqn: &str,
|
||||||
|
identifier: &Identifier,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let symbol = ConcreteUseSymbol::new(
|
||||||
|
base_fqn,
|
||||||
|
identifier.name(),
|
||||||
|
Some(SourceDefinition::from_identifier(identifier)),
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = symbol_table.insert_concrete_use_symbol(symbol) {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&base_fqn,
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
"Use Statement",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_module(
|
||||||
|
module: &Module,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let module_symbol = ModuleSymbol::new(
|
||||||
|
&fqn_context.resolve(module.identifier().name()),
|
||||||
|
module.identifier().name(),
|
||||||
|
module.is_public(),
|
||||||
|
Some(SourceDefinition::from_identifier(module.identifier())),
|
||||||
|
);
|
||||||
|
if let Err(symbol_insert_error) = symbol_table.insert_module_symbol(module_symbol) {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
module.identifier().name(),
|
||||||
|
module.identifier().file_id(),
|
||||||
|
module.identifier().range(),
|
||||||
|
"Module",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fqn_context.push(module.identifier().name());
|
||||||
|
symbol_table.push_scope(&format!("ModuleScope {}", module.identifier().name()));
|
||||||
|
|
||||||
|
for declaration in module.declarations() {
|
||||||
|
gather_node(
|
||||||
|
declaration.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_interface(
|
||||||
|
interface: &Interface,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let type_symbol = ConcreteTypeSymbol::new(
|
||||||
|
&fqn_context.resolve(interface.identifier().name()),
|
||||||
|
interface.identifier().name(),
|
||||||
|
interface.is_public(),
|
||||||
|
ConcreteTypeSymbolKind::Interface,
|
||||||
|
Some(SourceDefinition::from_identifier(interface.identifier())),
|
||||||
|
);
|
||||||
|
if let Err(symbol_insert_error) =
|
||||||
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(type_symbol))
|
||||||
|
{
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
interface.identifier().name(),
|
||||||
|
interface.identifier().file_id(),
|
||||||
|
interface.identifier().range(),
|
||||||
|
"Interface",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fqn_context.push(interface.identifier().name());
|
||||||
|
symbol_table.push_scope(&format!("InterfaceScope {}", interface.identifier().name()));
|
||||||
|
|
||||||
|
for declaration in interface.declarations() {
|
||||||
|
gather_node(
|
||||||
|
declaration.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_class(
|
||||||
|
class: &Class,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let class_symbol = ConcreteTypeSymbol::new(
|
||||||
|
&fqn_context.resolve(class.identifier().name()),
|
||||||
|
class.identifier().name(),
|
||||||
|
class.is_public(),
|
||||||
|
ConcreteTypeSymbolKind::Class,
|
||||||
|
Some(SourceDefinition::from_identifier(class.identifier())),
|
||||||
|
);
|
||||||
|
if let Err(symbol_insert_error) =
|
||||||
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(class_symbol))
|
||||||
|
{
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
class.identifier().name(),
|
||||||
|
class.identifier().file_id(),
|
||||||
|
class.identifier().range(),
|
||||||
|
"Class",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fqn_context.push(class.identifier().name());
|
||||||
|
symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name()));
|
||||||
|
|
||||||
|
for declaration in class.class_level_declarations() {
|
||||||
|
gather_node(
|
||||||
|
declaration.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_function(
|
||||||
|
function: &Function,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||||
|
&fqn_context.resolve(function.identifier().name()),
|
||||||
|
function.identifier().name(),
|
||||||
|
function.is_public(),
|
||||||
|
false,
|
||||||
|
Some(SourceDefinition::from_identifier(function.identifier())),
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
function.identifier().name(),
|
||||||
|
function.identifier().file_id(),
|
||||||
|
function.identifier().range(),
|
||||||
|
"Function",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
gather_node(
|
||||||
|
function.function_body().as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_function_block_body(
|
||||||
|
function_block_body: &FunctionBlockBody,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
symbol_table.push_scope("FunctionBlockBody");
|
||||||
|
gather_node_children(function_block_body, symbol_table, fqn_context, diagnostics);
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_variable_declaration(
|
||||||
|
variable_declaration: &VariableDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let variable_symbol = VariableSymbol::new(
|
||||||
|
variable_declaration.identifier().name(),
|
||||||
|
variable_declaration.is_mut(),
|
||||||
|
Some(SourceDefinition::from_identifier(
|
||||||
|
variable_declaration.identifier(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = symbol_table.insert_variable_symbol(variable_symbol) {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
variable_declaration.identifier().name(),
|
||||||
|
variable_declaration.identifier().file_id(),
|
||||||
|
variable_declaration.identifier().range(),
|
||||||
|
"Variable",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(expression) = variable_declaration.expression() {
|
||||||
|
gather_node(
|
||||||
|
expression.as_node_ref(),
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ use crate::name_analysis::symbol_table::SymbolTable;
|
|||||||
use codespan_reporting::files::Files;
|
use codespan_reporting::files::Files;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
mod fqn_context;
|
pub(self) mod fqn_context;
|
||||||
mod gather;
|
mod gather;
|
||||||
// mod resolve;
|
// mod resolve;
|
||||||
pub mod symbol;
|
pub mod symbol;
|
||||||
@ -44,13 +44,7 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
// gather symbols
|
// gather symbols
|
||||||
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();
|
||||||
gather_compilation_unit(
|
gather_compilation_unit(compilation_unit, &file_name, symbol_table, &mut diagnostics);
|
||||||
compilation_unit,
|
|
||||||
&file_name,
|
|
||||||
symbol_table,
|
|
||||||
&mut identifier_scope_ids,
|
|
||||||
&mut diagnostics,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve symbols
|
// resolve symbols
|
||||||
|
|||||||
@ -28,6 +28,7 @@ pub struct ConcreteTypeSymbol {
|
|||||||
fqn: String,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
|
kind: ConcreteTypeSymbolKind,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,12 +37,14 @@ impl ConcreteTypeSymbol {
|
|||||||
fqn: &str,
|
fqn: &str,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
|
kind: ConcreteTypeSymbolKind,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
is_public,
|
is_public,
|
||||||
|
kind,
|
||||||
source_definition
|
source_definition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,6 +57,10 @@ impl ConcreteTypeSymbol {
|
|||||||
self.is_public
|
self.is_public
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn kind(&self) -> &ConcreteTypeSymbolKind {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
@ -69,11 +76,18 @@ impl Debug for ConcreteTypeSymbol {
|
|||||||
.field("fqn", &self.fqn)
|
.field("fqn", &self.fqn)
|
||||||
.field("declared_name", &self.declared_name)
|
.field("declared_name", &self.declared_name)
|
||||||
.field("is_public", &self.is_public)
|
.field("is_public", &self.is_public)
|
||||||
|
.field("kind", &self.kind)
|
||||||
.field("source_definition", &self.source_definition)
|
.field("source_definition", &self.source_definition)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ConcreteTypeSymbolKind {
|
||||||
|
Interface,
|
||||||
|
Class
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GenericTypeSymbol {
|
pub struct GenericTypeSymbol {
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
|
|||||||
@ -181,7 +181,7 @@ ReturnType:
|
|||||||
CompilationUnit:
|
CompilationUnit:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
- parent_mod:
|
- namespace:
|
||||||
member:
|
member:
|
||||||
optional: true
|
optional: true
|
||||||
- use_statements:
|
- use_statements:
|
||||||
@ -196,12 +196,12 @@ CompilationUnit:
|
|||||||
- file_id:
|
- file_id:
|
||||||
special:
|
special:
|
||||||
kind: file_id
|
kind: file_id
|
||||||
ParentMod:
|
Namespace:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
- mod_kw:
|
- ns_kw:
|
||||||
skip:
|
skip:
|
||||||
rule: Mod
|
rule: Ns
|
||||||
- fqn:
|
- fqn:
|
||||||
member:
|
member:
|
||||||
rule: FullyQualifiedName
|
rule: FullyQualifiedName
|
||||||
@ -253,7 +253,6 @@ ModuleLevelDeclaration:
|
|||||||
InterfaceLevelDeclaration:
|
InterfaceLevelDeclaration:
|
||||||
tree_enum:
|
tree_enum:
|
||||||
rules:
|
rules:
|
||||||
- CompanionModule
|
|
||||||
- Interface
|
- Interface
|
||||||
- Class
|
- Class
|
||||||
- InterfaceFunction
|
- InterfaceFunction
|
||||||
@ -263,7 +262,6 @@ InterfaceLevelDeclaration:
|
|||||||
ClassLevelDeclaration:
|
ClassLevelDeclaration:
|
||||||
tree_enum:
|
tree_enum:
|
||||||
rules:
|
rules:
|
||||||
- CompanionModule
|
|
||||||
- Interface
|
- Interface
|
||||||
- Class
|
- Class
|
||||||
- Function
|
- Function
|
||||||
@ -290,21 +288,6 @@ Module:
|
|||||||
- end_kw:
|
- end_kw:
|
||||||
skip:
|
skip:
|
||||||
rule: End
|
rule: End
|
||||||
CompanionModule:
|
|
||||||
struct:
|
|
||||||
children:
|
|
||||||
- companion_kw:
|
|
||||||
skip:
|
|
||||||
rule: Companion
|
|
||||||
- mod_kw:
|
|
||||||
skip:
|
|
||||||
rule: Mod
|
|
||||||
- declarations:
|
|
||||||
vec:
|
|
||||||
rule: ModuleLevelDeclaration
|
|
||||||
- end_kw:
|
|
||||||
skip:
|
|
||||||
rule: End
|
|
||||||
Interface:
|
Interface:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
|
|||||||
@ -307,13 +307,13 @@ ReturnType = {
|
|||||||
|
|
||||||
CompilationUnit = {
|
CompilationUnit = {
|
||||||
SOI
|
SOI
|
||||||
~ ParentMod?
|
~ Namespace?
|
||||||
~ ( UseStatement | ModuleLevelDeclaration )*
|
~ ( UseStatement | ModuleLevelDeclaration )*
|
||||||
~ EOI
|
~ EOI
|
||||||
}
|
}
|
||||||
|
|
||||||
ParentMod = {
|
Namespace = {
|
||||||
Mod
|
Ns
|
||||||
~ FullyQualifiedName
|
~ FullyQualifiedName
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,8 +352,7 @@ ModuleLevelDeclaration = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InterfaceLevelDeclaration = {
|
InterfaceLevelDeclaration = {
|
||||||
CompanionModule
|
Interface
|
||||||
| Interface
|
|
||||||
| Class
|
| Class
|
||||||
| InterfaceFunction
|
| InterfaceFunction
|
||||||
| InterfaceDefaultFunction
|
| InterfaceDefaultFunction
|
||||||
@ -362,8 +361,7 @@ InterfaceLevelDeclaration = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClassLevelDeclaration = {
|
ClassLevelDeclaration = {
|
||||||
CompanionModule
|
Interface
|
||||||
| Interface
|
|
||||||
| Class
|
| Class
|
||||||
| Function
|
| Function
|
||||||
| OperatorFunction
|
| OperatorFunction
|
||||||
@ -380,13 +378,6 @@ Module = {
|
|||||||
~ End
|
~ End
|
||||||
}
|
}
|
||||||
|
|
||||||
CompanionModule = {
|
|
||||||
Companion
|
|
||||||
~ Mod
|
|
||||||
~ ModuleLevelDeclaration*
|
|
||||||
~ End
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface = {
|
Interface = {
|
||||||
Pub?
|
Pub?
|
||||||
~ IntKw
|
~ IntKw
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user