diff --git a/crates/analysis/src/jobs/scan_symbols.rs b/crates/analysis/src/jobs/scan_symbols.rs index 7e8c68b..4a4403d 100644 --- a/crates/analysis/src/jobs/scan_symbols.rs +++ b/crates/analysis/src/jobs/scan_symbols.rs @@ -280,6 +280,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { ClassDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: false, traverse_errors: false } } @@ -339,6 +340,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { StateDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: false, traverse_errors: false } } @@ -389,6 +391,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { StructDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: false, traverse_errors: false } } @@ -423,6 +426,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { EnumDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: false, traverse_errors: false } } @@ -547,6 +551,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { traverse_params: traverse, traverse_return_type: false, traverse_definition: traverse, + traverse_unnamed: false, traverse_errors: false } } @@ -628,6 +633,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { traverse_params: traverse, traverse_return_type: false, traverse_definition: traverse, + traverse_unnamed: false, traverse_errors: false } } @@ -664,6 +670,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { traverse_params: traverse, traverse_return_type: false, traverse_definition: traverse, + traverse_unnamed: false, traverse_errors: false } } @@ -802,6 +809,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { VarDeclarationTraversalPolicy { traverse_type: false, traverse_init_value: false, + traverse_unnamed: false, traverse_errors: false } } @@ -817,6 +825,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { WhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -825,6 +834,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { DoWhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -835,6 +845,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { traverse_cond: false, traverse_iter: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -844,6 +855,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { traverse_cond: false, traverse_body: true, traverse_else_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -852,6 +864,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> { SwitchConditionalTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } diff --git a/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs b/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs index fea70a6..61ddeb2 100644 --- a/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs +++ b/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs @@ -457,6 +457,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { VarDeclarationTraversalPolicy { traverse_init_value: false, traverse_type: false, + traverse_unnamed: false, traverse_errors: false } } @@ -466,6 +467,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { ExpressionStatementTraversalPolicy { traverse_expr: false, + traverse_unnamed: false, traverse_errors: false } } @@ -477,6 +479,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { traverse_cond: false, traverse_body: true, traverse_else_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -487,6 +490,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { SwitchConditionalTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -499,6 +503,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { traverse_cond: false, traverse_iter: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -509,6 +514,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { WhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -519,6 +525,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { DoWhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true, + traverse_unnamed: false, traverse_errors: false } } @@ -528,6 +535,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { DeleteStatementTraversalPolicy { traverse_value: false, + traverse_unnamed: false, traverse_errors: false } } @@ -546,6 +554,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> { ReturnStatementTraversalPolicy { traverse_value: false, + traverse_unnamed: false, traverse_errors: false } } 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 4821417..004fcfa 100644 --- a/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs +++ b/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs @@ -119,6 +119,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { ClassDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -142,6 +143,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { StateDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -159,6 +161,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { StructDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -176,6 +179,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { EnumDeclarationTraversalPolicy { traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -195,6 +199,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { } EnumVariantDeclarationTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -212,6 +217,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { TypeAnnotationTraversalPolicy { traverse_type_arg: any_error, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -229,8 +235,9 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { MemberVarDeclarationTraversalPolicy { traverse_annotation: any_error, + traverse_type: any_error, + traverse_unnamed: any_error, traverse_errors: any_error, - traverse_type: any_error } } @@ -247,8 +254,9 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { MemberVarDeclarationTraversalPolicy { traverse_annotation: any_error, + traverse_type: any_error, + traverse_unnamed: any_error, traverse_errors: any_error, - traverse_type: any_error } } @@ -265,6 +273,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { MemberDefaultValueTraversalPolicy { traverse_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -280,6 +289,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { } MemberHintTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -296,6 +306,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { AutobindDeclarationTraversalPolicy { traverse_type: any_error, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -313,6 +324,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { FunctionParameterGroupTraversalPolicy { traverse_type: any_error, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -335,6 +347,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_return_type: any_error, traverse_params, traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -357,6 +370,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_return_type: any_error, traverse_params, traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -378,6 +392,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_return_type: any_error, traverse_params, traverse_definition, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -387,6 +402,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { MemberDefaultsBlockTraversalPolicy { traverse_assignments: any_error, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -404,6 +420,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { MemberDefaultValueTraversalPolicy { traverse_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -437,6 +454,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { VarDeclarationTraversalPolicy { traverse_type: any_error, traverse_init_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -452,6 +470,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { ExpressionStatementTraversalPolicy { traverse_expr, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -467,6 +486,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { ReturnStatementTraversalPolicy { traverse_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -475,6 +495,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { let any_error = n.has_errors(); BreakStatementTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -483,6 +504,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { let any_error = n.has_errors(); ContinueStatementTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -498,6 +520,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { DeleteStatementTraversalPolicy { traverse_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -522,6 +545,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_cond, traverse_iter, traverse_body, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -540,6 +564,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { WhileLoopTraversalPolicy { traverse_cond, traverse_body, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -558,6 +583,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { DoWhileLoopTraversalPolicy { traverse_cond, traverse_body, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -579,6 +605,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_cond, traverse_body, traverse_else_body, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -597,6 +624,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { SwitchConditionalTraversalPolicy { traverse_cond, traverse_body, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -612,6 +640,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { SwitchConditionalCaseLabelTraversalPolicy { traverse_value, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -620,6 +649,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { let any_error = n.has_errors(); SwitchConditionalDefaultLabelTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -641,6 +671,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { ArrayExpressionTraversalPolicy { traverse_accessor, traverse_index, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -711,6 +742,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { FunctionCallExpressionTraversalPolicy { traverse_func, traverse_args, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -760,6 +792,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { NestedExpressionTraversalPolicy { traverse_inner, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -781,6 +814,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { traverse_cond, traverse_conseq, traverse_alt, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -813,6 +847,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { ArrayInitializerExpressionTraversalPolicy { traverse_items: any_error, + traverse_unnamed: any_error, traverse_errors: any_error } } @@ -822,7 +857,22 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> { let any_error = n.has_errors(); AnnotationTraversalPolicy { + traverse_unnamed: any_error, traverse_errors: any_error } } + + + fn visit_unnamed(&mut self, n: &UnnamedNode, _: &TraversalContextStack) { + if n.is_missing() { + match n.value() { + Unnamed::Keyword(kw) => { + self.missing_element(n.range(), format!("keyword {}", kw.as_ref())); + }, + Unnamed::Punctuation(punct) => { + self.missing_element(n.range(), punct.to_string()); + }, + } + } + } } \ No newline at end of file diff --git a/crates/core/src/ast/annotation.rs b/crates/core/src/ast/annotation.rs index 50aa891..a1a68d2 100644 --- a/crates/core/src/ast/annotation.rs +++ b/crates/core/src/ast/annotation.rs @@ -86,8 +86,12 @@ impl SyntaxNodeTraversal for AnnotationNode<'_> { if tp.any() { ctx.push(TraversalContext::Annotation); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/classes.rs b/crates/core/src/ast/classes.rs index b8f4ec6..efe54a5 100644 --- a/crates/core/src/ast/classes.rs +++ b/crates/core/src/ast/classes.rs @@ -63,13 +63,16 @@ impl SyntaxNodeTraversal for ClassDeclarationNode<'_> { if tp.any() { ctx.push(TraversalContext::Class); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((definition, Some("definition"))) if tp.traverse_definition => { let definition: ClassBlockNode = definition.unsafe_into(); - definition.accept_with_policy(visitor, ctx, tp.clone()); - } + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx) }, @@ -99,13 +102,16 @@ impl<'script> ClassBlockNode<'script> { fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: ClassDeclarationTraversalPolicy) { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((prop, _)) => { + Ok((prop, _)) if prop.is_named() => { let prop: ClassPropertyNode = prop.unsafe_into(); - prop.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/conditionals.rs b/crates/core/src/ast/conditionals.rs index 76216de..f107d8b 100644 --- a/crates/core/src/ast/conditionals.rs +++ b/crates/core/src/ast/conditionals.rs @@ -1,5 +1,5 @@ use std::fmt::Debug; -use crate::{AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::{tokens::UnnamedNode, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -59,7 +59,7 @@ impl SyntaxNodeTraversal for IfConditionalNode<'_> { let tp = visitor.visit_if_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((cond, Some("cond"))) if tp.traverse_cond => { let cond: ExpressionNode = cond.unsafe_into(); @@ -81,7 +81,11 @@ impl SyntaxNodeTraversal for IfConditionalNode<'_> { ctx.push(TraversalContext::IfConditionalElseBody); else_body.accept(visitor, ctx); ctx.pop(); - } + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx) }, @@ -138,22 +142,28 @@ impl SyntaxNodeTraversal for SwitchConditionalNode<'_> { let tp = visitor.visit_switch_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((cond, Some("cond"))) if tp.traverse_cond => { - let cond: ExpressionNode = cond.unsafe_into(); - ctx.push(TraversalContext::SwitchConditionalCond); + + let cond: ExpressionNode = cond.unsafe_into(); cond.accept(visitor, ctx); + ctx.pop(); }, Ok((body, Some("body"))) if tp.traverse_body => { - let body: SwitchConditionalBlockNode = body.unsafe_into(); - ctx.push(TraversalContext::SwitchConditionalBody); + + let body: SwitchConditionalBlockNode = body.unsafe_into(); body.accept_with_policy(visitor, ctx, tp.clone()); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -181,13 +191,16 @@ impl<'script> SwitchConditionalBlockNode<'script> { fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: SwitchConditionalTraversalPolicy) { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((section, _)) => { + Ok((section, _)) if section.is_named() => { let section: SwitchConditionalSectionNode = section.unsafe_into(); - section.accept(visitor, ctx) - } + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx) }, @@ -337,15 +350,20 @@ impl SyntaxNodeTraversal for SwitchConditionalCaseLabelNode<'_> { let tp = visitor.visit_switch_stmt_case(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((value, Some("value"))) if tp.traverse_value => { - let value: ExpressionNode = value.unsafe_into(); - ctx.push(TraversalContext::SwitchConditionalCaseLabel); + + let value: ExpressionNode = value.unsafe_into(); value.accept(visitor, ctx); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); } @@ -389,8 +407,12 @@ impl SyntaxNodeTraversal for SwitchConditionalDefaultLabelNode<'_> { let tp = visitor.visit_switch_stmt_default(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); } diff --git a/crates/core/src/ast/enums.rs b/crates/core/src/ast/enums.rs index 194148b..141a9de 100644 --- a/crates/core/src/ast/enums.rs +++ b/crates/core/src/ast/enums.rs @@ -1,5 +1,5 @@ use std::fmt::Debug; -use crate::{tokens::{IdentifierNode, LiteralHexNode, LiteralIntNode}, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::{tokens::*, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -52,15 +52,20 @@ impl SyntaxNodeTraversal for EnumDeclarationNode<'_> { let tp = visitor.visit_enum_decl(self); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((def, Some("definition"))) if tp.traverse_definition => { - let def: EnumBlockNode = def.unsafe_into(); - ctx.push(TraversalContext::Enum); + + let def: EnumBlockNode = def.unsafe_into(); def.accept_with_policy(visitor, ctx, tp.clone()); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -88,13 +93,16 @@ impl<'script> EnumBlockNode<'script> { fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: EnumDeclarationTraversalPolicy) { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((variant, _)) => { + Ok((variant, _)) if variant.is_named() => { let variant: EnumVariantDeclarationNode = variant.unsafe_into(); - variant.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -182,8 +190,12 @@ impl SyntaxNodeTraversal for EnumVariantDeclarationNode<'_> { let tp = visitor.visit_enum_variant_decl(self); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/expressions.rs b/crates/core/src/ast/expressions.rs index 741ae4a..ee79b3d 100644 --- a/crates/core/src/ast/expressions.rs +++ b/crates/core/src/ast/expressions.rs @@ -62,9 +62,9 @@ impl SyntaxNodeTraversal for NestedExpressionNode<'_> { let tp = visitor.visit_nested_expr(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((inner, _)) if tp.traverse_inner => { + Ok((inner, _)) if inner.is_named() && tp.traverse_inner => { ctx.push(TraversalContext::NestedExpressionInner); let inner: ExpressionNode = inner.unsafe_into(); @@ -72,6 +72,10 @@ impl SyntaxNodeTraversal for NestedExpressionNode<'_> { ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx) }, @@ -264,7 +268,7 @@ impl SyntaxNodeTraversal for FunctionCallExpressionNode<'_> { let tp = visitor.visit_func_call_expr(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((func, Some("func"))) if tp.traverse_func => { ctx.push(TraversalContext::FunctionCallExpressionFunc); @@ -279,6 +283,10 @@ impl SyntaxNodeTraversal for FunctionCallExpressionNode<'_> { args.accept_with_policy(visitor, ctx, tp.clone()); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -479,7 +487,7 @@ impl SyntaxNodeTraversal for ArrayExpressionNode<'_> { let tp = visitor.visit_array_expr(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((accessor, Some("accessor"))) if tp.traverse_accessor => { let accessor: ExpressionNode = accessor.unsafe_into(); @@ -495,6 +503,10 @@ impl SyntaxNodeTraversal for ArrayExpressionNode<'_> { index.accept(visitor, ctx); ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -971,7 +983,7 @@ impl SyntaxNodeTraversal for TernaryConditionalExpressionNode<'_> { let tp = visitor.visit_ternary_cond_expr(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((cond, Some("cond"))) if tp.traverse_cond => { let cond: ExpressionNode = cond.unsafe_into(); @@ -994,6 +1006,10 @@ impl SyntaxNodeTraversal for TernaryConditionalExpressionNode<'_> { alt.accept(visitor, ctx); ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -1048,13 +1064,16 @@ impl SyntaxNodeTraversal for ArrayInitializerExpressionNode<'_> { if tp.any() { ctx.push(TraversalContext::ArrayInitializerExpression); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((item, _)) if tp.traverse_items => { + Ok((item, _)) if item.is_named() && tp.traverse_items => { let item: ExpressionNode = item.unsafe_into(); - item.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -1358,15 +1377,20 @@ impl SyntaxNodeTraversal for ExpressionStatementNode<'_> { let tp = visitor.visit_expr_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((expr, _)) if tp.traverse_expr => { - let expr: ExpressionNode = expr.unsafe_into(); - + Ok((expr, _)) if expr.is_named() && tp.traverse_expr => { ctx.push(TraversalContext::ExpressionStatement); + + let expr: ExpressionNode = expr.unsafe_into(); expr.accept(visitor, ctx); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/functions.rs b/crates/core/src/ast/functions.rs index 6126435..aea2a30 100644 --- a/crates/core/src/ast/functions.rs +++ b/crates/core/src/ast/functions.rs @@ -1,5 +1,5 @@ use std::fmt::Debug; -use crate::{attribs::*, tokens::IdentifierNode, debug::*, AnyNode, NamedSyntaxNode, SyntaxNode}; +use crate::{attribs::*, tokens::*, debug::*, AnyNode, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -66,7 +66,7 @@ impl SyntaxNodeTraversal for EventDeclarationNode<'_> { if tp.any() { ctx.push(TraversalContext::Event); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((params, Some("params"))) if tp.traverse_params => { let params: FunctionParametersNode = params.unsafe_into(); @@ -81,7 +81,11 @@ impl SyntaxNodeTraversal for EventDeclarationNode<'_> { Ok((def, Some("definition"))) if tp.traverse_definition => { let def: FunctionDefinitionNode = def.unsafe_into(); - def.accept_with_policy(visitor, ctx, tp.traverse_errors); + def.accept_with_policy(visitor, ctx, tp.traverse_unnamed, tp.traverse_errors); + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); @@ -165,7 +169,7 @@ impl SyntaxNodeTraversal for FunctionDeclarationNode<'_> { fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) { // closure to not repeat code below let accept_proper = |self_: &Self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: FunctionDeclarationTraversalPolicy| { - for ch in self_.children_detailed().must_be_named(true) { + for ch in self_.children_detailed() { match ch { Ok((annot, Some("annotation"))) if tp.traverse_annotation => { let annot: AnnotationNode = annot.unsafe_into(); @@ -185,7 +189,11 @@ impl SyntaxNodeTraversal for FunctionDeclarationNode<'_> { Ok((def, Some("definition"))) if tp.traverse_definition => { let def: FunctionDefinitionNode = def.unsafe_into(); - def.accept_with_policy(visitor, ctx, tp.traverse_errors); + def.accept_with_policy(visitor, ctx, tp.traverse_unnamed, tp.traverse_errors); + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); @@ -253,9 +261,9 @@ impl<'script> FunctionDefinitionNode<'script> { } - fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_errors: bool) { + fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_unnamed: bool, traverse_errors: bool) { if let FunctionDefinition::Some(block) = self.clone().value() { - block.accept_with_policy(visitor, ctx, traverse_errors); + block.accept_with_policy(visitor, ctx, traverse_unnamed, traverse_errors); } } } @@ -305,14 +313,17 @@ impl<'script> FunctionBlockNode<'script> { } - fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_errors: bool) { - for ch in self.children_detailed().must_be_named(true) { + fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_unnamed: bool, traverse_errors: bool) { + for ch in self.children_detailed() { match ch { - Ok((stmt, _)) => { + Ok((stmt, _)) if stmt.is_named() => { let stmt: FunctionStatementNode = stmt.unsafe_into(); - stmt.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if traverse_errors => { e.accept(visitor, ctx); }, @@ -458,13 +469,16 @@ impl SyntaxNodeTraversal for FunctionParameterGroupNode<'_> { let tp = visitor.visit_func_param_group(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((typ, Some("param_type"))) if tp.traverse_type => { let typ: TypeAnnotationNode = typ.unsafe_into(); - typ.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/loops.rs b/crates/core/src/ast/loops.rs index 92cf43e..8f3b1a3 100644 --- a/crates/core/src/ast/loops.rs +++ b/crates/core/src/ast/loops.rs @@ -1,5 +1,5 @@ use std::fmt::Debug; -use crate::{AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::{tokens::UnnamedNode, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -62,36 +62,44 @@ impl SyntaxNodeTraversal for ForLoopNode<'_> { let tp = visitor.visit_for_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((init, Some("init"))) if tp.traverse_init => { - let init: ExpressionNode = init.unsafe_into(); - ctx.push(TraversalContext::ForLoopInit); + + let init: ExpressionNode = init.unsafe_into(); init.accept(visitor, ctx); + ctx.pop(); }, Ok((cond, Some("cond"))) if tp.traverse_cond => { - let cond: ExpressionNode = cond.unsafe_into(); - ctx.push(TraversalContext::ForLoopCond); + + let cond: ExpressionNode = cond.unsafe_into(); cond.accept(visitor, ctx); + ctx.pop(); }, Ok((iter, Some("iter"))) if tp.traverse_iter => { - let iter: ExpressionNode = iter.unsafe_into(); - ctx.push(TraversalContext::ForLoopIter); + + let iter: ExpressionNode = iter.unsafe_into(); iter.accept(visitor, ctx); + ctx.pop(); }, Ok((body, Some("body"))) if tp.traverse_body => { - let body: FunctionStatementNode = body.unsafe_into(); - ctx.push(TraversalContext::ForLoopBody); + + let body: FunctionStatementNode = body.unsafe_into(); body.accept(visitor, ctx); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -148,22 +156,28 @@ impl SyntaxNodeTraversal for WhileLoopNode<'_> { let tp = visitor.visit_while_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((cond, Some("cond"))) if tp.traverse_cond => { - let cond: ExpressionNode = cond.unsafe_into(); - ctx.push(TraversalContext::WhileLoopCond); + + let cond: ExpressionNode = cond.unsafe_into(); cond.accept(visitor, ctx); + ctx.pop(); }, Ok((body, Some("body"))) if tp.traverse_body => { - let body: FunctionStatementNode = body.unsafe_into(); - ctx.push(TraversalContext::WhileLoopBody); + + let body: FunctionStatementNode = body.unsafe_into(); body.accept(visitor, ctx); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -220,7 +234,7 @@ impl SyntaxNodeTraversal for DoWhileLoopNode<'_> { let tp = visitor.visit_do_while_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((cond, Some("cond"))) if tp.traverse_cond => { let cond: ExpressionNode = cond.unsafe_into(); @@ -236,6 +250,10 @@ impl SyntaxNodeTraversal for DoWhileLoopNode<'_> { body.accept(visitor, ctx); ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/misc_props.rs b/crates/core/src/ast/misc_props.rs index 7952473..0dcd757 100644 --- a/crates/core/src/ast/misc_props.rs +++ b/crates/core/src/ast/misc_props.rs @@ -48,13 +48,16 @@ impl SyntaxNodeTraversal for MemberDefaultsBlockNode<'_> { let tp = visitor.visit_member_defaults_block(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((assign, _)) if tp.traverse_assignments => { + Ok((assign, _)) if assign.is_named() && tp.traverse_assignments => { let assign: MemberDefaultsBlockAssignmentNode = assign.unsafe_into(); - assign.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -113,13 +116,16 @@ impl SyntaxNodeTraversal for MemberDefaultsBlockAssignmentNode<'_> { if tp.any() { ctx.push(TraversalContext::MemberDefaultValue); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((value, Some("value"))) if tp.traverse_value => { let value: ExpressionNode = value.unsafe_into(); - value.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -180,13 +186,16 @@ impl SyntaxNodeTraversal for MemberDefaultValueNode<'_> { if tp.any() { ctx.push(TraversalContext::MemberDefaultValue); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((value, Some("value"))) if tp.traverse_value => { let value: ExpressionNode = value.unsafe_into(); - value.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -245,8 +254,12 @@ impl SyntaxNodeTraversal for MemberHintNode<'_> { let tp = visitor.visit_member_hint(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/misc_stmts.rs b/crates/core/src/ast/misc_stmts.rs index e9a1283..926f63c 100644 --- a/crates/core/src/ast/misc_stmts.rs +++ b/crates/core/src/ast/misc_stmts.rs @@ -1,4 +1,4 @@ -use crate::{debug::*, AnyNode, NamedSyntaxNode, SyntaxNode}; +use crate::{debug::*, tokens::UnnamedNode, AnyNode, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -44,6 +44,10 @@ impl SyntaxNodeTraversal for BreakStatementNode<'_> { if tp.any() { for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -91,6 +95,10 @@ impl SyntaxNodeTraversal for ContinueStatementNode<'_> { if tp.any() { for ch in self.children_detailed() { match ch { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -144,13 +152,16 @@ impl SyntaxNodeTraversal for ReturnStatementNode<'_> { if tp.any() { ctx.push(TraversalContext::ReturnStatement); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((value, _)) if tp.traverse_value => { let value: ExpressionNode = value.unsafe_into(); - value.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -206,13 +217,16 @@ impl SyntaxNodeTraversal for DeleteStatementNode<'_> { if tp.any() { ctx.push(TraversalContext::DeleteStatement); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { - Ok((value, _)) if tp.traverse_value => { + Ok((value, _)) if value.is_named() && tp.traverse_value => { let value: ExpressionNode = value.unsafe_into(); - value.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, diff --git a/crates/core/src/ast/states.rs b/crates/core/src/ast/states.rs index e6f3ccf..e593393 100644 --- a/crates/core/src/ast/states.rs +++ b/crates/core/src/ast/states.rs @@ -1,5 +1,5 @@ use std::fmt::Debug; -use crate::{attribs::SpecifierNode, tokens::IdentifierNode, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; +use crate::{attribs::SpecifierNode, tokens::*, AnyNode, DebugMaybeAlternate, DebugRange, NamedSyntaxNode, SyntaxNode}; use super::*; @@ -68,12 +68,15 @@ impl SyntaxNodeTraversal for StateDeclarationNode<'_> { if tp.any() { ctx.push(TraversalContext::State); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((def, Some("definition"))) if tp.traverse_definition => { let def: StateBlockNode = def.unsafe_into(); - - def.accept_with_policy(visitor, ctx, tp.traverse_errors); + def.accept_with_policy(visitor, ctx, tp.clone()); + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); @@ -102,15 +105,18 @@ impl<'script> StateBlockNode<'script> { } - fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_errors: bool) { - for ch in self.children_detailed().must_be_named(true) { + fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: StateDeclarationTraversalPolicy) { + for ch in self.children_detailed() { match ch { - Ok((prop, _)) => { + Ok((prop, _)) if prop.is_named() => { let prop: ClassPropertyNode = prop.unsafe_into(); - prop.accept(visitor, ctx); }, - Err(e) if traverse_errors => { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, + Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, _ => {} diff --git a/crates/core/src/ast/structs.rs b/crates/core/src/ast/structs.rs index b6b1b16..3185b7f 100644 --- a/crates/core/src/ast/structs.rs +++ b/crates/core/src/ast/structs.rs @@ -58,12 +58,15 @@ impl SyntaxNodeTraversal for StructDeclarationNode<'_> { if tp.any() { ctx.push(TraversalContext::Struct); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((def, Some("definition"))) if tp.traverse_definition => { let def: StructBlockNode = def.unsafe_into(); - - def.accept_with_policy(visitor, ctx, tp.traverse_errors); + def.accept_with_policy(visitor, ctx, tp.clone()); + }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); @@ -93,15 +96,19 @@ impl<'script> StructBlockNode<'script> { } - fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, traverse_errors: bool) { - for ch in self.children_detailed().must_be_named(true) { + fn accept_with_policy(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: StructDeclarationTraversalPolicy) { + for ch in self.children_detailed() { match ch { - Ok((prop, _)) => { + Ok((prop, _)) if prop.is_named() => { let prop: StructPropertyNode = prop.unsafe_into(); prop.accept(visitor, ctx); }, - Err(e) if traverse_errors => { + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, + Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, _ => {} diff --git a/crates/core/src/ast/traversal/policies.rs b/crates/core/src/ast/traversal/policies.rs index 704bee3..05e02f9 100644 --- a/crates/core/src/ast/traversal/policies.rs +++ b/crates/core/src/ast/traversal/policies.rs @@ -48,12 +48,14 @@ macro_rules! traversal_policy { traversal_policy!(NestedExpressionTraversalPolicy, traverse_inner, + traverse_unnamed, traverse_errors ); traversal_policy!(FunctionCallExpressionTraversalPolicy, traverse_func, traverse_args, + traverse_unnamed, traverse_errors ); @@ -64,6 +66,7 @@ traversal_policy!(FunctionCallArgumentTraversalPolicy, traversal_policy!(ArrayExpressionTraversalPolicy, traverse_accessor, traverse_index, + traverse_unnamed, traverse_errors ); @@ -103,11 +106,13 @@ traversal_policy!(TernaryConditionalExpressionTraversalPolicy, traverse_cond, traverse_conseq, traverse_alt, + traverse_unnamed, traverse_errors ); traversal_policy!(ArrayInitializerExpressionTraversalPolicy, traverse_items, + traverse_unnamed, traverse_errors ); @@ -120,25 +125,30 @@ traversal_policy!(RootTraversalPolicy, traversal_policy!(ClassDeclarationTraversalPolicy, traverse_definition, + traverse_unnamed, traverse_errors ); traversal_policy!(StateDeclarationTraversalPolicy, traverse_definition, + traverse_unnamed, traverse_errors ); traversal_policy!(StructDeclarationTraversalPolicy, traverse_definition, + traverse_unnamed, traverse_errors ); traversal_policy!(EnumDeclarationTraversalPolicy, traverse_definition, + traverse_unnamed, traverse_errors ); traversal_policy!(EnumVariantDeclarationTraversalPolicy, + traverse_unnamed, traverse_errors ); @@ -147,30 +157,36 @@ traversal_policy!(EnumVariantDeclarationTraversalPolicy, traversal_policy!(MemberVarDeclarationTraversalPolicy, traverse_annotation, traverse_type, + traverse_unnamed, traverse_errors ); traversal_policy!(MemberDefaultValueTraversalPolicy, traverse_value, + traverse_unnamed, traverse_errors ); traversal_policy!(MemberDefaultsBlockTraversalPolicy, traverse_assignments, + traverse_unnamed, traverse_errors ); traversal_policy!(MemberHintTraversalPolicy, + traverse_unnamed, traverse_errors ); traversal_policy!(AutobindDeclarationTraversalPolicy, traverse_type, + traverse_unnamed, traverse_errors ); traversal_policy!(FunctionParameterGroupTraversalPolicy, traverse_type, + traverse_unnamed, traverse_errors ); @@ -179,6 +195,7 @@ traversal_policy!(FunctionDeclarationTraversalPolicy, traverse_params, traverse_return_type, traverse_definition, + traverse_unnamed, traverse_errors ); @@ -186,6 +203,7 @@ traversal_policy!(EventDeclarationTraversalPolicy, traverse_params, traverse_return_type, traverse_definition, + traverse_unnamed, traverse_errors ); @@ -196,18 +214,21 @@ traversal_policy!(ForLoopTraversalPolicy, traverse_cond, traverse_iter, traverse_body, + traverse_unnamed, traverse_errors ); traversal_policy!(WhileLoopTraversalPolicy, traverse_cond, traverse_body, + traverse_unnamed, traverse_errors ); traversal_policy!(DoWhileLoopTraversalPolicy, traverse_cond, traverse_body, + traverse_unnamed, traverse_errors ); @@ -215,29 +236,35 @@ traversal_policy!(IfConditionalTraversalPolicy, traverse_cond, traverse_body, traverse_else_body, + traverse_unnamed, traverse_errors ); traversal_policy!(SwitchConditionalTraversalPolicy, traverse_cond, traverse_body, + traverse_unnamed, traverse_errors ); traversal_policy!(SwitchConditionalCaseLabelTraversalPolicy, traverse_value, + traverse_unnamed, traverse_errors ); traversal_policy!(SwitchConditionalDefaultLabelTraversalPolicy, + traverse_unnamed, traverse_errors ); traversal_policy!(BreakStatementTraversalPolicy, + traverse_unnamed, traverse_errors ); traversal_policy!(ContinueStatementTraversalPolicy, + traverse_unnamed, traverse_errors ); @@ -249,21 +276,25 @@ traversal_policy!(CompoundStatementTraversalPolicy, traversal_policy!(VarDeclarationTraversalPolicy, traverse_type, traverse_init_value, + traverse_unnamed, traverse_errors ); traversal_policy!(ExpressionStatementTraversalPolicy, traverse_expr, + traverse_unnamed, traverse_errors ); traversal_policy!(ReturnStatementTraversalPolicy, traverse_value, + traverse_unnamed, traverse_errors ); traversal_policy!(DeleteStatementTraversalPolicy, traverse_value, + traverse_unnamed, traverse_errors ); @@ -271,10 +302,12 @@ traversal_policy!(DeleteStatementTraversalPolicy, traversal_policy!(TypeAnnotationTraversalPolicy, traverse_type_arg, + traverse_unnamed, traverse_errors ); traversal_policy!(AnnotationTraversalPolicy, + traverse_unnamed, traverse_errors ); diff --git a/crates/core/src/ast/traversal/visitor.rs b/crates/core/src/ast/traversal/visitor.rs index 0afb011..7c5fae1 100644 --- a/crates/core/src/ast/traversal/visitor.rs +++ b/crates/core/src/ast/traversal/visitor.rs @@ -277,6 +277,9 @@ pub trait SyntaxNodeVisitor { fn exit_annotation(&mut self, n: &AnnotationNode, ctx: &TraversalContextStack) {} + /// Called when visiting an unnamed node (i.e. keyword or punctuation). + fn visit_unnamed(&mut self, n: &UnnamedNode, ctx: &TraversalContextStack) {} + /// Called when visiting a node representing a syntax error. fn visit_error(&mut self, n: &ErrorNode, ctx: &TraversalContextStack) -> ErrorTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) } /// Called after visiting a node representing a syntax error and possibly also children nodes specified in traversal policy. diff --git a/crates/core/src/ast/traversal/visitor_chain.rs b/crates/core/src/ast/traversal/visitor_chain.rs index e41cfda..1ccd95c 100644 --- a/crates/core/src/ast/traversal/visitor_chain.rs +++ b/crates/core/src/ast/traversal/visitor_chain.rs @@ -581,6 +581,11 @@ impl<'a> SyntaxNodeVisitor for SyntaxNodeVisitorChain<'a> { } + #[inline] + fn visit_unnamed(&mut self, n: &UnnamedNode, ctx: &TraversalContextStack) { + self.chain_visit(move |link| link.visit_unnamed(n, ctx)) + } + #[inline] fn visit_error(&mut self, n: &ErrorNode, ctx: &TraversalContextStack) -> ErrorTraversalPolicy { self.chain_visit_traversable(move |link| link.visit_error(n, ctx)) diff --git a/crates/core/src/ast/vars.rs b/crates/core/src/ast/vars.rs index 2b53b98..c8486da 100644 --- a/crates/core/src/ast/vars.rs +++ b/crates/core/src/ast/vars.rs @@ -56,13 +56,16 @@ impl SyntaxNodeTraversal for TypeAnnotationNode<'_> { if tp.any() { ctx.push(TraversalContext::TypeAnnotation); - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((type_arg, Some("type_arg"))) if tp.traverse_type_arg => { let type_arg: TypeAnnotationNode = type_arg.unsafe_into(); - type_arg.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -126,20 +129,24 @@ impl SyntaxNodeTraversal for LocalVarDeclarationNode<'_> { let tp = visitor.visit_local_var_decl_stmt(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((typ, Some("var_type"))) if tp.traverse_type => { let typ: TypeAnnotationNode = typ.unsafe_into(); - typ.accept(visitor, ctx); }, Ok((init_value, Some("init_value"))) if tp.traverse_init_value => { - let init_value: ExpressionNode = init_value.unsafe_into(); - ctx.push(TraversalContext::LocalVarDeclarationInitValue); + + let init_value: ExpressionNode = init_value.unsafe_into(); init_value.accept(visitor, ctx); + ctx.pop(); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -205,18 +212,20 @@ impl SyntaxNodeTraversal for MemberVarDeclarationNode<'_> { fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) { // closure to avoid code repetition below let accept_proper = |self_: &Self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: MemberVarDeclarationTraversalPolicy| { - for ch in self_.children_detailed().must_be_named(true) { + for ch in self_.children_detailed() { match ch { Ok((annot, Some("annotation"))) if tp.traverse_annotation => { let annot: AnnotationNode = annot.unsafe_into(); - annot.accept(visitor, ctx); }, Ok((typ, Some("var_type"))) if tp.traverse_type => { let typ: TypeAnnotationNode = typ.unsafe_into(); - typ.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) if tp.traverse_errors => { e.accept(visitor, ctx); }, @@ -301,13 +310,16 @@ impl SyntaxNodeTraversal for AutobindDeclarationNode<'_> { let tp = visitor.visit_autobind_decl(self, ctx); if tp.any() { - for ch in self.children_detailed().must_be_named(true) { + for ch in self.children_detailed() { match ch { Ok((typ, Some("autobind_type"))) if tp.traverse_type => { let typ: TypeAnnotationNode = typ.unsafe_into(); - typ.accept(visitor, ctx); }, + Ok((unnamed, _)) if !unnamed.is_named() && tp.traverse_unnamed => { + let unnamed: UnnamedNode = unnamed.unsafe_into(); + unnamed.accept(visitor, ctx); + }, Err(e) => { e.accept(visitor, ctx) }, diff --git a/crates/core/src/tokens/unnamed.rs b/crates/core/src/tokens/unnamed.rs index 74364c0..52ded8d 100644 --- a/crates/core/src/tokens/unnamed.rs +++ b/crates/core/src/tokens/unnamed.rs @@ -1,6 +1,6 @@ use std::str::FromStr; use std::fmt::Debug; -use crate::{tokens::Keyword, AnyNode, DebugMaybeAlternate, DebugRange, SyntaxNode}; +use crate::{ast::{SyntaxNodeTraversal, SyntaxNodeVisitor, TraversalContextStack}, tokens::Keyword, AnyNode, DebugMaybeAlternate, DebugRange, SyntaxNode}; #[derive(Debug, Clone)] @@ -41,4 +41,10 @@ impl<'script> TryFrom> for UnnamedNode<'script> { Err(()) } } +} + +impl SyntaxNodeTraversal for UnnamedNode<'_> { + fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) { + visitor.visit_unnamed(self, ctx); + } } \ No newline at end of file diff --git a/crates/lsp/src/providers/selection_range.rs b/crates/lsp/src/providers/selection_range.rs index 13e7c3a..15968c4 100644 --- a/crates/lsp/src/providers/selection_range.rs +++ b/crates/lsp/src/providers/selection_range.rs @@ -618,6 +618,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver { } AnnotationTraversalPolicy { + traverse_unnamed: false, traverse_errors: false } }