WIP on name-analysis gather, up to statements.
This commit is contained in:
parent
d5ac6dfc2d
commit
3ab59961dd
@ -1,6 +1,36 @@
|
||||
pub mod node {
|
||||
include!(concat!(env!("OUT_DIR"), "/src/ast/node.rs"));
|
||||
|
||||
impl OperatorInner {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
OperatorInner::Or => "op_or",
|
||||
OperatorInner::And => "op_and",
|
||||
OperatorInner::EqualTo => "op_eq",
|
||||
OperatorInner::NotEqualTo => "op_neq",
|
||||
OperatorInner::Greater => "op_gt",
|
||||
OperatorInner::Less => "op_lt",
|
||||
OperatorInner::GreaterEqual => "op_ge",
|
||||
OperatorInner::LessEqual => "op_le",
|
||||
OperatorInner::Add => "op_add",
|
||||
OperatorInner::Subtract => "op_sub",
|
||||
OperatorInner::Multiply => "op_mul",
|
||||
OperatorInner::Divide => "op_div",
|
||||
OperatorInner::Modulo => "op_mod",
|
||||
OperatorInner::LeftShift => "op_ls",
|
||||
OperatorInner::RightShift => "op_rs",
|
||||
OperatorInner::Spread => "op_spread",
|
||||
OperatorInner::Star => "op_star",
|
||||
OperatorInner::Not => "op_not",
|
||||
OperatorInner::Negative => "op_neg",
|
||||
OperatorInner::PlusPlus => "op_pp",
|
||||
OperatorInner::MinusMinus => "op_mm",
|
||||
OperatorInner::CallOp => "op_call",
|
||||
OperatorInner::Index => "op_index",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Parameters {
|
||||
fn default() -> Self {
|
||||
Self::new(vec![])
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
use crate::ast::ast_node::{AstNode, AstNodeRef};
|
||||
use crate::ast::node::{
|
||||
Class, CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Interface,
|
||||
Module, Namespace, Statement, UseStatement, UseStatementSuffix, VariableDeclaration,
|
||||
Class, CompilationUnit, Function, FunctionBody, Identifier, Interface,
|
||||
InterfaceDefaultFunction, InterfaceDefaultOperatorFunction, InterfaceFunction,
|
||||
InterfaceOperatorFunction, Member, Module, Namespace, OperatorFunction, PlatformFunction,
|
||||
PlatformOperatorFunction, Statement, UseStatement, UseStatementSuffix, VariableDeclaration,
|
||||
};
|
||||
use crate::diagnostic::DmDiagnostic;
|
||||
use crate::name_analysis::fqn_context::FqnContext;
|
||||
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||
@ -67,9 +70,14 @@ fn gather_node(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
match node {
|
||||
AstNodeRef::Operator(_) => {}
|
||||
AstNodeRef::Operator(_) => {
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::OperatorInner(_) => {
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::Identifier(_) => {
|
||||
unreachable!()
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::FullyQualifiedName(_) => {}
|
||||
AstNodeRef::TypeUseList(_) => {}
|
||||
@ -98,13 +106,13 @@ fn gather_node(
|
||||
gather_use_statement(use_statement, symbol_table, diagnostics);
|
||||
}
|
||||
AstNodeRef::UseStatementPrefix(_) => {
|
||||
unreachable!()
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::UseStatementSuffix(_) => {
|
||||
unreachable!()
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::UseList(_) => {
|
||||
unreachable!()
|
||||
unreachable!();
|
||||
}
|
||||
AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => {
|
||||
gather_node_children(
|
||||
@ -142,45 +150,65 @@ fn gather_node(
|
||||
AstNodeRef::Function(function) => {
|
||||
gather_function(function, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::OperatorFunction(_) => {}
|
||||
AstNodeRef::PlatformFunction(_) => {}
|
||||
AstNodeRef::InterfaceFunction(_) => {}
|
||||
AstNodeRef::InterfaceDefaultFunction(_) => {}
|
||||
AstNodeRef::InterfaceOperatorFunction(_) => {}
|
||||
AstNodeRef::InterfaceDefaultOperatorFunction(_) => {}
|
||||
AstNodeRef::FunctionBody(function_body) => match function_body {
|
||||
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||
gather_node(
|
||||
alias_body.as_node_ref(),
|
||||
AstNodeRef::OperatorFunction(operator_function) => {
|
||||
gather_operator_function(operator_function, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::PlatformFunction(platform_function) => {
|
||||
gather_platform_function(platform_function, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::PlatformOperatorFunction(platform_operator_function) => {
|
||||
gather_platform_operator_function(
|
||||
platform_operator_function,
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
FunctionBody::FunctionEqualsBody(equals_body) => {
|
||||
gather_node(
|
||||
equals_body.as_node_ref(),
|
||||
AstNodeRef::InterfaceFunction(interface_function) => {
|
||||
gather_interface_function(interface_function, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::InterfaceDefaultFunction(interface_default_function) => {
|
||||
gather_interface_default_function(
|
||||
interface_default_function,
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
FunctionBody::FunctionBlockBody(block_body) => {
|
||||
gather_node(
|
||||
block_body.as_node_ref(),
|
||||
AstNodeRef::InterfaceOperatorFunction(interface_operator_function) => {
|
||||
gather_interface_operator_function(
|
||||
interface_operator_function,
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
},
|
||||
AstNodeRef::FunctionEqualsBody(_) => {}
|
||||
AstNodeRef::FunctionAliasBody(_) => {}
|
||||
AstNodeRef::FunctionBlockBody(block_body) => {
|
||||
gather_function_block_body(block_body, symbol_table, fqn_context, diagnostics);
|
||||
AstNodeRef::InterfaceDefaultOperatorFunction(interface_default_operator_function) => {
|
||||
gather_interface_default_operator_function(
|
||||
interface_default_operator_function,
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
AstNodeRef::FunctionBody(function_body) => {
|
||||
gather_function_body(function_body, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::FunctionEqualsBody(function_equals_body) => {
|
||||
gather_node_children(function_equals_body, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::FunctionAliasBody(_) => {
|
||||
// no-op
|
||||
}
|
||||
AstNodeRef::FunctionBlockBody(function_block_body) => {
|
||||
gather_node_children(function_block_body, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::ClassConstructor(class_constructor) => {
|
||||
gather_node_children(class_constructor, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::Member(member) => {
|
||||
gather_member(member, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
AstNodeRef::ClassConstructor(_) => {}
|
||||
AstNodeRef::Member(_) => {}
|
||||
AstNodeRef::Statement(statement) => match statement {
|
||||
Statement::VariableDeclaration(variable_declaration) => {
|
||||
gather_node(
|
||||
@ -190,14 +218,59 @@ fn gather_node(
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
Statement::AssignmentStatement(_) => {}
|
||||
Statement::ExpressionStatement(_) => {}
|
||||
Statement::UseStatement(_) => {}
|
||||
Statement::IfStatement(_) => {}
|
||||
Statement::WhileStatement(_) => {}
|
||||
Statement::ForStatement(_) => {}
|
||||
Statement::AssignmentStatement(assignment_statement) => {
|
||||
gather_node(
|
||||
assignment_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
Statement::ExpressionStatement(expression_statement) => {
|
||||
gather_node(
|
||||
expression_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
Statement::UseStatement(use_statement) => {
|
||||
gather_node(
|
||||
use_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
Statement::IfStatement(if_statement) => gather_node(
|
||||
if_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
),
|
||||
Statement::WhileStatement(while_statement) => gather_node(
|
||||
while_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
),
|
||||
Statement::ForStatement(for_statement) => {
|
||||
gather_node(
|
||||
for_statement.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
},
|
||||
AstNodeRef::VariableDeclaration(_) => {}
|
||||
AstNodeRef::VariableDeclaration(variable_declaration) => {
|
||||
gather_variable_declaration(
|
||||
variable_declaration,
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
AstNodeRef::AssignmentStatement(_) => {}
|
||||
AstNodeRef::ExpressionStatement(_) => {}
|
||||
AstNodeRef::IfStatement(_) => {}
|
||||
@ -443,6 +516,12 @@ fn gather_class(
|
||||
fqn_context.push(class.identifier().name());
|
||||
symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name()));
|
||||
|
||||
gather_node(
|
||||
class.class_constructor().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
for declaration in class.class_level_declarations() {
|
||||
gather_node(
|
||||
declaration.as_node_ref(),
|
||||
@ -479,25 +558,488 @@ fn gather_function(
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
||||
gather_node(
|
||||
function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
function.function_body().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_function_block_body(
|
||||
function_block_body: &FunctionBlockBody,
|
||||
fn gather_operator_function(
|
||||
operator_function: &OperatorFunction,
|
||||
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);
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(&operator_function.operator().inner().name()),
|
||||
operator_function.operator().inner().name(),
|
||||
operator_function.is_public(),
|
||||
false,
|
||||
Some(SourceDefinition::from_operator(
|
||||
operator_function.operator(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
operator_function.operator().inner().name(),
|
||||
operator_function.operator().file_id(),
|
||||
operator_function.operator().range(),
|
||||
"Operator",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"FunctionScope {}",
|
||||
operator_function.operator().inner().name()
|
||||
));
|
||||
gather_node(
|
||||
operator_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
operator_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
operator_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
operator_function.function_body().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_platform_function(
|
||||
platform_function: &PlatformFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(platform_function.identifier().name()),
|
||||
platform_function.identifier().name(),
|
||||
platform_function.is_public(),
|
||||
true,
|
||||
Some(SourceDefinition::from_identifier(
|
||||
platform_function.identifier(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
platform_function.identifier().name(),
|
||||
platform_function.identifier().file_id(),
|
||||
platform_function.identifier().range(),
|
||||
"Function",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"PlatformFunctionScope {}",
|
||||
platform_function.identifier().name()
|
||||
));
|
||||
gather_node(
|
||||
platform_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
platform_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
platform_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_platform_operator_function(
|
||||
platform_operator_function: &PlatformOperatorFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(platform_operator_function.operator().inner().name()),
|
||||
platform_operator_function.operator().inner().name(),
|
||||
platform_operator_function.is_public(),
|
||||
true,
|
||||
Some(SourceDefinition::from_operator(
|
||||
platform_operator_function.operator(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
platform_operator_function.operator().inner().name(),
|
||||
platform_operator_function.operator().file_id(),
|
||||
platform_operator_function.operator().range(),
|
||||
"Function",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"PlatformOperatorFunctionScope {}",
|
||||
platform_operator_function.operator().inner().name()
|
||||
));
|
||||
gather_node(
|
||||
platform_operator_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
platform_operator_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
platform_operator_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_interface_function(
|
||||
interface_function: &InterfaceFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(interface_function.identifier().name()),
|
||||
interface_function.identifier().name(),
|
||||
true,
|
||||
false,
|
||||
Some(SourceDefinition::from_identifier(
|
||||
interface_function.identifier(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
interface_function.identifier().name(),
|
||||
interface_function.identifier().file_id(),
|
||||
interface_function.identifier().range(),
|
||||
"Type",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"InterfaceFunctionScope {}",
|
||||
interface_function.identifier().name()
|
||||
));
|
||||
gather_node(
|
||||
interface_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_interface_default_function(
|
||||
interface_default_function: &InterfaceDefaultFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(interface_default_function.identifier().name()),
|
||||
interface_default_function.identifier().name(),
|
||||
true,
|
||||
false,
|
||||
Some(SourceDefinition::from_identifier(
|
||||
interface_default_function.identifier(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
interface_default_function.identifier().name(),
|
||||
interface_default_function.identifier().file_id(),
|
||||
interface_default_function.identifier().range(),
|
||||
"Function",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"InterfaceDefaultFunctionScope {}",
|
||||
interface_default_function.identifier().name()
|
||||
));
|
||||
gather_node(
|
||||
interface_default_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_function.function_body().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_interface_operator_function(
|
||||
interface_operator_function: &InterfaceOperatorFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(interface_operator_function.operator().inner().name()),
|
||||
interface_operator_function.operator().inner().name(),
|
||||
true,
|
||||
false,
|
||||
Some(SourceDefinition::from_operator(
|
||||
interface_operator_function.operator(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
interface_operator_function.operator().inner().name(),
|
||||
interface_operator_function.operator().file_id(),
|
||||
interface_operator_function.operator().range(),
|
||||
"Function",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"InterfaceOperatorFunctionScope {}",
|
||||
interface_operator_function.operator().inner().name()
|
||||
));
|
||||
gather_node(
|
||||
interface_operator_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_operator_function.parameters().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_operator_function.return_type().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_interface_default_operator_function(
|
||||
interface_default_operator_function: &InterfaceDefaultOperatorFunction,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
|
||||
&fqn_context.resolve(
|
||||
interface_default_operator_function
|
||||
.operator()
|
||||
.inner()
|
||||
.name(),
|
||||
),
|
||||
interface_default_operator_function
|
||||
.operator()
|
||||
.inner()
|
||||
.name(),
|
||||
true,
|
||||
false,
|
||||
Some(SourceDefinition::from_operator(
|
||||
interface_default_operator_function.operator(),
|
||||
)),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
interface_default_operator_function
|
||||
.operator()
|
||||
.inner()
|
||||
.name(),
|
||||
interface_default_operator_function.operator().file_id(),
|
||||
interface_default_operator_function.operator().range(),
|
||||
"Function",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
symbol_table.push_scope(&format!(
|
||||
"InterfaceDefaultOperatorFunctionScope {}",
|
||||
interface_default_operator_function
|
||||
.operator()
|
||||
.inner()
|
||||
.name()
|
||||
));
|
||||
gather_node(
|
||||
interface_default_operator_function.generics().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_operator_function
|
||||
.parameters()
|
||||
.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_operator_function
|
||||
.return_type()
|
||||
.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_node(
|
||||
interface_default_operator_function
|
||||
.function_body()
|
||||
.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_function_body(
|
||||
function_body: &FunctionBody,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
symbol_table.push_scope("FunctionBodyScope");
|
||||
match function_body {
|
||||
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||
gather_node(
|
||||
alias_body.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
FunctionBody::FunctionEqualsBody(equals_body) => {
|
||||
gather_node(
|
||||
equals_body.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
FunctionBody::FunctionBlockBody(block_body) => {
|
||||
gather_node(
|
||||
block_body.as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
}
|
||||
symbol_table.pop_scope();
|
||||
}
|
||||
|
||||
fn gather_member(
|
||||
member: &Member,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let member_symbol = ClassMemberSymbol::new(
|
||||
member.is_public(),
|
||||
member.is_mut(),
|
||||
member.identifier().name(),
|
||||
Some(SourceDefinition::from_identifier(member.identifier())),
|
||||
);
|
||||
if let Err(insert_error) = symbol_table.insert_class_member_symbol(member_symbol) {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
member.identifier().name(),
|
||||
member.identifier().file_id(),
|
||||
member.identifier().range(),
|
||||
"Class Member",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
gather_node(
|
||||
member.type_use().as_node_ref(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn gather_variable_declaration(
|
||||
variable_declaration: &VariableDeclaration,
|
||||
symbol_table: &mut SymbolTable,
|
||||
|
||||
@ -3,30 +3,37 @@ use std::fmt::{Debug, Formatter};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClassMemberSymbol {
|
||||
is_public: bool,
|
||||
is_mut: bool,
|
||||
declared_name: String,
|
||||
is_field: bool,
|
||||
source_definition: Option<SourceDefinition>,
|
||||
}
|
||||
|
||||
impl ClassMemberSymbol {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
is_mut: bool,
|
||||
declared_name: &str,
|
||||
is_field: bool,
|
||||
source_definition: Option<SourceDefinition>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
is_mut,
|
||||
declared_name: declared_name.to_string(),
|
||||
is_field,
|
||||
source_definition,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn is_field(&self) -> bool {
|
||||
self.is_field
|
||||
pub fn is_mut(&self) -> bool {
|
||||
self.is_mut
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||
@ -37,8 +44,9 @@ impl ClassMemberSymbol {
|
||||
impl Debug for ClassMemberSymbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ClassMemberSymbol")
|
||||
.field("is_public", &self.is_public)
|
||||
.field("is_mut", &self.is_mut)
|
||||
.field("declared_name", &self.declared_name)
|
||||
.field("is_field", &self.is_field)
|
||||
.field("source_definition", &self.source_definition)
|
||||
.finish()
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::range::Range;
|
||||
use std::rc::Rc;
|
||||
use crate::ast::node::{Identifier, UseStatement};
|
||||
use crate::ast::node::{Identifier, Operator, UseStatement};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SourceDefinition {
|
||||
@ -17,14 +17,6 @@ impl SourceDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self {
|
||||
let borrowed = identifier.borrow();
|
||||
SourceDefinition {
|
||||
file_id: borrowed.file_id(),
|
||||
range: borrowed.range(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_use_statement(use_statement: &UseStatement) -> Self {
|
||||
Self {
|
||||
file_id: use_statement.file_id(),
|
||||
@ -32,6 +24,13 @@ impl SourceDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_operator(operator: &Operator) -> Self {
|
||||
Self {
|
||||
file_id: operator.file_id(),
|
||||
range: operator.range(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
@ -57,11 +57,11 @@ impl SymbolTable {
|
||||
}
|
||||
|
||||
fn current_scope(&self) -> &Scope {
|
||||
self.scopes.last().unwrap()
|
||||
&self.scopes[self.current_scope_id]
|
||||
}
|
||||
|
||||
fn current_scope_mut(&mut self) -> &mut Scope {
|
||||
self.scopes.last_mut().unwrap()
|
||||
&mut self.scopes[self.current_scope_id]
|
||||
}
|
||||
|
||||
fn find_current_scope_concrete_use_symbol(
|
||||
|
||||
@ -127,7 +127,13 @@ macro_rules! write_symbols {
|
||||
|
||||
impl Display for Scope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "----Scope {} {}----", self.id(), self.debug_name())?;
|
||||
writeln!(
|
||||
f,
|
||||
"----Scope {} (p: {}) {}----",
|
||||
self.id(),
|
||||
self.parent().map(|parent_id| format!("{}", parent_id)).unwrap_or_else(|| "None".to_string()),
|
||||
self.debug_name()
|
||||
)?;
|
||||
write_symbols!(f, self.concrete_use_symbols());
|
||||
write_symbols!(f, self.star_use_symbols());
|
||||
write_symbols!(f, self.module_symbols());
|
||||
|
||||
@ -1,6 +1,18 @@
|
||||
# $schema: ./ast.schema.yaml
|
||||
# Operators
|
||||
Operator:
|
||||
struct:
|
||||
children:
|
||||
- inner:
|
||||
member:
|
||||
rule: OperatorInner
|
||||
- file_id:
|
||||
special:
|
||||
kind: file_id
|
||||
- range:
|
||||
special:
|
||||
kind: range
|
||||
OperatorInner:
|
||||
leaf_enum:
|
||||
rules:
|
||||
- Or
|
||||
@ -429,6 +441,30 @@ PlatformFunction:
|
||||
- identifier
|
||||
- parameters
|
||||
- return_type
|
||||
PlatformOperatorFunction:
|
||||
struct:
|
||||
children:
|
||||
- is_public:
|
||||
member:
|
||||
rule: Pub
|
||||
build:
|
||||
boolean:
|
||||
on: rule_present
|
||||
- platform_kw:
|
||||
skip:
|
||||
rule: Platform
|
||||
- op_kw:
|
||||
skip:
|
||||
rule: Op
|
||||
- generics:
|
||||
member:
|
||||
rule: GenericParameters
|
||||
build:
|
||||
node:
|
||||
or_else_default: true
|
||||
- operator
|
||||
- parameters
|
||||
- return_type
|
||||
InterfaceFunction:
|
||||
struct:
|
||||
children:
|
||||
|
||||
@ -131,6 +131,10 @@ Index = { "[]" }
|
||||
BorrowMut = { Borrow ~ Mut }
|
||||
|
||||
Operator = {
|
||||
OperatorInner
|
||||
}
|
||||
|
||||
OperatorInner = {
|
||||
Or
|
||||
| And
|
||||
| EqualTo
|
||||
@ -431,6 +435,16 @@ PlatformFunction = {
|
||||
~ ReturnType
|
||||
}
|
||||
|
||||
PlatformOperatorFunction = {
|
||||
Pub?
|
||||
~ Platform
|
||||
~ Op
|
||||
~ GenericParameters?
|
||||
~ Operator
|
||||
~ Parameters
|
||||
~ ReturnType
|
||||
}
|
||||
|
||||
InterfaceFunction = {
|
||||
Fn
|
||||
~ GenericParameters?
|
||||
|
||||
Loading…
Reference in New Issue
Block a user