Skip to content

Commit

Permalink
Rewrote node traversal to allow visitations to error nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
SpontanCombust committed Aug 14, 2024
1 parent b7444ff commit 00b8cea
Show file tree
Hide file tree
Showing 12 changed files with 1,058 additions and 238 deletions.
53 changes: 50 additions & 3 deletions crates/core/src/ast/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,27 @@ impl<'script> TryFrom<AnyNode<'script>> for ClassDeclarationNode<'script> {
impl SyntaxNodeTraversal for ClassDeclarationNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_class_decl(self);
if tp.traverse_definition {

if tp.any() {
ctx.push(TraversalContext::Class);
self.definition().accept(visitor, ctx);

for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((definition, Some("definition"))) if tp.traverse_definition => {
let definition: ClassBlockNode = definition.into();

definition.accept_with_policy(visitor, ctx, tp.clone());
}
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx)
},
_ => {}
}
}

ctx.pop();
}

visitor.exit_class_decl(self);
}
}
Expand All @@ -82,6 +98,23 @@ impl<'script> ClassBlockNode<'script> {
pub fn iter(&self) -> impl Iterator<Item = ClassPropertyNode<'script>> {
self.named_children().map(|n| n.into())
}


fn accept_with_policy<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: ClassDeclarationTraversalPolicy) {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((prop, _)) => {
let prop: ClassPropertyNode = prop.into();

prop.accept(visitor, ctx);
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}
}
}

impl Debug for ClassBlockNode<'_> {
Expand All @@ -107,6 +140,7 @@ impl<'script> TryFrom<AnyNode<'script>> for ClassBlockNode<'script> {

impl SyntaxNodeTraversal for ClassBlockNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
// UNUSED
self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
Expand Down Expand Up @@ -253,7 +287,20 @@ impl<'script> TryFrom<AnyNode<'script>> for AutobindDeclarationNode<'script> {

impl SyntaxNodeTraversal for AutobindDeclarationNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_autobind_decl(self, ctx);
let tp = visitor.visit_autobind_decl(self, ctx);

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Err(e) => {
e.accept(visitor, ctx)
},
_ => {}
}
}
}

visitor.exit_autobind_decl(self, ctx);
}
}

Expand Down
135 changes: 107 additions & 28 deletions crates/core/src/ast/conditionals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,39 @@ impl<'script> TryFrom<AnyNode<'script>> for IfConditionalNode<'script> {
impl SyntaxNodeTraversal for IfConditionalNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_if_stmt(self, ctx);
if tp.traverse_cond {
ctx.push(TraversalContext::IfConditionalCond);
self.cond().accept(visitor, ctx);
ctx.pop();
}
if tp.traverse_body {
ctx.push(TraversalContext::IfConditionalBody);
self.body().accept(visitor, ctx);
ctx.pop();
}
if tp.traverse_else_body {
ctx.push(TraversalContext::IfConditionalElseBody);
self.else_body().map(|s| s.accept(visitor, ctx));
ctx.pop();

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((cond, Some("cond"))) if tp.traverse_cond => {
let cond: ExpressionNode = cond.into();

ctx.push(TraversalContext::IfConditionalCond);
cond.accept(visitor, ctx);
ctx.pop();
},
Ok((body, Some("body"))) if tp.traverse_body => {
let body: FunctionStatementNode = body.into();

ctx.push(TraversalContext::IfConditionalBody);
body.accept(visitor, ctx);
ctx.pop();
},
Ok((else_body, Some("else"))) if tp.traverse_else_body => {
let else_body: FunctionStatementNode = else_body.into();

ctx.push(TraversalContext::IfConditionalElseBody);
else_body.accept(visitor, ctx);
ctx.pop();
}
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx)
},
_ => {}
}
}
}

visitor.exit_if_stmt(self, ctx);
}
}
Expand Down Expand Up @@ -118,16 +136,32 @@ impl<'script> TryFrom<AnyNode<'script>> for SwitchConditionalNode<'script> {
impl SyntaxNodeTraversal for SwitchConditionalNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_switch_stmt(self, ctx);
if tp.traverse_cond {
ctx.push(TraversalContext::SwitchConditionalCond);
self.cond().accept(visitor, ctx);
ctx.pop();
}
if tp.traverse_body {
ctx.push(TraversalContext::SwitchConditionalBody);
self.body().accept(visitor, ctx);
ctx.pop();

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((cond, Some("cond"))) if tp.traverse_cond => {
let cond: ExpressionNode = cond.into();

ctx.push(TraversalContext::SwitchConditionalCond);
cond.accept(visitor, ctx);
ctx.pop();
},
Ok((body, Some("body"))) if tp.traverse_body => {
let body: SwitchConditionalBlockNode = body.into();

ctx.push(TraversalContext::SwitchConditionalBody);
body.accept_with_policy(visitor, ctx, tp.clone());
ctx.pop();
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}
}

