From a560d540c094fff8c9fd23053b421e200788f94f Mon Sep 17 00:00:00 2001 From: SpontanCombust <61706594+SpontanCombust@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:58:29 +0200 Subject: [PATCH] Add context parameter to traversed nodes --- crates/analysis/src/jobs/scan_symbols.rs | 24 +-- .../syntax_analysis/syntax_error_visitor.rs | 94 ++++----- crates/core/src/ast/classes.rs | 38 ++-- crates/core/src/ast/conditionals.rs | 44 ++-- crates/core/src/ast/enums.rs | 16 +- crates/core/src/ast/expressions.rs | 191 +++++++++++------- crates/core/src/ast/functions.rs | 120 +++++++---- crates/core/src/ast/loops.rs | 26 ++- crates/core/src/ast/nop.rs | 10 +- crates/core/src/ast/root.rs | 20 +- crates/core/src/ast/states.rs | 8 +- crates/core/src/ast/structs.rs | 55 +++-- crates/core/src/ast/traversal/contexts.rs | 72 +++++++ crates/core/src/ast/traversal/mod.rs | 14 +- crates/core/src/ast/traversal/visitor.rs | 103 +++++----- crates/core/src/ast/vars.rs | 14 +- crates/core/src/script.rs | 7 +- crates/core/src/tokens/identifier.rs | 9 +- crates/core/src/tokens/literals.rs | 11 +- 19 files changed, 550 insertions(+), 326 deletions(-) create mode 100644 crates/core/src/ast/traversal/contexts.rs diff --git a/crates/analysis/src/jobs/scan_symbols.rs b/crates/analysis/src/jobs/scan_symbols.rs index ba3be19c..663d2136 100644 --- a/crates/analysis/src/jobs/scan_symbols.rs +++ b/crates/analysis/src/jobs/scan_symbols.rs @@ -23,7 +23,7 @@ pub fn scan_symbols(script: &Script, doc: &ScriptDocument, doc_path: &AbsPath, s current_ordinal: 0 }; - script.root_node().accept(&mut visitor); + script.root_node().accept(&mut visitor, ()); visitor.diagnostics } @@ -333,13 +333,13 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { fn exit_global_func_decl(&mut self, n: &GlobalFunctionDeclarationNode) { if self.current_path.components().last().map(|comp| comp.category == SymbolCategory::Callable).unwrap_or(false) { - n.definition().accept(self); + n.definition().accept(self, FunctionTraversalContext::GlobalFunction); self.current_path.pop(); self.current_ordinal = 0; } } - fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) -> MemberFunctionDeclarationTraversalPolicy { + fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode, _: PropertyTraversalContext) -> MemberFunctionDeclarationTraversalPolicy { let mut traverse_params = false; let name_node = n.name(); @@ -377,16 +377,16 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { } } - fn exit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) { + fn exit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode, _: PropertyTraversalContext) { // pop only if visit managed to create the symbol if self.current_path.components().last().map(|comp| comp.category == SymbolCategory::Callable).unwrap_or(false) { - n.definition().accept(self); + n.definition().accept(self, FunctionTraversalContext::MemberFunction); self.current_path.pop(); self.current_ordinal = 0; } } - fn visit_event_decl(&mut self, n: &EventDeclarationNode) -> EventDeclarationTraversalPolicy { + fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: PropertyTraversalContext) -> EventDeclarationTraversalPolicy { let mut traverse_params = false; let name_node = n.name(); @@ -407,15 +407,15 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { } } - fn exit_event_decl(&mut self, n: &EventDeclarationNode) { + fn exit_event_decl(&mut self, n: &EventDeclarationNode, _: PropertyTraversalContext) { if self.current_path.components().last().map(|comp| comp.category == SymbolCategory::Callable).unwrap_or(false) { - n.definition().accept(self); + n.definition().accept(self, FunctionTraversalContext::Event); self.current_path.pop(); self.current_ordinal = 0; } } - fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode) { + fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) { let mut specifiers = HashSet::new(); for (spec, range) in n.specifiers().map(|specn| (specn.value(), specn.range())) { if !specifiers.insert(spec) { @@ -445,7 +445,7 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { } } - fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode) { + fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: PropertyTraversalContext) { let mut specifiers = HashSet::new(); let mut found_access_modif_before = false; for (spec, range) in n.specifiers().map(|specn| (specn.value(), specn.range())) { @@ -486,7 +486,7 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { } } - fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode) { + fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: PropertyTraversalContext) { let name_node = n.name(); if let Some(autobind_name) = name_node.value(&self.doc) { let path = DataSymbolPath::new(&self.current_path, &autobind_name); @@ -522,7 +522,7 @@ impl DeclarationVisitor for SymbolScannerVisitor<'_> { } impl StatementVisitor for SymbolScannerVisitor<'_> { - fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode) { + fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode, _: StatementTraversalContext) { let type_path = self.check_type_from_type_annot(n.var_type()); for name_node in n.names() { diff --git a/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs b/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs index 79963464..c4d7c623 100644 --- a/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs +++ b/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs @@ -10,7 +10,7 @@ pub fn syntax_analysis(script_root: RootNode, diagnostics: &mut Vec { } } - fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode) { + fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: PropertyTraversalContext) { if n.has_errors() { n.names().for_each(|name| { self.check_identifier(&name); } ); self.check_type_annot(&n.var_type()); @@ -233,20 +233,20 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode) { + fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: PropertyTraversalContext) { if n.has_errors() { self.check_identifier(&n.member()); let value = n.value(); if !self.check_expression(&value) { - value.accept(self); + value.accept(self, ExpressionTraversalContext::MemberDefaultValue); } self.check_errors(n); } } - fn visit_member_hint(&mut self, n: &MemberHintNode) { + fn visit_member_hint(&mut self, n: &MemberHintNode, _: PropertyTraversalContext) { if n.has_errors() { self.check_identifier(&n.member()); self.check_missing(&n.value(), "hint string"); @@ -255,7 +255,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode) { + fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: PropertyTraversalContext) { if n.has_errors() { self.check_identifier(&n.name()); self.check_type_annot(&n.autobind_type()); @@ -264,7 +264,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode) { + fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) { if n.has_errors() { n.names().for_each(|name| { self.check_identifier(&name); } ); self.check_type_annot(&n.param_type()); @@ -289,7 +289,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { let def = n.definition(); if !self.check_function_def(&def) { - def.accept(self); + def.accept(self, FunctionTraversalContext::GlobalFunction); } } @@ -298,7 +298,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) -> MemberFunctionDeclarationTraversalPolicy { + fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode, _: PropertyTraversalContext) -> MemberFunctionDeclarationTraversalPolicy { let mut traverse_params = false; if n.has_errors() { self.check_identifier(&n.name()); @@ -317,7 +317,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { let def = n.definition(); if !self.check_function_def(&def) { - def.accept(self); + def.accept(self, FunctionTraversalContext::MemberFunction); } } @@ -326,7 +326,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_event_decl(&mut self, n: &EventDeclarationNode) -> EventDeclarationTraversalPolicy { + fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: PropertyTraversalContext) -> EventDeclarationTraversalPolicy { let mut traverse_params = false; if n.has_errors() { self.check_identifier(&n.name()); @@ -345,7 +345,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { let def = n.definition(); if !self.check_function_def(&def) { - def.accept(self); + def.accept(self, FunctionTraversalContext::Event); } } @@ -354,7 +354,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode) -> MemberDefaultsBlockTraversalPolicy { + fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: PropertyTraversalContext) -> MemberDefaultsBlockTraversalPolicy { let traverse = if n.has_errors() { self.check_errors(n); true @@ -373,7 +373,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { let value = n.value(); if !self.check_expression(&value) { - value.accept(self); + value.accept(self, ExpressionTraversalContext::MemberDefaultValue); } self.check_errors(n); @@ -382,7 +382,7 @@ impl DeclarationVisitor for SyntaxErrorVisitor<'_> { } impl StatementVisitor for SyntaxErrorVisitor<'_> { - fn visit_block_stmt(&mut self, n: &FunctionBlockNode) -> FunctionBlockTraversalPolicy { + fn visit_block_stmt(&mut self, n: &FunctionBlockNode, _: FunctionBlockTraversalContext) -> FunctionBlockTraversalPolicy { let traverse = if n.has_errors() { self.check_errors(n); true @@ -395,7 +395,7 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode) { + fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode, _: StatementTraversalContext) { if n.has_errors() { n.names().for_each(|name| { self.check_identifier(&name); } ); self.check_type_annot(&n.var_type()); @@ -404,61 +404,61 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode) { + fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: StatementTraversalContext) { if n.has_errors() { let expr = n.expr(); if !self.check_expression(&expr) { - expr.accept(self); + expr.accept(self, ExpressionTraversalContext::ExpressionStatement); } self.check_errors(n); } } - fn visit_return_stmt(&mut self, n: &ReturnStatementNode) { + fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: StatementTraversalContext) { if n.has_errors() { if let Some(value) = n.value() { - value.accept(self); + value.accept(self, ExpressionTraversalContext::ReturnStatement); } self.check_errors(n); } } - fn visit_break_stmt(&mut self, n: &BreakStatementNode) { + fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: StatementTraversalContext) { if n.has_errors() { self.check_errors(n); } } - fn visit_continue_stmt(&mut self, n: &ContinueStatementNode) { + fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: StatementTraversalContext) { if n.has_errors() { self.check_errors(n); } } - fn visit_delete_stmt(&mut self, n: &DeleteStatementNode) { + fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: StatementTraversalContext) { if n.has_errors() { let value = n.value(); if !self.check_expression(&value) { - value.accept(self); + value.accept(self, ExpressionTraversalContext::DeleteStatement); } self.check_errors(n); } } - fn visit_for_stmt(&mut self, n: &ForLoopNode) -> ForLoopTraversalPolicy { + fn visit_for_stmt(&mut self, n: &ForLoopNode, _: StatementTraversalContext) -> ForLoopTraversalPolicy { let mut traverse_body = false; if n.has_errors() { if let Some(init) = n.init() { - init.accept(self); + init.accept(self, ExpressionTraversalContext::ForLoopInit); } if let Some(cond) = n.cond() { - cond.accept(self) + cond.accept(self, ExpressionTraversalContext::ForLoopCond) } if let Some(iter) = n.iter() { - iter.accept(self); + iter.accept(self, ExpressionTraversalContext::ForLoopIter); } self.check_errors(n); @@ -471,12 +471,12 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_while_stmt(&mut self, n: &WhileLoopNode) -> WhileLoopTraversalPolicy { + fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: StatementTraversalContext) -> WhileLoopTraversalPolicy { let mut traverse_body = false; if n.has_errors() { let cond = n.cond(); if !self.check_expression(&cond) { - cond.accept(self); + cond.accept(self, ExpressionTraversalContext::WhileLoopCond); } self.check_errors(n); @@ -489,12 +489,12 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode) -> DoWhileLoopTraversalPolicy { + fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: StatementTraversalContext) -> DoWhileLoopTraversalPolicy { let mut traverse_body = false; if n.has_errors() { let cond = n.cond(); if !self.check_expression(&cond) { - cond.accept(self); + cond.accept(self, ExpressionTraversalContext::DoWhileLoopCond); } self.check_errors(n); @@ -507,13 +507,13 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_if_stmt(&mut self, n: &IfConditionalNode) -> IfConditionalTraversalPolicy { + fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: StatementTraversalContext) -> IfConditionalTraversalPolicy { let mut traverse_body = false; let mut traverse_else_body = false; if n.has_errors() { let cond = n.cond(); if !self.check_expression(&cond) { - cond.accept(self); + cond.accept(self, ExpressionTraversalContext::IfConditionalCond); } self.check_errors(n); @@ -528,12 +528,12 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode) -> SwitchConditionalTraversalPolicy { + fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: StatementTraversalContext) -> SwitchConditionalTraversalPolicy { let mut traverse_body = false; if n.has_errors() { let cond = n.cond(); if !self.check_expression(&cond) { - cond.accept(self); + cond.accept(self, ExpressionTraversalContext::SwitchConditionalCond); } self.check_errors(n); @@ -554,7 +554,7 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { if n.has_errors() { let value = n.value(); if !self.check_expression(&value) { - value.accept(self); + value.accept(self, ExpressionTraversalContext::SwitchConditionalCaseLabel); } self.check_errors(n); @@ -569,7 +569,7 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> { } impl ExpressionVisitor for SyntaxErrorVisitor<'_> { - fn visit_array_expr(&mut self, n: &ArrayExpressionNode) -> ArrayExpressionTraversalPolicy { + fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy { let traverse_accessor = !self.check_expression(&n.accessor()); let traverse_index = !self.check_expression(&n.index()); @@ -581,7 +581,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode) -> AssignmentOperationExpressionTraversalPolicy { + fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy { let traverse_left = !self.check_expression(&n.left()); let traverse_right = !self.check_expression(&n.right()); @@ -593,7 +593,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode) -> BinaryOperationExpressionTraversalPolicy { + fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy { let traverse_left = !self.check_expression(&n.left()); let traverse_right = !self.check_expression(&n.right()); @@ -605,7 +605,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode) -> UnaryOperationExpressionTraversalPolicy { + fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy { let traverse_right = !self.check_expression(&n.right()); self.check_errors(n); @@ -615,7 +615,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode) -> FunctionCallExpressionTraversalPolicy { + fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy { let func = n.func(); let traverse_func = !self.check_missing(&func, "function") || func.has_errors(); @@ -635,7 +635,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_new_expr(&mut self, n: &NewExpressionNode) -> NewExpressionTraversalPolicy { + fn visit_new_expr(&mut self, n: &NewExpressionNode, _: ExpressionTraversalContext) -> NewExpressionTraversalPolicy { self.check_identifier(&n.class()); let mut traverse_lifetime_obj = false; @@ -650,7 +650,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_member_field_expr(&mut self, n: &MemberFieldExpressionNode) -> MemberFieldExpressionTraversalPolicy { + fn visit_member_field_expr(&mut self, n: &MemberFieldExpressionNode, _: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy { let traverse_accessor = !self.check_expression(&n.accessor()); self.check_identifier(&n.member()); @@ -661,7 +661,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_nested_expr(&mut self, n: &NestedExpressionNode) -> NestedExpressionTraversalPolicy { + fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy { let traverse_inner = !self.check_expression(&n.inner()); self.check_errors(n); @@ -671,7 +671,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode) -> TernaryConditionalExpressionTraversalPolicy { + fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy { let traverse_cond = !self.check_expression(&n.cond()); let traverse_conseq = !self.check_expression(&n.conseq()); let traverse_alt = !self.check_expression(&n.alt()); @@ -685,7 +685,7 @@ impl ExpressionVisitor for SyntaxErrorVisitor<'_> { } } - fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode) -> TypeCastExpressionTraversalPolicy { + fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy { self.check_identifier(&n.target_type()); let traverse_value = !self.check_expression(&n.value()); diff --git a/crates/core/src/ast/classes.rs b/crates/core/src/ast/classes.rs index 07356fad..54616987 100644 --- a/crates/core/src/ast/classes.rs +++ b/crates/core/src/ast/classes.rs @@ -59,17 +59,19 @@ impl<'script> TryFrom> for ClassDeclarationNode<'script> { } impl DeclarationTraversal for ClassDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_class_decl(self); if tp.traverse_definition { - self.definition().accept(visitor); + self.definition().accept(visitor, PropertyTraversalContext::ClassDefinition); } visitor.exit_class_decl(self); } } - +//TODO make seperate StateBlockNode type with the same NODE_KIND to disambiguate traversal with state pub type ClassBlockNode<'script> = SyntaxNode<'script, tags::ClassBlock>; impl NamedSyntaxNode for ClassBlockNode<'_> { @@ -104,8 +106,10 @@ impl<'script> TryFrom> for ClassBlockNode<'script> { } impl DeclarationTraversal for ClassBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - self.iter().for_each(|s| s.accept(visitor)); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + self.iter().for_each(|s| s.accept(visitor, ctx)); } } @@ -180,15 +184,17 @@ impl<'script> TryFrom> for ClassStatementNode<'script> { } impl DeclarationTraversal for ClassStatementNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { match self.clone().value() { - ClassStatement::Var(s) => s.accept(visitor), - ClassStatement::Default(s) => s.accept(visitor), - ClassStatement::DefaultsBlock(s) => s.accept(visitor), - ClassStatement::Hint(s) => s.accept(visitor), - ClassStatement::Autobind(s) => s.accept(visitor), - ClassStatement::Method(s) => s.accept(visitor), - ClassStatement::Event(s) => s.accept(visitor), + ClassStatement::Var(s) => s.accept(visitor, ctx), + ClassStatement::Default(s) => s.accept(visitor, ctx), + ClassStatement::DefaultsBlock(s) => s.accept(visitor, ctx), + ClassStatement::Hint(s) => s.accept(visitor, ctx), + ClassStatement::Autobind(s) => s.accept(visitor, ctx), + ClassStatement::Method(s) => s.accept(visitor, ctx), + ClassStatement::Event(s) => s.accept(visitor, ctx), ClassStatement::Nop(_) => {}, } } @@ -250,8 +256,10 @@ impl<'script> TryFrom> for AutobindDeclarationNode<'script> { } impl DeclarationTraversal for AutobindDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_autobind_decl(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_autobind_decl(self, ctx); } } diff --git a/crates/core/src/ast/conditionals.rs b/crates/core/src/ast/conditionals.rs index 105be4f4..3dbebc58 100644 --- a/crates/core/src/ast/conditionals.rs +++ b/crates/core/src/ast/conditionals.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{StatementTraversal, StatementVisitor, ExpressionNode, FunctionStatementNode}; +use super::*; mod tags { @@ -55,13 +55,15 @@ impl<'script> TryFrom> for IfConditionalNode<'script> { } impl StatementTraversal for IfConditionalNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_if_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_if_stmt(self, ctx); if tp.traverse_body { - self.body().accept(visitor); + self.body().accept(visitor, StatementTraversalContext::IfConditionalBody); } if tp.traverse_else_body { - self.else_body().map(|s| { s.accept(visitor) }); + self.else_body().map(|s| { s.accept(visitor, StatementTraversalContext::IfConditionalElseBody) }); } } } @@ -106,10 +108,12 @@ impl<'script> TryFrom> for SwitchConditionalNode<'script> { } impl StatementTraversal for SwitchConditionalNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_switch_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_switch_stmt(self, ctx); if tp.traverse_body { - self.body().accept(visitor); + self.body().accept(visitor, ()); } } } @@ -150,8 +154,10 @@ impl<'script> TryFrom> for SwitchConditionalBlockNode<'script> } impl StatementTraversal for SwitchConditionalBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - self.sections().for_each(|s| s.accept(visitor)); + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { + self.sections().for_each(|s| s.accept(visitor, ())); } } @@ -219,11 +225,13 @@ impl<'script> TryFrom> for SwitchConditionalSectionNode<'script } impl StatementTraversal for SwitchConditionalSectionNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { match self.clone().value() { - SwitchConditionalSection::Statement(n) => n.accept(visitor), - SwitchConditionalSection::Case(n) => n.accept(visitor), - SwitchConditionalSection::Default(n) => n.accept(visitor), + SwitchConditionalSection::Statement(n) => n.accept(visitor, StatementTraversalContext::SwitchConditionalBody), + SwitchConditionalSection::Case(n) => n.accept(visitor, ()), + SwitchConditionalSection::Default(n) => n.accept(visitor, ()), } } } @@ -263,7 +271,9 @@ impl<'script> TryFrom> for SwitchConditionalCaseLabelNode<'scri } impl StatementTraversal for SwitchConditionalCaseLabelNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { visitor.visit_switch_stmt_case(self); } } @@ -295,7 +305,9 @@ impl<'script> TryFrom> for SwitchConditionalDefaultLabelNode<'s } impl StatementTraversal for SwitchConditionalDefaultLabelNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { visitor.visit_switch_stmt_default(self); } } \ No newline at end of file diff --git a/crates/core/src/ast/enums.rs b/crates/core/src/ast/enums.rs index 8a4d28f1..58b8941f 100644 --- a/crates/core/src/ast/enums.rs +++ b/crates/core/src/ast/enums.rs @@ -48,10 +48,12 @@ impl<'script> TryFrom> for EnumDeclarationNode<'script> { } impl DeclarationTraversal for EnumDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_enum_decl(self); if tp.traverse_definition { - self.definition().accept(visitor); + self.definition().accept(visitor, ()); } visitor.exit_enum_decl(self); } @@ -93,8 +95,10 @@ impl<'script> TryFrom> for EnumBlockNode<'script> { } impl DeclarationTraversal for EnumBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - self.iter().for_each(|s| s.accept(visitor)); + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { + self.iter().for_each(|s| s.accept(visitor, ())); } } @@ -144,7 +148,9 @@ impl<'script> TryFrom> for EnumVariantDeclarationNode<'script> } impl DeclarationTraversal for EnumVariantDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { visitor.visit_enum_variant_decl(self); } } diff --git a/crates/core/src/ast/expressions.rs b/crates/core/src/ast/expressions.rs index ad2fc3ac..aad11e8b 100644 --- a/crates/core/src/ast/expressions.rs +++ b/crates/core/src/ast/expressions.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{tokens::*, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{StatementTraversal, ExpressionVisitor, ExpressionTraversal, StatementVisitor}; +use super::*; mod tags { @@ -56,12 +56,14 @@ impl<'script> TryFrom> for NestedExpressionNode<'script> { } impl ExpressionTraversal for NestedExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_nested_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_nested_expr(self, ctx); if tp.traverse_inner { - self.inner().accept(visitor); + self.inner().accept(visitor, ExpressionTraversalContext::NestedExpressionInner); } - visitor.exit_nested_expr(self); + visitor.exit_nested_expr(self, ctx); } } @@ -94,8 +96,10 @@ impl<'script> TryFrom> for ThisExpressionNode<'script> { } impl ExpressionTraversal for ThisExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_this_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_this_expr(self, ctx); } } @@ -128,8 +132,10 @@ impl<'script> TryFrom> for SuperExpressionNode<'script> { } impl ExpressionTraversal for SuperExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_super_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_super_expr(self, ctx); } } @@ -162,8 +168,10 @@ impl<'script> TryFrom> for ParentExpressionNode<'script> { } impl ExpressionTraversal for ParentExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_parent_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_parent_expr(self, ctx); } } @@ -196,8 +204,10 @@ impl<'script> TryFrom> for VirtualParentExpressionNode<'script> } impl ExpressionTraversal for VirtualParentExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_virtual_parent_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_virtual_parent_expr(self, ctx); } } @@ -241,15 +251,17 @@ impl<'script> TryFrom> for FunctionCallExpressionNode<'script> } impl ExpressionTraversal for FunctionCallExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_func_call_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_func_call_expr(self, ctx); if tp.traverse_func { - self.func().accept(visitor); + self.func().accept(visitor, ExpressionTraversalContext::FunctionCallExpressionFunc); } if tp.traverse_args { - self.args().map(|n| n.accept(visitor)); + self.args().map(|n| n.accept(visitor, ())); } - visitor.exit_func_call_expr(self); + visitor.exit_func_call_expr(self, ctx); } } @@ -309,8 +321,10 @@ impl<'script> TryFrom> for FunctionCallArgumentsNode<'script> { } impl ExpressionTraversal for FunctionCallArgumentsNode<'_> { - fn accept(&self, visitor: &mut V) { - self.iter().for_each(|n| n.accept(visitor)) + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { + self.iter().for_each(|n| n.accept(visitor, ())) } } @@ -331,11 +345,13 @@ impl Debug for FunctionCallArgument<'_> { } impl ExpressionTraversal for FunctionCallArgument<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_func_call_arg(self); if tp.traverse_expr { if let FunctionCallArgument::Some(n) = self { - n.accept(visitor); + n.accept(visitor, ExpressionTraversalContext::FunctionCallArg); } } visitor.exit_func_call_arg(self); @@ -382,15 +398,17 @@ impl<'script> TryFrom> for ArrayExpressionNode<'script> { } impl ExpressionTraversal for ArrayExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_array_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_array_expr(self, ctx); if tp.traverse_accessor { - self.accessor().accept(visitor); + self.accessor().accept(visitor, ExpressionTraversalContext::ArrayExpressionAccessor); } if tp.traverse_index { - self.index().accept(visitor); + self.index().accept(visitor, ExpressionTraversalContext::ArrayExpressionIndex); } - visitor.exit_array_expr(self); + visitor.exit_array_expr(self, ctx); } } @@ -434,12 +452,14 @@ impl<'script> TryFrom> for MemberFieldExpressionNode<'script> { } impl ExpressionTraversal for MemberFieldExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_member_field_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_member_field_expr(self, ctx); if tp.traverse_accessor { - self.accessor().accept(visitor); + self.accessor().accept(visitor, ExpressionTraversalContext::MemberFieldExpressionAccessor); } - visitor.exit_member_field_expr(self); + visitor.exit_member_field_expr(self, ctx); } } @@ -483,12 +503,14 @@ impl<'script> TryFrom> for NewExpressionNode<'script> { } impl ExpressionTraversal for NewExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_new_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_new_expr(self, ctx); if tp.traverse_lifetime_obj { - self.lifetime_obj().map(|n| n.accept(visitor)); + self.lifetime_obj().map(|n| n.accept(visitor, ExpressionTraversalContext::NewExpressionLifetimeObj)); } - visitor.exit_new_expr(self); + visitor.exit_new_expr(self, ctx); } } @@ -532,12 +554,14 @@ impl<'script> TryFrom> for TypeCastExpressionNode<'script> { } impl ExpressionTraversal for TypeCastExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_type_cast_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_type_cast_expr(self, ctx); if tp.traverse_value { - self.value().accept(visitor); + self.value().accept(visitor, ExpressionTraversalContext::TypeCastExpressionValue); } - visitor.exit_type_cast_expr(self); + visitor.exit_type_cast_expr(self, ctx); } } @@ -581,12 +605,14 @@ impl<'script> TryFrom> for UnaryOperationExpressionNode<'script } impl ExpressionTraversal for UnaryOperationExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_unary_op_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_unary_op_expr(self, ctx); if tp.traverse_right { - self.right().accept(visitor); + self.right().accept(visitor, ExpressionTraversalContext::UnaryOperationExpressionRight); } - visitor.exit_unary_op_expr(self); + visitor.exit_unary_op_expr(self, ctx); } } @@ -635,15 +661,17 @@ impl<'script> TryFrom> for BinaryOperationExpressionNode<'scrip } impl ExpressionTraversal for BinaryOperationExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_binary_op_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_binary_op_expr(self, ctx); if tp.traverse_left { - self.left().accept(visitor); + self.left().accept(visitor, ExpressionTraversalContext::BinaryOperationExpressionLeft); } if tp.traverse_right { - self.right().accept(visitor); + self.right().accept(visitor, ExpressionTraversalContext::BinaryOperationExpressionRight); } - visitor.exit_binary_op_expr(self); + visitor.exit_binary_op_expr(self, ctx); } } @@ -692,15 +720,17 @@ impl<'script> TryFrom> for AssignmentOperationExpressionNode<'s } impl ExpressionTraversal for AssignmentOperationExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_assign_op_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_assign_op_expr(self, ctx); if tp.traverse_left { - self.left().accept(visitor); + self.left().accept(visitor, ExpressionTraversalContext::AssignmentOperationExpressionLeft); } if tp.traverse_right { - self.right().accept(visitor); + self.right().accept(visitor, ExpressionTraversalContext::AssignmentOperationExpressionRight); } - visitor.exit_assign_op_expr(self); + visitor.exit_assign_op_expr(self, ctx); } } @@ -749,17 +779,20 @@ impl<'script> TryFrom> for TernaryConditionalExpressionNode<'sc } impl ExpressionTraversal for TernaryConditionalExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_ternary_cond_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_ternary_cond_expr(self, ctx); if tp.traverse_cond { - self.cond().accept(visitor); + self.cond().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionCond); } if tp.traverse_conseq { - self.conseq().accept(visitor); + self.conseq().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionConseq); } if tp.traverse_alt { - self.alt().accept(visitor); + self.alt().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionAlt); } + visitor.exit_ternary_cond_expr(self, ctx); } } @@ -884,24 +917,26 @@ impl<'script> TryFrom> for ExpressionNode<'script> { } impl ExpressionTraversal for ExpressionNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { match self.clone().value() { - Expression::Nested(n) => n.accept(visitor), - Expression::Literal(n) => n.accept(visitor), - Expression::This(n) => n.accept(visitor), - Expression::Super(n) => n.accept(visitor), - Expression::Parent(n) => n.accept(visitor), - Expression::VirtualParent(n) => n.accept(visitor), - Expression::Identifier(n) => n.accept(visitor), - Expression::FunctionCall(n) => n.accept(visitor), - Expression::Array(n) => n.accept(visitor), - Expression::MemberField(n) => n.accept(visitor), - Expression::New(n) => n.accept(visitor), - Expression::TypeCast(n) => n.accept(visitor), - Expression::UnaryOperation(n) => n.accept(visitor), - Expression::BinaryOperation(n) => n.accept(visitor), - Expression::AssignmentOperation(n) => n.accept(visitor), - Expression::TernaryConditional(n) => n.accept(visitor), + Expression::Nested(n) => n.accept(visitor, ctx), + Expression::Literal(n) => n.accept(visitor, ctx), + Expression::This(n) => n.accept(visitor, ctx), + Expression::Super(n) => n.accept(visitor, ctx), + Expression::Parent(n) => n.accept(visitor, ctx), + Expression::VirtualParent(n) => n.accept(visitor, ctx), + Expression::Identifier(n) => n.accept(visitor, ctx), + Expression::FunctionCall(n) => n.accept(visitor, ctx), + Expression::Array(n) => n.accept(visitor, ctx), + Expression::MemberField(n) => n.accept(visitor, ctx), + Expression::New(n) => n.accept(visitor, ctx), + Expression::TypeCast(n) => n.accept(visitor, ctx), + Expression::UnaryOperation(n) => n.accept(visitor, ctx), + Expression::BinaryOperation(n) => n.accept(visitor, ctx), + Expression::AssignmentOperation(n) => n.accept(visitor, ctx), + Expression::TernaryConditional(n) => n.accept(visitor, ctx), } } } @@ -941,7 +976,9 @@ impl<'script> TryFrom> for ExpressionStatementNode<'script> { } impl StatementTraversal for ExpressionStatementNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_expr_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_expr_stmt(self, ctx); } } \ No newline at end of file diff --git a/crates/core/src/ast/functions.rs b/crates/core/src/ast/functions.rs index dbea7368..85282599 100644 --- a/crates/core/src/ast/functions.rs +++ b/crates/core/src/ast/functions.rs @@ -65,12 +65,14 @@ impl<'script> TryFrom> for EventDeclarationNode<'script> { } impl DeclarationTraversal for EventDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_event_decl(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_event_decl(self, ctx); if tp.traverse_params { - self.params().accept(visitor); + self.params().accept(visitor, FunctionTraversalContext::Event); } - visitor.exit_event_decl(self); + visitor.exit_event_decl(self, ctx); } } @@ -134,10 +136,12 @@ impl<'script> TryFrom> for GlobalFunctionDeclarationNode<'scrip } impl DeclarationTraversal for GlobalFunctionDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_global_func_decl(self); if tp.traverse_params { - self.params().accept(visitor); + self.params().accept(visitor, FunctionTraversalContext::GlobalFunction); } visitor.exit_global_func_decl(self); } @@ -203,12 +207,14 @@ impl<'script> TryFrom> for MemberFunctionDeclarationNode<'scrip } impl DeclarationTraversal for MemberFunctionDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_member_func_decl(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_member_func_decl(self, ctx); if tp.traverse_params { - self.params().accept(visitor); + self.params().accept(visitor, FunctionTraversalContext::MemberFunction); } - visitor.exit_member_func_decl(self); + visitor.exit_member_func_decl(self, ctx); } } @@ -264,9 +270,17 @@ impl<'script> TryFrom> for FunctionDefinitionNode<'script> { } impl StatementTraversal for FunctionDefinitionNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = FunctionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { if let FunctionDefinition::Some(block) = self.clone().value() { - block.accept(visitor); + let block_ctx = match ctx { + FunctionTraversalContext::GlobalFunction => FunctionBlockTraversalContext::GlobalFunctionDefinition, + FunctionTraversalContext::MemberFunction => FunctionBlockTraversalContext::MemberFunctionDefinition, + FunctionTraversalContext::Event => FunctionBlockTraversalContext::EventDefinition, + }; + + block.accept(visitor, block_ctx); } } } @@ -307,8 +321,10 @@ impl<'script> TryFrom> for FunctionParametersNode<'script> { } impl DeclarationTraversal for FunctionParametersNode<'_> { - fn accept(&self, visitor: &mut V) { - self.iter().for_each(|s| s.accept(visitor)); + type TraversalCtx = FunctionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + self.iter().for_each(|s| s.accept(visitor, ctx)); } } @@ -357,8 +373,10 @@ impl<'script> TryFrom> for FunctionParameterGroupNode<'script> } impl DeclarationTraversal for FunctionParameterGroupNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_func_param_group(self); + type TraversalCtx = FunctionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_func_param_group(self, ctx); } } @@ -458,21 +476,23 @@ impl<'script> TryFrom> for FunctionStatementNode<'script> { } impl StatementTraversal for FunctionStatementNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { match self.clone().value() { - FunctionStatement::Var(s) => s.accept(visitor), - FunctionStatement::Expr(s) => s.accept(visitor), - FunctionStatement::For(s) => s.accept(visitor), - FunctionStatement::While(s) => s.accept(visitor), - FunctionStatement::DoWhile(s) => s.accept(visitor), - FunctionStatement::If(s) => s.accept(visitor), - FunctionStatement::Switch(s) => s.accept(visitor), - FunctionStatement::Break(s) => s.accept(visitor), - FunctionStatement::Continue(s) => s.accept(visitor), - FunctionStatement::Return(s) => s.accept(visitor), - FunctionStatement::Delete(s) => s.accept(visitor), - FunctionStatement::Block(s) => s.accept(visitor), - FunctionStatement::Nop(s) => s.accept(visitor), + FunctionStatement::Var(s) => s.accept(visitor, ctx), + FunctionStatement::Expr(s) => s.accept(visitor, ctx), + FunctionStatement::For(s) => s.accept(visitor, ctx), + FunctionStatement::While(s) => s.accept(visitor, ctx), + FunctionStatement::DoWhile(s) => s.accept(visitor, ctx), + FunctionStatement::If(s) => s.accept(visitor, ctx), + FunctionStatement::Switch(s) => s.accept(visitor, ctx), + FunctionStatement::Break(s) => s.accept(visitor, ctx), + FunctionStatement::Continue(s) => s.accept(visitor, ctx), + FunctionStatement::Return(s) => s.accept(visitor, ctx), + FunctionStatement::Delete(s) => s.accept(visitor, ctx), + FunctionStatement::Block(s) => s.accept(visitor, FunctionBlockTraversalContext::Statement(ctx)), + FunctionStatement::Nop(s) => s.accept(visitor, ctx), } } } @@ -512,9 +532,19 @@ impl<'script> TryFrom> for FunctionBlockNode<'script> { } impl StatementTraversal for FunctionBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_block_stmt(self); - self.iter().for_each(|s| s.accept(visitor)); + type TraversalCtx = FunctionBlockTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_block_stmt(self, ctx); + if tp.traverse { + let iter_ctx = match ctx { + //TODO make seperate CompoundStatement type with the same NODE_KIND to disambiguate traversal with function definition + FunctionBlockTraversalContext::Statement(stmt_ctx) => stmt_ctx, + _ => StatementTraversalContext::InCallableDefinition + }; + + self.iter().for_each(|s| s.accept(visitor, iter_ctx)); + } } } @@ -547,8 +577,10 @@ impl<'script> TryFrom> for BreakStatementNode<'script> { } impl StatementTraversal for BreakStatementNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_break_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_break_stmt(self, ctx); } } @@ -581,8 +613,10 @@ impl<'script> TryFrom> for ContinueStatementNode<'script> { } impl StatementTraversal for ContinueStatementNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_continue_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_continue_stmt(self, ctx); } } @@ -621,8 +655,10 @@ impl<'script> TryFrom> for ReturnStatementNode<'script> { } impl StatementTraversal for ReturnStatementNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_return_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_return_stmt(self, ctx); } } @@ -661,7 +697,9 @@ impl<'script> TryFrom> for DeleteStatementNode<'script> { } impl StatementTraversal for DeleteStatementNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_delete_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_delete_stmt(self, ctx); } } \ No newline at end of file diff --git a/crates/core/src/ast/loops.rs b/crates/core/src/ast/loops.rs index e33db4f1..3ebccf70 100644 --- a/crates/core/src/ast/loops.rs +++ b/crates/core/src/ast/loops.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{StatementTraversal, StatementVisitor, ExpressionNode, FunctionStatementNode}; +use super::*; mod tags { @@ -58,10 +58,12 @@ impl<'script> TryFrom> for ForLoopNode<'script> { } impl StatementTraversal for ForLoopNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_for_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_for_stmt(self, ctx); if tp.traverse_body { - self.body().accept(visitor); + self.body().accept(visitor, StatementTraversalContext::ForLoopBody); } } } @@ -106,10 +108,12 @@ impl<'script> TryFrom> for WhileLoopNode<'script> { } impl StatementTraversal for WhileLoopNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_while_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_while_stmt(self, ctx); if tp.traverse_body { - self.body().accept(visitor); + self.body().accept(visitor, StatementTraversalContext::WhileLoopBody); } } } @@ -154,10 +158,12 @@ impl<'script> TryFrom> for DoWhileLoopNode<'script> { } impl StatementTraversal for DoWhileLoopNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_do_while_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_do_while_stmt(self, ctx); if tp.traverse_body { - self.body().accept(visitor); + self.body().accept(visitor, StatementTraversalContext::DoWhileLoopBody); } } } \ No newline at end of file diff --git a/crates/core/src/ast/nop.rs b/crates/core/src/ast/nop.rs index 53df8b2d..09363d12 100644 --- a/crates/core/src/ast/nop.rs +++ b/crates/core/src/ast/nop.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::StatementTraversal; +use super::*; mod tags { @@ -8,7 +8,7 @@ mod tags { pub struct Nop; } - +//TODO bring back full traversal in root and type declarations once there is only one visitor trait pub type NopNode<'script> = SyntaxNode<'script, tags::Nop>; impl NamedSyntaxNode for NopNode<'_> { @@ -36,7 +36,9 @@ impl<'script> TryFrom> for NopNode<'script> { } impl StatementTraversal for NopNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_nop_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_nop_stmt(self, ctx); } } \ No newline at end of file diff --git a/crates/core/src/ast/root.rs b/crates/core/src/ast/root.rs index 64693af0..b7654fe2 100644 --- a/crates/core/src/ast/root.rs +++ b/crates/core/src/ast/root.rs @@ -75,13 +75,15 @@ impl<'script> TryFrom> for RootStatementNode<'script> { } impl DeclarationTraversal for RootStatementNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { match self.clone().value() { - RootStatement::Function(s) => s.accept(visitor), - RootStatement::Class(s) => s.accept(visitor), - RootStatement::State(s) => s.accept(visitor), - RootStatement::Struct(s) => s.accept(visitor), - RootStatement::Enum(s) => s.accept(visitor), + RootStatement::Function(s) => s.accept(visitor, ()), + RootStatement::Class(s) => s.accept(visitor, ()), + RootStatement::State(s) => s.accept(visitor, ()), + RootStatement::Struct(s) => s.accept(visitor, ()), + RootStatement::Enum(s) => s.accept(visitor, ()), RootStatement::Nop(_) => {}, } } @@ -123,10 +125,12 @@ impl<'script> TryFrom> for RootNode<'script> { } impl DeclarationTraversal for RootNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_root(self); if tp.traverse { - self.iter().for_each(|s| s.accept(visitor)); + self.iter().for_each(|s| s.accept(visitor, ())); } } } \ No newline at end of file diff --git a/crates/core/src/ast/states.rs b/crates/core/src/ast/states.rs index d4a194cc..c30c194b 100644 --- a/crates/core/src/ast/states.rs +++ b/crates/core/src/ast/states.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{attribs::StateSpecifierNode, tokens::IdentifierNode, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{ClassBlockNode, DeclarationTraversal, DeclarationVisitor}; +use super::*; mod tags { @@ -61,10 +61,12 @@ impl<'script> TryFrom> for StateDeclarationNode<'script> { } impl DeclarationTraversal for StateDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_state_decl(self); if tp.traverse_definition { - self.definition().accept(visitor); + self.definition().accept(visitor, PropertyTraversalContext::StateDefinition); } visitor.exit_state_decl(self); } diff --git a/crates/core/src/ast/structs.rs b/crates/core/src/ast/structs.rs index cd3f3548..db5a21c7 100644 --- a/crates/core/src/ast/structs.rs +++ b/crates/core/src/ast/structs.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use crate::{attribs::StructSpecifierNode, tokens::{IdentifierNode, LiteralStringNode}, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{DeclarationTraversal, DeclarationVisitor, ExpressionNode, MemberVarDeclarationNode, NopNode}; +use crate::{attribs::*, tokens::*, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; +use super::*; mod tags { @@ -56,10 +56,12 @@ impl<'script> TryFrom> for StructDeclarationNode<'script> { } impl DeclarationTraversal for StructDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { let tp = visitor.visit_struct_decl(self); if tp.traverse_definition { - self.definition().accept(visitor); + self.definition().accept(visitor, ()); } visitor.exit_struct_decl(self); } @@ -101,8 +103,10 @@ impl<'script> TryFrom> for StructBlockNode<'script> { } impl DeclarationTraversal for StructBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - self.iter().for_each(|s| s.accept(visitor)); + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { + self.iter().for_each(|s| s.accept(visitor, ())); } } @@ -170,12 +174,15 @@ impl<'script> TryFrom> for StructStatementNode<'script> { } impl DeclarationTraversal for StructStatementNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { + let ctx = PropertyTraversalContext::StructDefinition; match self.clone().value() { - StructStatement::Var(s) => s.accept(visitor), - StructStatement::Default(s) => s.accept(visitor), - StructStatement::DefaultsBlock(s) => s.accept(visitor), - StructStatement::Hint(s) => s.accept(visitor), + StructStatement::Var(s) => s.accept(visitor, ctx), + StructStatement::Default(s) => s.accept(visitor, ctx), + StructStatement::DefaultsBlock(s) => s.accept(visitor, ctx), + StructStatement::Hint(s) => s.accept(visitor, ctx), StructStatement::Nop(_) => {}, } } @@ -217,12 +224,14 @@ impl<'script> TryFrom> for MemberDefaultsBlockNode<'script> { } impl DeclarationTraversal for MemberDefaultsBlockNode<'_> { - fn accept(&self, visitor: &mut V) { - let tp = visitor.visit_member_defaults_block(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + let tp = visitor.visit_member_defaults_block(self, ctx); if tp.traverse { - self.iter().for_each(|n| n.accept(visitor)) + self.iter().for_each(|n| n.accept(visitor, ())); } - visitor.exit_member_defaults_block(self); + visitor.exit_member_defaults_block(self, ctx); } } @@ -266,7 +275,9 @@ impl<'script> TryFrom> for MemberDefaultsBlockAssignmentNode<'s } impl DeclarationTraversal for MemberDefaultsBlockAssignmentNode<'_> { - fn accept(&self, visitor: &mut V) { + type TraversalCtx = (); + + fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) { visitor.visit_member_defaults_block_assignment(self); } } @@ -311,8 +322,10 @@ impl<'script> TryFrom> for MemberDefaultValueNode<'script> { } impl DeclarationTraversal for MemberDefaultValueNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_member_default_val(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_member_default_val(self, ctx); } } @@ -356,7 +369,9 @@ impl<'script> TryFrom> for MemberHintNode<'script> { } impl DeclarationTraversal for MemberHintNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_member_hint(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_member_hint(self, ctx); } } diff --git a/crates/core/src/ast/traversal/contexts.rs b/crates/core/src/ast/traversal/contexts.rs new file mode 100644 index 00000000..a5105df0 --- /dev/null +++ b/crates/core/src/ast/traversal/contexts.rs @@ -0,0 +1,72 @@ +//! Types that allow for disambiguation during node traversal +//! e.g. if a member var declaration is visited it is supplied with a context whether it is visited inside +//! a class, a state or a struct. + + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExpressionTraversalContext { + MemberDefaultValue, + ExpressionStatement, + ReturnStatement, + DeleteStatement, + ForLoopInit, + ForLoopCond, + ForLoopIter, + WhileLoopCond, + DoWhileLoopCond, + IfConditionalCond, + SwitchConditionalCond, + SwitchConditionalCaseLabel, + + NestedExpressionInner, + FunctionCallExpressionFunc, + FunctionCallArg, + ArrayExpressionAccessor, + ArrayExpressionIndex, + MemberFieldExpressionAccessor, + NewExpressionLifetimeObj, + TypeCastExpressionValue, + UnaryOperationExpressionRight, + BinaryOperationExpressionLeft, + BinaryOperationExpressionRight, + AssignmentOperationExpressionLeft, + AssignmentOperationExpressionRight, + TernaryConditionalExpressionCond, + TernaryConditionalExpressionConseq, + TernaryConditionalExpressionAlt, +} + + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PropertyTraversalContext { + ClassDefinition, + StateDefinition, + StructDefinition +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FunctionTraversalContext { + GlobalFunction, + MemberFunction, + Event +} + + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum StatementTraversalContext { + InCallableDefinition, + IfConditionalBody, + IfConditionalElseBody, + SwitchConditionalBody, + ForLoopBody, + WhileLoopBody, + DoWhileLoopBody +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FunctionBlockTraversalContext { + GlobalFunctionDefinition, + MemberFunctionDefinition, + EventDefinition, + Statement(StatementTraversalContext) +} \ No newline at end of file diff --git a/crates/core/src/ast/traversal/mod.rs b/crates/core/src/ast/traversal/mod.rs index 00aab81c..977864c4 100644 --- a/crates/core/src/ast/traversal/mod.rs +++ b/crates/core/src/ast/traversal/mod.rs @@ -1,21 +1,29 @@ mod policies; mod visitor; +mod contexts; pub use policies::*; pub use visitor::*; +pub use contexts::*; /// Traverse an expression node using left-recursion. pub trait ExpressionTraversal { - fn accept(&self, visitor: &mut V); + type TraversalCtx; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx); } /// Traverse a statement node using left-recursion. pub trait DeclarationTraversal { - fn accept(&self, visitor: &mut V); + type TraversalCtx; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx); } /// Traverse a statement node using left-recursion. pub trait StatementTraversal { - fn accept(&self, visitor: &mut V); + type TraversalCtx; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx); } diff --git a/crates/core/src/ast/traversal/visitor.rs b/crates/core/src/ast/traversal/visitor.rs index 4d6f94b7..0d77388d 100644 --- a/crates/core/src/ast/traversal/visitor.rs +++ b/crates/core/src/ast/traversal/visitor.rs @@ -1,6 +1,7 @@ use crate::tokens::*; use crate::ast::*; use super::policies::*; +use super::contexts::*; /// Handle visitations to expression nodes. @@ -10,35 +11,34 @@ use super::policies::*; pub trait ExpressionVisitor { /// Called when visiting a parenthesized expression node. /// Should return whether to traverse into the expression [nested][NestedExpressionNode::inner] inside it. True by default. - fn visit_nested_expr(&mut self, n: &NestedExpressionNode) -> NestedExpressionTraversalPolicy { Default::default() } - + fn visit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy { Default::default() } /// Called after visiting the nested expression node and possibly its [inner][NestedExpressionNode::inner] node. - fn exit_nested_expr(&mut self, n: &NestedExpressionNode) {} + fn exit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing any literal. - fn visit_literal_expr(&mut self, n: &LiteralNode) {} + fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing a `this` expression. - fn visit_this_expr(&mut self, n: &ThisExpressionNode) {} + fn visit_this_expr(&mut self, n: &ThisExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing a `super` expression. - fn visit_super_expr(&mut self, n: &SuperExpressionNode) {} + fn visit_super_expr(&mut self, n: &SuperExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing a `parent` expression. - fn visit_parent_expr(&mut self, n: &ParentExpressionNode) {} + fn visit_parent_expr(&mut self, n: &ParentExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing a `virtual_parent` expression. - fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode) {} + fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a node representing an identifier in code (not a keyword). - fn visit_identifier_expr(&mut self, n: &IdentifierNode) {} + fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a function call node. /// Should return whether to traverse into this node's callee [func][FunctionCallExpressionNode::func] node /// and [args][FunctionCallExpressionNode::args]. Both true by default. - fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode) -> FunctionCallExpressionTraversalPolicy { Default::default() } + fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy { Default::default() } /// Called after visiting function call expression node and possibly its [func][FunctionCallExpressionNode::func] and [args][FunctionCallExpressionNode::args] nodes. - fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode) {} + fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a function call argument. /// Node may be None due to it referring to an optional function parameter. @@ -50,67 +50,67 @@ pub trait ExpressionVisitor { /// Called when visiting an indexing expression. /// Should return whether to traverse into this node's [accessor][ArrayExpressionNode::accessor] /// and [index][ArrayExpressionNode::index] expressions. Both true by default. - fn visit_array_expr(&mut self, n: &ArrayExpressionNode) -> ArrayExpressionTraversalPolicy { Default::default() } + fn visit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy { Default::default() } /// Called after visiting an indexing expression and possibly its [accessor][ArrayExpressionNode::accessor] /// and [index][ArrayExpressionNode::index] expressions. - fn exit_array_expr(&mut self, n: &ArrayExpressionNode) {} + fn exit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting an expression of accessing a field in an object. /// Should return whether to traverse into this node's [accessor][MemberFieldExpressionNode::accessor] node. True by default. /// The [member][MemberFieldExpressionNode::member] identifier node is not visited automatically. - fn visit_member_field_expr(&mut self, n: &MemberFieldExpressionNode) -> MemberFieldExpressionTraversalPolicy { Default::default() } + fn visit_member_field_expr(&mut self, n: &MemberFieldExpressionNode, ctx: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy { Default::default() } /// Called after visiting an expression of accessing a field in an object and possibly its /// [accessor][MemberFieldExpressionNode::accessor] and [member][MemberFieldExpressionNode::member] nodes. - fn exit_member_field_expr(&mut self, n: &MemberFieldExpressionNode) {} + fn exit_member_field_expr(&mut self, n: &MemberFieldExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting an instantiation expression. /// Should return whether to traverse into this node's [lifetime_obj][NewExpressionNode::lifetime_obj] node if there is any. True by default. /// The [class][NewExpressionNode::class] identifier is not visited automatically. - fn visit_new_expr(&mut self, n: &NewExpressionNode) -> NewExpressionTraversalPolicy { Default::default() } + fn visit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) -> NewExpressionTraversalPolicy { Default::default() } /// Called after visiting an instantiation expression and possibly its [lifetime_obj][NewExpressionNode::lifetime_obj] node. - fn exit_new_expr(&mut self, n: &NewExpressionNode) {} + fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a type-casting expression. /// Should return whether to traverse into this node's [value][NewExpressionNode::class] node. True by default. /// The [target_type][NewExpressionNode::target_type] identifier is not visited automatically. - fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode) -> TypeCastExpressionTraversalPolicy { Default::default() } + fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy { Default::default() } /// Called after visiting a type-casting expression and possibly also its [value][NewExpressionNode::class] node. - fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode) {} + fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting an unary operation expression. /// Should return whether to traverse into this node's [right][UnaryOperationExpressionNode::right] node. True by default. /// The [operator][UnaryOperationExpressionNode::op] node is not visited automatically. - fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode) -> UnaryOperationExpressionTraversalPolicy { Default::default() } + fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy { Default::default() } /// Called after visiting an unary operation expression and possibly also its [right][UnaryOperationExpressionNode::right] node. - fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode) {} + fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a binary operation expression. /// Should return whether to traverse into to this node's [left][BinaryOperationExpressionNode::left] /// and [right][BinaryOperationExpressionNode::right] nodes. Both true by default. /// The [operator][BinaryOperationExpressionNode::op] node is not visited automatically. - fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode) -> BinaryOperationExpressionTraversalPolicy { Default::default() } + fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy { Default::default() } /// Called after visiting a binary operation expression and possibly also its [left][BinaryOperationExpressionNode::left] /// and [right][BinaryOperationExpressionNode::right] nodes. - fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode) {} + fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting an assignment operation expression. /// Should return whether to traverse into this node's [left][AssignmentOperationExpressionNode::left] /// and [right][AssignmentOperationExpressionNode::right] nodes. Both true by default. /// The [operator][AssignmentOperationExpressionNode::op] node is not visited automatically. - fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode) -> AssignmentOperationExpressionTraversalPolicy { Default::default() } + fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy { Default::default() } /// Called after visiting an assignment operation expression and possibly also /// its [left][AssignmentOperationExpressionNode::left] and [right][AssignmentOperationExpressionNode::right] nodes. - fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode) {} + fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) {} /// Called when visiting a ternary conditional expression (expr1 ? expr2 : expr3). /// Should return whether to traverse into this node's [cond][TernaryConditionalExpressionNode::cond], /// [conseq][TernaryConditionalExpressionNode::conseq] and [alt][TernaryConditionalExpressionNode::alt] nodes. /// All true by default. - fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode) -> TernaryConditionalExpressionTraversalPolicy { Default::default() } + fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy { Default::default() } /// Called after visiting a ternary conditional expression and possiblt also its /// [cond][TernaryConditionalExpressionNode::cond], [conseq][TernaryConditionalExpressionNode::conseq] /// and [alt][TernaryConditionalExpressionNode::alt] nodes. - fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode) {} + fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) {} } @@ -151,28 +151,28 @@ pub trait DeclarationVisitor { fn visit_enum_variant_decl(&mut self, n: &EnumVariantDeclarationNode) {} /// Called when visiting member variable (i.e. field) declaration. - fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode) {} + fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: PropertyTraversalContext) {} /// Called when visiting a statement assigning a default value to a field. - fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode) {} + fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: PropertyTraversalContext) {} /// Called when visiting a `defaults` block. /// Should return whether to traverse into its [assignment][MemberDefaultsBlockNode::iter] nodes. - fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode) -> MemberDefaultsBlockTraversalPolicy { Default::default() } + fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: PropertyTraversalContext) -> MemberDefaultsBlockTraversalPolicy { Default::default() } /// Called after visitng a `defaults` block and possibly also its assignment nodes. - fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode) {} + fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: PropertyTraversalContext) {} /// Called when visiting a default value assignment inside a `defaults` block. fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) {} /// Called when visiting a statement noting some information about a perticular type field. - fn visit_member_hint(&mut self, n: &MemberHintNode) {} + fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: PropertyTraversalContext) {} /// Called when visiting an autobind variable declaration. - fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode) {} + fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, ctx: PropertyTraversalContext) {} /// Called when visiting a group of function parameters. This may mean a single parameter or multiple delimited names with common specifiers and a type. - fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode) {} + fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, ctx: FunctionTraversalContext) {} /// Called when visiting a global function declaration. /// Should return whether to traverse into [parameters][GlobalFunctionDeclarationNode::params] of the function. True by default. @@ -182,15 +182,15 @@ pub trait DeclarationVisitor { /// Called when visiting a member function declaration (i.e. a method). /// Should return whether to traverse into [parameters][MemberFunctionDeclarationNode::params] of the function. True by default. - fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) -> MemberFunctionDeclarationTraversalPolicy { Default::default() } + fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode, ctx: PropertyTraversalContext) -> MemberFunctionDeclarationTraversalPolicy { Default::default() } /// Called after visiting member function declaration and possibly also its [parameters][MemberFunctionDeclarationNode::params]. - fn exit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) {} + fn exit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode, ctx: PropertyTraversalContext) {} /// Called when visiting an event function declaration. /// Should return whether to traverse into [parameters][EventDeclarationNode::params] of the function. True by default. - fn visit_event_decl(&mut self, n: &EventDeclarationNode) -> EventDeclarationTraversalPolicy { Default::default() } + fn visit_event_decl(&mut self, n: &EventDeclarationNode, ctx: PropertyTraversalContext) -> EventDeclarationTraversalPolicy { Default::default() } /// Called after visiting member function declaration and possibly also its [parameters][EventDeclarationNode::params]. - fn exit_event_decl(&mut self, n: &EventDeclarationNode) {} + fn exit_event_decl(&mut self, n: &EventDeclarationNode, ctx: PropertyTraversalContext) {} } @@ -201,30 +201,31 @@ pub trait DeclarationVisitor { #[allow(unused_variables)] pub trait StatementVisitor { /// Called when visiting a local variable declaration inside a function. - fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode) {} + fn visit_local_var_decl_stmt(&mut self, n: &VarDeclarationNode, ctx: StatementTraversalContext) {} /// Called when visiting an expression statement inside a function. - fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode) {} + fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: StatementTraversalContext) {} + //TODO! add missing exit_ functions /// Called when visiting a `for` loop. /// Should return whether to traverse into the [body][ForLoopNode::body] of the loop. True by default. - fn visit_for_stmt(&mut self, n: &ForLoopNode) -> ForLoopTraversalPolicy { Default::default() } + fn visit_for_stmt(&mut self, n: &ForLoopNode, ctx: StatementTraversalContext) -> ForLoopTraversalPolicy { Default::default() } /// Called when visiting a `while` loop. /// Should return whether to traverse into the [body][WhileLoopNode::body] of the loop. True by default. - fn visit_while_stmt(&mut self, n: &WhileLoopNode) -> WhileLoopTraversalPolicy { Default::default() } + fn visit_while_stmt(&mut self, n: &WhileLoopNode, ctx: StatementTraversalContext) -> WhileLoopTraversalPolicy { Default::default() } /// Called when visiting a `do-while` loop. /// Should return whether to traverse into the [body][DoWhileLoopNode::body] of the loop. True by default. - fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode) -> DoWhileLoopTraversalPolicy { Default::default() } + fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: StatementTraversalContext) -> DoWhileLoopTraversalPolicy { Default::default() } /// Called when visiting an `if` condition. /// Should return whether to traverse into the [body][IfConditionalNode::body] of the statement. True by default. - fn visit_if_stmt(&mut self, n: &IfConditionalNode) -> IfConditionalTraversalPolicy { Default::default() } + fn visit_if_stmt(&mut self, n: &IfConditionalNode, ctx: StatementTraversalContext) -> IfConditionalTraversalPolicy { Default::default() } /// Called when visiting a `switch` statement. /// Should return whether to traverse into [body][SwitchConditionalNode::body] of the statement. True by default. - fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode) -> SwitchConditionalTraversalPolicy { Default::default() } + fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: StatementTraversalContext) -> SwitchConditionalTraversalPolicy { Default::default() } /// Called when visiting a `case` label inside a `switch` statement. fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) {} @@ -233,24 +234,24 @@ pub trait StatementVisitor { fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {} /// Called when visiting a `break` statement. - fn visit_break_stmt(&mut self, n: &BreakStatementNode) {} + fn visit_break_stmt(&mut self, n: &BreakStatementNode, ctx: StatementTraversalContext) {} /// Called when visiting a `continue` statement. - fn visit_continue_stmt(&mut self, n: &ContinueStatementNode) {} + fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, ctx: StatementTraversalContext) {} /// Called when visiting a `return` statement. - fn visit_return_stmt(&mut self, n: &ReturnStatementNode) {} + fn visit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: StatementTraversalContext) {} /// Called when visiting a `delete` statement. - fn visit_delete_stmt(&mut self, n: &DeleteStatementNode) {} + fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: StatementTraversalContext) {} /// Called when visiting a function block. This may mean a function definition or a scope inside that function. /// Should return whether to traverse into [statements][FunctionBlockNode::iter] of the block. True by default. - fn visit_block_stmt(&mut self, n: &FunctionBlockNode) -> FunctionBlockTraversalPolicy { Default::default() } + fn visit_block_stmt(&mut self, n: &FunctionBlockNode, ctx: FunctionBlockTraversalContext) -> FunctionBlockTraversalPolicy { Default::default() } /// Called when visiting a NOP statement. /// It most notably means: /// 1. A trailing "orphan" semicolon somewhere in code /// 2. Indicating absence of action, e.g. `while(!AreWeThereYet());` - fn visit_nop_stmt(&mut self, n: &NopNode) {} + fn visit_nop_stmt(&mut self, n: &NopNode, ctx: StatementTraversalContext) {} } diff --git a/crates/core/src/ast/vars.rs b/crates/core/src/ast/vars.rs index 8d1521a7..bb613886 100644 --- a/crates/core/src/ast/vars.rs +++ b/crates/core/src/ast/vars.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; use crate::{attribs::MemberVarSpecifierNode, tokens::IdentifierNode, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; -use super::{DeclarationTraversal, DeclarationVisitor, ExpressionNode, StatementTraversal, StatementVisitor}; +use super::*; mod tags { @@ -92,8 +92,10 @@ impl<'script> TryFrom> for VarDeclarationNode<'script> { } impl StatementTraversal for VarDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_local_var_decl_stmt(self); + type TraversalCtx = StatementTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_local_var_decl_stmt(self, ctx); } } @@ -142,7 +144,9 @@ impl<'script> TryFrom> for MemberVarDeclarationNode<'script> { } impl DeclarationTraversal for MemberVarDeclarationNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_member_var_decl(self); + type TraversalCtx = PropertyTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_member_var_decl(self, ctx); } } \ No newline at end of file diff --git a/crates/core/src/script.rs b/crates/core/src/script.rs index ae28d7dc..571187dd 100644 --- a/crates/core/src/script.rs +++ b/crates/core/src/script.rs @@ -2,7 +2,7 @@ use std::io; use ropey::Rope; use thiserror::Error; use tree_sitter::{Parser, Tree, LanguageError}; -use crate::{ast::RootNode, script_document::ScriptDocument}; +use crate::{ast::{DeclarationTraversal, DeclarationVisitor, RootNode}, script_document::ScriptDocument}; #[derive(Debug, Clone)] @@ -74,7 +74,12 @@ impl Script { } + #[inline(always)] pub fn root_node(&self) -> RootNode { RootNode::new(self.current_tree.root_node()) } + + pub fn visit_nodes(&self, visitor: &mut V) { + self.root_node().accept(visitor, ()); + } } \ No newline at end of file diff --git a/crates/core/src/tokens/identifier.rs b/crates/core/src/tokens/identifier.rs index 48072eb3..6afa028d 100644 --- a/crates/core/src/tokens/identifier.rs +++ b/crates/core/src/tokens/identifier.rs @@ -1,6 +1,7 @@ use std::fmt::Debug; use shrinkwraprs::Shrinkwrap; -use crate::{ast::{ExpressionTraversal, ExpressionVisitor}, script_document::ScriptDocument, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::{script_document::ScriptDocument, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::ast::{ExpressionTraversal, ExpressionTraversalContext, ExpressionVisitor}; #[derive(Shrinkwrap, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -32,8 +33,10 @@ impl Debug for IdentifierNode<'_> { } impl ExpressionTraversal for IdentifierNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_identifier_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_identifier_expr(self, ctx); } } diff --git a/crates/core/src/tokens/literals.rs b/crates/core/src/tokens/literals.rs index 6418bc7c..b6a4080d 100644 --- a/crates/core/src/tokens/literals.rs +++ b/crates/core/src/tokens/literals.rs @@ -3,9 +3,8 @@ use std::fmt::Debug; use std::str::ParseBoolError; use shrinkwraprs::Shrinkwrap; use thiserror::Error; -use crate::{DebugMaybeAlternate, DebugRange}; -use crate::script_document::ScriptDocument; -use crate::{AnyNode, NamedSyntaxNode, SyntaxNode, ast::{ExpressionTraversal, ExpressionVisitor}}; +use crate::{AnyNode, NamedSyntaxNode, SyntaxNode, DebugMaybeAlternate, DebugRange, script_document::ScriptDocument}; +use crate::ast::{ExpressionTraversal, ExpressionVisitor, ExpressionTraversalContext}; #[derive(Debug, Clone, Error)] @@ -356,7 +355,9 @@ impl<'script> TryFrom> for LiteralNode<'script> { } impl ExpressionTraversal for LiteralNode<'_> { - fn accept(&self, visitor: &mut V) { - visitor.visit_literal_expr(self); + type TraversalCtx = ExpressionTraversalContext; + + fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) { + visitor.visit_literal_expr(self, ctx); } } \ No newline at end of file