Properly using dyn for better dispatch of gather methods.

This commit is contained in:
Jesse Brault 2025-10-13 11:58:30 -05:00
parent 6b206605c1
commit dd249dd5bd
11 changed files with 153 additions and 579 deletions

View File

@ -16,7 +16,7 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream {
let child_ident = format_ident!("{}", node_child.node_kind().to_case(Case::Snake)); let child_ident = format_ident!("{}", node_child.node_kind().to_case(Case::Snake));
quote! { quote! {
#type_ident::#rule_ident(#child_ident) => vec![ #type_ident::#rule_ident(#child_ident) => vec![
#child_ident.as_node_ref() #child_ident
] ]
} }
} }
@ -35,14 +35,14 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
match self { match self {
#(#match_arms,)* #(#match_arms,)*
} }
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }

View File

@ -1,18 +1,18 @@
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.build()); let type_ident = format_ident!("{}", spec.build());
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
vec![] vec![]
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }
} }
} }

View File

@ -5,12 +5,12 @@ use quote::{format_ident, quote};
pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream { pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.build()); let type_ident = format_ident!("{}", spec.build());
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
vec![] vec![]
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }

View File

@ -70,4 +70,35 @@ pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> {
#type_ident(&'a #type_ident) #type_ident(&'a #type_ident)
} }
}) })
}
pub fn make_ast_node_ref_unwrapper(build_spec: &BuildSpec) -> Option<TokenStream> {
match build_spec {
BuildSpec::Enum(enum_spec) => {
Some(format_ident!("{}", enum_spec.build()))
}
BuildSpec::LeafEnum(leaf_enum) => {
Some(format_ident!("{}", leaf_enum.build()))
}
BuildSpec::Struct(struct_spec) => {
Some(format_ident!("{}", struct_spec.build()))
}
BuildSpec::LeafStruct(leaf_struct) => {
Some(format_ident!("{}", leaf_struct.build()))
}
BuildSpec::Production(_) => None,
BuildSpec::NodeProduction(_) => None,
BuildSpec::PolymorphicType(polymorphic_type) => {
Some(format_ident!("{}", polymorphic_type.name()))
}
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
Some(format_ident!("{}", polymorphic_enum_loop.name()))
}
BuildSpec::PolymorphicPassThrough(_) => None
}
.map(|type_ident| {
quote! {
AstNodeRef::#type_ident(inner) => *inner
}
})
} }

View File

@ -28,20 +28,20 @@ pub fn make_polymorphic_enum_loop_ast_node_impl(
} }
}; };
quote! { quote! {
children.push(self.#child_ident().as_node_ref()) children.push(self.#child_ident() as &dyn AstNode);
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
let mut children: Vec<AstNodeRef> = vec![]; let mut children = vec![];
#(#child_adders;)* #(#child_adders;)*
children children
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }

View File

@ -11,20 +11,20 @@ pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> T
let variant_ident = format_ident!("{}", variant.name()); let variant_ident = format_ident!("{}", variant.name());
let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake)); let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake));
quote! { quote! {
#type_ident::#variant_ident(#child_ident) => vec![#child_ident.as_node_ref()] #type_ident::#variant_ident(#child_ident) => vec![#child_ident]
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
match self { match self {
#(#match_arms,)* #(#match_arms,)*
} }
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }

View File

@ -13,8 +13,8 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
VecChildBuild::Node(_) => { VecChildBuild::Node(_) => {
let child_ident = format_ident!("{}", vec_child.name()); let child_ident = format_ident!("{}", vec_child.name());
let children_stream = quote! { let children_stream = quote! {
for child in self.#child_ident().map(AstNode::as_node_ref) { for child in self.#child_ident() {
children.push(child); children.push(child as &dyn AstNode);
} }
}; };
Some(children_stream) Some(children_stream)
@ -26,12 +26,12 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
if member_child.optional() { if member_child.optional() {
Some(quote! { Some(quote! {
if let Some(#child_ident) = self.#child_ident() { if let Some(#child_ident) = self.#child_ident() {
children.push(#child_ident.as_node_ref()); children.push(#child_ident as &dyn AstNode);
} }
}) })
} else { } else {
Some(quote! { Some(quote! {
children.push(self.#child_ident().as_node_ref()) children.push(self.#child_ident() as &dyn AstNode)
}) })
} }
} }
@ -44,14 +44,14 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
quote! { quote! {
impl AstNode for #type_ident { impl<'a> AstNode<'a> for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> {
let mut children: Vec<AstNodeRef> = vec![]; let mut children = vec![];
#(#child_adders;)* #(#child_adders;)*
children children
} }
fn as_node_ref(&self) -> AstNodeRef { fn as_node_ref(&'a self) -> AstNodeRef<'a> {
AstNodeRef::#type_ident(&self) AstNodeRef::#type_ident(&self)
} }
} }