visitor.exit_switch_stmt(self, ctx);
}
}
Expand All @@ -144,6 +178,23 @@ impl<'script> SwitchConditionalBlockNode<'script> {
pub fn sections(&self) -> impl Iterator<Item = SwitchConditionalSectionNode<'script>> {
self.named_children().map(|n| n.into())
}


fn accept_with_policy<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: SwitchConditionalTraversalPolicy) {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((section, _)) => {
let section: SwitchConditionalSectionNode = section.into();

section.accept(visitor, ctx)
}
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx)
},
_ => {}
}
}
}
}

impl Debug for SwitchConditionalBlockNode<'_> {
Expand All @@ -169,6 +220,7 @@ impl<'script> TryFrom<AnyNode<'script>> for SwitchConditionalBlockNode<'script>

impl SyntaxNodeTraversal for SwitchConditionalBlockNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
// UNUSED
self.sections().for_each(|s| s.accept(visitor, ctx));
}
}
Expand Down Expand Up @@ -283,11 +335,25 @@ impl<'script> TryFrom<AnyNode<'script>> for SwitchConditionalCaseLabelNode<'scri
impl SyntaxNodeTraversal for SwitchConditionalCaseLabelNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_switch_stmt_case(self, ctx);
if tp.traverse_value {
ctx.push(TraversalContext::SwitchConditionalCaseLabel);
self.value().accept(visitor, ctx);
ctx.pop();

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((value, Some("value"))) if tp.traverse_value => {
let value: ExpressionNode = value.into();

ctx.push(TraversalContext::SwitchConditionalCaseLabel);
value.accept(visitor, ctx);
ctx.pop();
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
}
_ => {}
}
}
}

visitor.exit_switch_stmt_case(self, ctx);
}
}
Expand Down Expand Up @@ -320,6 +386,19 @@ impl<'script> TryFrom<AnyNode<'script>> for SwitchConditionalDefaultLabelNode<'s

impl SyntaxNodeTraversal for SwitchConditionalDefaultLabelNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_switch_stmt_default(self, ctx);
let tp = visitor.visit_switch_stmt_default(self, ctx);

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
}
_ => {}
}
}
}

visitor.exit_switch_stmt_default(self, ctx);
}
}
57 changes: 51 additions & 6 deletions crates/core/src/ast/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,25 @@ impl<'script> TryFrom<AnyNode<'script>> for EnumDeclarationNode<'script> {
impl SyntaxNodeTraversal for EnumDeclarationNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_enum_decl(self);
if tp.traverse_definition {
ctx.push(TraversalContext::Enum);
self.definition().accept(visitor, ctx);
ctx.pop();

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((def, Some("definition"))) if tp.traverse_definition => {
let def: EnumBlockNode = def.into();

ctx.push(TraversalContext::Enum);
def.accept_with_policy(visitor, ctx, tp.clone());
ctx.pop();
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}
}

visitor.exit_enum_decl(self);
}
}
Expand All @@ -71,6 +85,23 @@ impl<'script> EnumBlockNode<'script> {
pub fn iter(&self) -> impl Iterator<Item = EnumVariantDeclarationNode<'script>> {
self.named_children().map(|n| n.into())
}


fn accept_with_policy<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack, tp: EnumDeclarationTraversalPolicy) {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((variant, _)) => {
let variant: EnumVariantDeclarationNode = variant.into();

variant.accept(visitor, ctx);
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}
}
}

impl Debug for EnumBlockNode<'_> {
Expand All @@ -96,6 +127,7 @@ impl<'script> TryFrom<AnyNode<'script>> for EnumBlockNode<'script> {

impl SyntaxNodeTraversal for EnumBlockNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
// UNUSED
self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
Expand Down Expand Up @@ -146,8 +178,21 @@ impl<'script> TryFrom<AnyNode<'script>> for EnumVariantDeclarationNode<'script>
}

impl SyntaxNodeTraversal for EnumVariantDeclarationNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, _: &mut TraversalContextStack) {
visitor.visit_enum_variant_decl(self);
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_enum_variant_decl(self);

if tp.any() {
for ch in self.children_detailed().must_be_named(true) {
match ch {
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}
}

visitor.exit_enum_variant_decl(self);
}
}

Expand Down
Loading

0 comments on commit 00b8cea

Please sign in to comment.