View File

@ -6,7 +6,7 @@ mod spec;
mod type_gen; mod type_gen;
mod walk; mod walk;
use crate::ast_node::{make_ast_enum_member, make_ast_node_impl}; use crate::ast_node::{make_ast_enum_member, make_ast_node_impl, make_ast_node_ref_unwrapper};
use crate::build_fn::make_build_fn; use crate::build_fn::make_build_fn;
use crate::deserialize::deserialize_yaml_spec; use crate::deserialize::deserialize_yaml_spec;
use crate::pretty_print::make_pretty_print_impl; use crate::pretty_print::make_pretty_print_impl;
@ -165,6 +165,13 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
.map(Option::unwrap) .map(Option::unwrap)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let inner_unwrappers = build_specs
.iter()
.map(|build_spec| make_ast_node_ref_unwrapper(build_spec))
.filter(Option::is_some)
.map(Option::unwrap)
.collect::<Vec<_>>();
let combined = quote! { let combined = quote! {
use crate::ast::node::*; use crate::ast::node::*;
@ -172,10 +179,18 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
#(#ast_enum_members,)* #(#ast_enum_members,)*
} }
pub trait AstNode { impl<'a> AstNodeRef<'a> {
fn children(&self) -> Vec<AstNodeRef>; pub fn inner(&self) -> &dyn AstNode<'a> {
match self {
#(#inner_unwrappers,)*
}
}
}
fn as_node_ref(&self) -> AstNodeRef; pub trait AstNode<'a> {
fn children(&'a self) -> Vec<&'a dyn AstNode<'a>>;
fn as_node_ref(&'a self) -> AstNodeRef<'a>;
} }
#(#impls)* #(#impls)*

View File

@ -1,59 +1,16 @@
use crate::spec::BuildSpec; use crate::spec::BuildSpec;
use convert_case::{Case, Casing};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::quote;
pub fn make_walk_fn(specs: &[BuildSpec]) -> TokenStream { pub fn make_walk_fn(specs: &[BuildSpec]) -> TokenStream {
let child_match_arms = specs
.iter()
.map(|spec| match spec {
BuildSpec::Enum(enum_spec) => Some((
format_ident!("{}", enum_spec.build()),
format_ident!("{}", enum_spec.build().to_case(Case::Snake)),
)),
BuildSpec::LeafEnum(leaf_enum) => Some((
format_ident!("{}", leaf_enum.build()),
format_ident!("{}", leaf_enum.build().to_case(Case::Snake)),
)),
BuildSpec::Struct(struct_spec) => Some((
format_ident!("{}", struct_spec.build()),
format_ident!("{}", struct_spec.build().to_case(Case::Snake)),
)),
BuildSpec::LeafStruct(leaf_struct) => Some((
format_ident!("{}", leaf_struct.build()),
format_ident!("{}", leaf_struct.build().to_case(Case::Snake)),
)),
BuildSpec::Production(_) => None,
BuildSpec::NodeProduction(_) => None,
BuildSpec::PolymorphicType(polymorphic_type) => Some((
format_ident!("{}", polymorphic_type.name()),
format_ident!("{}", polymorphic_type.name().to_case(Case::Snake)),
)),
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => Some((
format_ident!("{}", polymorphic_enum_loop.name()),
format_ident!("{}", polymorphic_enum_loop.name().to_case(Case::Snake)),
)),
BuildSpec::PolymorphicPassThrough(_) => None,
})
.filter(Option::is_some)
.map(Option::unwrap)
.map(|(type_ident, inner_ident)| {
quote! {
#type_ident(#inner_ident) => walk_depth_first(#inner_ident, f)
}
})
.collect::<Vec<_>>();
quote! { quote! {
use crate::ast::node::*; use crate::ast::node::*;
use crate::ast::ast_node::*; use crate::ast::ast_node::*;
pub fn walk_depth_first(node: &impl AstNode, f: &mut impl FnMut(AstNodeRef)) { pub fn walk_depth_first<'a>(node: &'a dyn AstNode<'a>, f: &mut impl FnMut(AstNodeRef<'a>)) {
use AstNodeRef::*; use AstNodeRef::*;
for child in node.children() { for child in node.children() {
match child { walk_depth_first(child, f);
#(#child_match_arms,)*
}
} }
f(node.as_node_ref()); f(node.as_node_ref());
} }

View File

@ -28,9 +28,9 @@ pub mod node {
OperatorInner::CallOp => "op_call", OperatorInner::CallOp => "op_call",
OperatorInner::Index => "op_index", OperatorInner::Index => "op_index",
} }
} }
} }
impl Default for Parameters { impl Default for Parameters {
fn default() -> Self { fn default() -> Self {
Self::new(vec![]) Self::new(vec![])

View File

@ -1,5 +1,12 @@
use crate::ast::ast_node::{AstNode, AstNodeRef}; use crate::ast::ast_node::{AstNode, AstNodeRef};
use crate::ast::node::{Class, Closure, ClosureParameter, CompilationUnit, ForStatement, FullyQualifiedName, Function, FunctionBody, GenericArguments, GenericParameters, Identifier, IfClause, Interface, InterfaceDefaultFunction, InterfaceDefaultOperatorFunction, InterfaceFunction, InterfaceOperatorFunction, Member, Module, Namespace, OperatorFunction, Parameter, PlatformFunction, PlatformOperatorFunction, PrimitiveType, TernaryExpression, UseStatement, UseStatementSuffix, VariableDeclaration, VariableUse, WhileStatement}; use crate::ast::node::{
Class, Closure, ClosureParameter, CompilationUnit, ForStatement, FullyQualifiedName, Function,
FunctionBody, GenericParameters, Identifier, IfClause, Interface, InterfaceDefaultFunction,
InterfaceDefaultOperatorFunction, InterfaceFunction, InterfaceOperatorFunction, Member, Module,
Namespace, OperatorFunction, Parameter, PlatformFunction, PlatformOperatorFunction,
PrimitiveType, TernaryExpression, UseStatement, UseStatementSuffix, VariableDeclaration,
VariableUse, WhileStatement,
};
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::fqn_context::FqnContext; use crate::name_analysis::fqn_context::FqnContext;
use crate::name_analysis::scope_table::ScopeTable; use crate::name_analysis::scope_table::ScopeTable;
@ -50,7 +57,7 @@ fn handle_insert_error(
} }
fn gather_node_children<'a>( fn gather_node_children<'a>(
node: &'a impl AstNode, node: &'a dyn AstNode<'a>,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext, fqn_context: &mut FqnContext,
scope_table: &mut ScopeTable<'a>, scope_table: &mut ScopeTable<'a>,
@ -62,148 +69,37 @@ fn gather_node_children<'a>(
} }
fn gather_node<'a>( fn gather_node<'a>(
node: AstNodeRef<'a>, node: &'a dyn AstNode<'a>,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext, fqn_context: &mut FqnContext,
scope_table: &mut ScopeTable<'a>, scope_table: &mut ScopeTable<'a>,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
match node { match node.as_node_ref() {
AstNodeRef::Operator(_) => {
unreachable!();
}
AstNodeRef::OperatorInner(_) => {
unreachable!();
}
AstNodeRef::Identifier(_) => {
unreachable!();
}
AstNodeRef::FullyQualifiedName(fully_qualified_name) => { AstNodeRef::FullyQualifiedName(fully_qualified_name) => {
gather_fully_qualified_name(fully_qualified_name, symbol_table, scope_table); gather_fully_qualified_name(fully_qualified_name, symbol_table, scope_table);
} }
AstNodeRef::TypeUseList(type_use_list) => {
gather_node_children(
type_use_list,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::IdentifierList(_) => {
unreachable!();
}
AstNodeRef::ParenthesesTypeUseList(parentheses_type_useList) => {
gather_node_children(
parentheses_type_useList,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::TypeUse(type_use) => {
gather_node_children(
type_use,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::PrimitiveType(primitive_type) => { AstNodeRef::PrimitiveType(primitive_type) => {
gather_primitive_type(primitive_type, symbol_table, fqn_context, scope_table, diagnostics); gather_primitive_type(
} primitive_type,
AstNodeRef::TypedArray(typed_array) => {
gather_node_children(typed_array, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::InterfaceOrClassTypeUse(interface_or_class_type_use) => {
gather_node_children(
interface_or_class_type_use,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
} }
AstNodeRef::TupleTypeUse(tuple_type_use) => {
gather_node_children(tuple_type_use, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::FunctionTypeUse(function_type_use) => {
gather_node_children(function_type_use, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::GenericArguments(generic_arguments) => {
gather_node_children(generic_arguments, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::GenericParameters(generic_parameters) => { AstNodeRef::GenericParameters(generic_parameters) => {
gather_generic_parameters(generic_parameters, symbol_table, diagnostics); gather_generic_parameters(generic_parameters, symbol_table, diagnostics);
} }
AstNodeRef::TupleArguments(tuple_arguments) => {
gather_node_children(tuple_arguments, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::ImplementsList(implements_list) => {
gather_node_children(implements_list, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::Parameters(parameters) => {
gather_node_children(parameters, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::Parameter(parameter) => { AstNodeRef::Parameter(parameter) => {
gather_parameter(parameter, symbol_table, diagnostics); gather_parameter(parameter, symbol_table, diagnostics);
} }
AstNodeRef::ReturnType(return_type) => {
gather_node_children(return_type, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::CompilationUnit(compilation_unit) => {
gather_node_children(
compilation_unit,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::Namespace(namespace) => { AstNodeRef::Namespace(namespace) => {
gather_namespace(namespace, fqn_context); gather_namespace(namespace, fqn_context);
} }
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(_) => {
unreachable!();
}
AstNodeRef::UseStatementSuffix(_) => {
unreachable!();
}
AstNodeRef::UseList(_) => {
unreachable!();
}
AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => {
gather_node_children(
module_level_declaration,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::InterfaceLevelDeclaration(interface_level_declaration) => {
gather_node_children(
interface_level_declaration,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ClassLevelDeclaration(class_level_declaration) => {
gather_node_children(
class_level_declaration,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::Module(module) => { AstNodeRef::Module(module) => {
gather_module(module, symbol_table, fqn_context, scope_table, diagnostics); gather_module(module, symbol_table, fqn_context, scope_table, diagnostics);
} }
@ -300,48 +196,9 @@ fn gather_node<'a>(
diagnostics, diagnostics,
); );
} }
AstNodeRef::FunctionEqualsBody(function_equals_body) => {
gather_node_children(
function_equals_body,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::FunctionAliasBody(_) => {
// no-op
}
AstNodeRef::FunctionBlockBody(function_block_body) => {
gather_node_children(
function_block_body,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ClassConstructor(class_constructor) => {
gather_node_children(
class_constructor,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::Member(member) => { AstNodeRef::Member(member) => {
gather_member(member, symbol_table, fqn_context, scope_table, diagnostics); gather_member(member, symbol_table, fqn_context, scope_table, diagnostics);
} }
AstNodeRef::Statement(statement) => {
gather_node_children(
statement,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::VariableDeclaration(variable_declaration) => { AstNodeRef::VariableDeclaration(variable_declaration) => {
gather_variable_declaration( gather_variable_declaration(
variable_declaration, variable_declaration,
@ -351,33 +208,6 @@ fn gather_node<'a>(
diagnostics, diagnostics,
); );
} }
AstNodeRef::AssignmentStatement(assignment_statement) => {
gather_node_children(
assignment_statement,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ExpressionStatement(expression_statement) => {
gather_node_children(
expression_statement,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::IfStatement(if_statement) => {
gather_node_children(
if_statement,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::IfClause(if_clause) => { AstNodeRef::IfClause(if_clause) => {
gather_if_clause( gather_if_clause(
if_clause, if_clause,
@ -396,9 +226,6 @@ fn gather_node<'a>(
diagnostics, diagnostics,
); );
} }
AstNodeRef::IfElse(if_else) => {
gather_node_children(if_else, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::WhileStatement(while_statement) => { AstNodeRef::WhileStatement(while_statement) => {
gather_while_statement( gather_while_statement(
while_statement, while_statement,
@ -420,27 +247,9 @@ fn gather_node<'a>(
AstNodeRef::LValue(l_value) => { AstNodeRef::LValue(l_value) => {
gather_node_children(l_value, symbol_table, fqn_context, scope_table, diagnostics); gather_node_children(l_value, symbol_table, fqn_context, scope_table, diagnostics);
} }
AstNodeRef::LValueSuffix(l_value_suffix) => {
gather_node_children(
l_value_suffix,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::VariableUse(variable_use) => { AstNodeRef::VariableUse(variable_use) => {
gather_variable_use(variable_use, symbol_table, scope_table); gather_variable_use(variable_use, symbol_table, scope_table);
} }
AstNodeRef::Expression(expression) => {
gather_node_children(
expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::TernaryExpression(ternary_expression) => { AstNodeRef::TernaryExpression(ternary_expression) => {
gather_ternary_expression( gather_ternary_expression(
ternary_expression, ternary_expression,
@ -450,219 +259,10 @@ fn gather_node<'a>(
diagnostics, diagnostics,
); );
} }
AstNodeRef::TernaryRhs(ternary_rhs) => {
gather_node_children(
ternary_rhs,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::OrExpression(or_expression) => {
gather_node_children(
or_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::OrRhs(or_rhs) => {
gather_node_children(or_rhs, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::AndExpression(and_expression) => {
gather_node_children(
and_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::AndRhs(and_rhs) => {
gather_node_children(and_rhs, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::ComparisonExpression(comparison_expression) => {
gather_node_children(
comparison_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ComparisonRhs(comparison_rhs) => {
gather_node_children(
comparison_rhs,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ComparisonOperator(_) => {
// no-op
}
AstNodeRef::ShiftExpression(shift_expression) => {
gather_node_children(
shift_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ShiftRhs(shift_rhs) => {
gather_node_children(
shift_rhs,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ShiftOperator(_) => {
// no-op
}
AstNodeRef::AdditiveExpression(additive_expression) => {
gather_node_children(
additive_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::AdditiveRhs(additive_rhs) => {
gather_node_children(
additive_rhs,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::AdditiveOperator(_) => {
// no-op
}
AstNodeRef::MultiplicativeExpression(multiplicative_expression) => {
gather_node_children(
multiplicative_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::MultiplicativeRhs(multiplicative_rhs) => {
gather_node_children(
multiplicative_rhs,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::MultiplicativeOperator(_) => {
// no-op
}
AstNodeRef::PrefixExpression(prefix_expression) => {
gather_node_children(
prefix_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::PrefixOperator(_) => {
// no-op
}
AstNodeRef::SuffixExpression(suffix_expression) => {
gather_node_children(
suffix_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::SuffixOperator(_) => {
// no-op
}
AstNodeRef::ObjectProperty(_) => {
// no-op
}
AstNodeRef::ObjectIndex(object_index) => {
gather_node_children(
object_index,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ListExpression(list_expression) => {
gather_node_children(
list_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::Call(call) => {
gather_node_children(call, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::ParenthesesCall(parentheses_call) => {
gather_node_children(
parentheses_call,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::NonParenthesesCall(non_parentheses_call) => {
gather_node_children(
non_parentheses_call,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::TurboFish(turbo_fish) => {
gather_node_children(
turbo_fish,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ExpressionList(expression_list) => {
gather_node_children(
expression_list,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::Closure(closure) => { AstNodeRef::Closure(closure) => {
gather_closure(closure, symbol_table, fqn_context, scope_table, diagnostics); gather_closure(closure, symbol_table, fqn_context, scope_table, diagnostics);
} }
AstNodeRef::ClosureParameters(closure_parameters) => {
gather_node_children(
closure_parameters,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::ClosureParameter(closure_parameter) => { AstNodeRef::ClosureParameter(closure_parameter) => {
gather_closure_parameter( gather_closure_parameter(
closure_parameter, closure_parameter,
@ -672,36 +272,7 @@ fn gather_node<'a>(
diagnostics, diagnostics,
); );
} }
AstNodeRef::Literal(literal) => { _ => gather_node_children(node, symbol_table, fqn_context, scope_table, diagnostics),
gather_node_children(literal, symbol_table, fqn_context, scope_table, diagnostics);
}
AstNodeRef::DString(d_string) => {
gather_node_children(
d_string,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::DStringExpression(d_string_expression) => {
gather_node_children(
d_string_expression,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
AstNodeRef::BacktickString(backtick_string) => {
gather_node_children(
backtick_string,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
}
} }
} }
@ -718,11 +289,17 @@ fn gather_primitive_type<'a>(
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext, fqn_context: &mut FqnContext,
scope_table: &mut ScopeTable<'a>, scope_table: &mut ScopeTable<'a>,
diagnostics: &mut Vec<DmDiagnostic> diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
match primitive_type { match primitive_type {
PrimitiveType::TypedArray(typed_array) => { PrimitiveType::TypedArray(typed_array) => {
gather_node(typed_array.as_node_ref(), symbol_table, fqn_context, scope_table, diagnostics); gather_node(
typed_array,
symbol_table,
fqn_context,
scope_table,
diagnostics,
);
} }
_ => {} _ => {}
} }
@ -782,7 +359,7 @@ pub fn gather_compilation_unit<'a>(
let mut fqn_context = FqnContext::new(); let mut fqn_context = FqnContext::new();
symbol_table.push_scope(&format!("FileScope {}", file_name)); symbol_table.push_scope(&format!("FileScope {}", file_name));
gather_node( gather_node(
compilation_unit.as_node_ref(), compilation_unit,
symbol_table, symbol_table,
&mut fqn_context, &mut fqn_context,
scope_table, scope_table,
@ -889,7 +466,7 @@ fn gather_module<'a>(
for declaration in module.declarations() { for declaration in module.declarations() {
gather_node( gather_node(
declaration.as_node_ref(), declaration,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -933,7 +510,7 @@ fn gather_interface<'a>(
for declaration in interface.declarations() { for declaration in interface.declarations() {
gather_node( gather_node(
declaration.as_node_ref(), declaration,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -976,7 +553,7 @@ fn gather_class<'a>(
symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name())); symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name()));
gather_node( gather_node(
class.class_constructor().as_node_ref(), class.class_constructor(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -984,7 +561,7 @@ fn gather_class<'a>(
); );
for declaration in class.class_level_declarations() { for declaration in class.class_level_declarations() {
gather_node( gather_node(
declaration.as_node_ref(), declaration,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1022,28 +599,28 @@ fn gather_function<'a>(
} }
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name())); symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
gather_node( gather_node(
function.generics().as_node_ref(), function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
function.parameters().as_node_ref(), function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
function.return_type().as_node_ref(), function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
function.function_body().as_node_ref(), function.function_body(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1083,28 +660,28 @@ fn gather_operator_function<'a>(
operator_function.operator().inner().name() operator_function.operator().inner().name()
)); ));
gather_node( gather_node(
operator_function.generics().as_node_ref(), operator_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
operator_function.parameters().as_node_ref(), operator_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
operator_function.return_type().as_node_ref(), operator_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
operator_function.function_body().as_node_ref(), operator_function.function_body(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1144,21 +721,21 @@ fn gather_platform_function<'a>(
platform_function.identifier().name() platform_function.identifier().name()
)); ));
gather_node( gather_node(
platform_function.generics().as_node_ref(), platform_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
platform_function.parameters().as_node_ref(), platform_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
platform_function.return_type().as_node_ref(), platform_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1198,21 +775,21 @@ fn gather_platform_operator_function<'a>(
platform_operator_function.operator().inner().name() platform_operator_function.operator().inner().name()
)); ));
gather_node( gather_node(
platform_operator_function.generics().as_node_ref(), platform_operator_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
platform_operator_function.parameters().as_node_ref(), platform_operator_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
platform_operator_function.return_type().as_node_ref(), platform_operator_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1252,21 +829,21 @@ fn gather_interface_function<'a>(
interface_function.identifier().name() interface_function.identifier().name()
)); ));
gather_node( gather_node(
interface_function.generics().as_node_ref(), interface_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_function.parameters().as_node_ref(), interface_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_function.return_type().as_node_ref(), interface_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1306,28 +883,28 @@ fn gather_interface_default_function<'a>(
interface_default_function.identifier().name() interface_default_function.identifier().name()
)); ));
gather_node( gather_node(
interface_default_function.generics().as_node_ref(), interface_default_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_function.parameters().as_node_ref(), interface_default_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_function.return_type().as_node_ref(), interface_default_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_function.function_body().as_node_ref(), interface_default_function.function_body(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1367,21 +944,21 @@ fn gather_interface_operator_function<'a>(
interface_operator_function.operator().inner().name() interface_operator_function.operator().inner().name()
)); ));
gather_node( gather_node(
interface_operator_function.generics().as_node_ref(), interface_operator_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_operator_function.parameters().as_node_ref(), interface_operator_function.parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_operator_function.return_type().as_node_ref(), interface_operator_function.return_type(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1435,34 +1012,28 @@ fn gather_interface_default_operator_function<'a>(
.name() .name()
)); ));
gather_node( gather_node(
interface_default_operator_function.generics().as_node_ref(), interface_default_operator_function.generics(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_operator_function interface_default_operator_function.parameters(),
.parameters()
.as_node_ref(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_operator_function interface_default_operator_function.return_type(),
.return_type()
.as_node_ref(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
diagnostics, diagnostics,
); );
gather_node( gather_node(
interface_default_operator_function interface_default_operator_function.function_body(),
.function_body()
.as_node_ref(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1513,7 +1084,7 @@ fn gather_member<'a>(
); );
} }
gather_node( gather_node(
member.type_use().as_node_ref(), member.type_use(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1547,7 +1118,7 @@ fn gather_variable_declaration<'a>(
} }
if let Some(expression) = variable_declaration.expression() { if let Some(expression) = variable_declaration.expression() {
gather_node( gather_node(
expression.as_node_ref(), expression,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1565,7 +1136,7 @@ fn gather_if_clause<'a>(
) { ) {
symbol_table.push_scope("IfClauseScope"); symbol_table.push_scope("IfClauseScope");
gather_node( gather_node(
if_clause.expression().as_node_ref(), if_clause.expression(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1574,7 +1145,7 @@ fn gather_if_clause<'a>(
symbol_table.push_scope("IfClauseStatementsScope"); symbol_table.push_scope("IfClauseStatementsScope");
for statement in if_clause.statements() { for statement in if_clause.statements() {
gather_node( gather_node(
statement.as_node_ref(), statement,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1594,7 +1165,7 @@ fn gather_while_statement<'a>(
) { ) {
symbol_table.push_scope("WhileStatementScope"); symbol_table.push_scope("WhileStatementScope");
gather_node( gather_node(
while_statement.expression().as_node_ref(), while_statement.expression(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1603,7 +1174,7 @@ fn gather_while_statement<'a>(
symbol_table.push_scope("WhileStatementStatementsScope"); symbol_table.push_scope("WhileStatementStatementsScope");
for statement in while_statement.statements() { for statement in while_statement.statements() {
gather_node( gather_node(
statement.as_node_ref(), statement,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1622,7 +1193,7 @@ fn gather_for_statement<'a>(
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
gather_node( gather_node(
for_statement.expression().as_node_ref(), for_statement.expression(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1649,7 +1220,7 @@ fn gather_for_statement<'a>(
symbol_table.push_scope("ForStatementStatementsScope"); symbol_table.push_scope("ForStatementStatementsScope");
for statement in for_statement.statements() { for statement in for_statement.statements() {
gather_node( gather_node(
statement.as_node_ref(), statement,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1695,7 +1266,7 @@ fn gather_closure<'a>(
) { ) {
symbol_table.push_scope("ClosureScope"); symbol_table.push_scope("ClosureScope");
gather_node( gather_node(
closure.closure_parameters().as_node_ref(), closure.closure_parameters(),
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1704,7 +1275,7 @@ fn gather_closure<'a>(
symbol_table.push_scope("ClosureStatementsScope"); symbol_table.push_scope("ClosureStatementsScope");
for statement in closure.statements() { for statement in closure.statements() {
gather_node( gather_node(
statement.as_node_ref(), statement,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,
@ -1740,7 +1311,7 @@ fn gather_closure_parameter<'a>(
} }
if let Some(type_use) = closure_parameter.type_use() { if let Some(type_use) = closure_parameter.type_use() {
gather_node( gather_node(
type_use.as_node_ref(), type_use,
symbol_table, symbol_table,
fqn_context, fqn_context,
scope_table, scope_table,