Skip to content

Commit

Permalink
fix(swc_visit): 🐛 visit program in AndThen
Browse files Browse the repository at this point in the history
  • Loading branch information
JSerFeng committed Mar 22, 2023
1 parent 737f2ad commit 7cd9674
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
40 changes: 40 additions & 0 deletions crates/swc_ecma_visit/src/lib.rs
Expand Up @@ -20,6 +20,12 @@ where

B: Fold,
{
#[inline(always)]
fn fold_program(&mut self, n: Program) -> Program {
let n = self.first.fold_program(n);
self.second.fold_program(n)
}

#[inline(always)]
fn fold_module(&mut self, n: Module) -> Module {
let n = self.first.fold_module(n);
Expand All @@ -38,6 +44,11 @@ where
A: VisitMut,
B: VisitMut,
{
fn visit_mut_program(&mut self, n: &mut Program) {
self.first.visit_mut_program(n);
self.second.visit_mut_program(n);
}

fn visit_mut_module(&mut self, n: &mut Module) {
self.first.visit_mut_module(n);
self.second.visit_mut_module(n)
Expand All @@ -54,6 +65,11 @@ where
A: Visit,
B: Visit,
{
fn visit_program(&mut self, n: &Program) {
self.first.visit_program(n);
self.second.visit_program(n);
}

fn visit_module(&mut self, n: &Module) {
self.first.visit_module(n);
self.second.visit_module(n);
Expand All @@ -69,6 +85,19 @@ impl<V> Fold for Repeat<V>
where
V: Fold + Repeated,
{
fn fold_program(&mut self, mut node: Program) -> Program {
loop {
self.pass.reset();
node = node.fold_with(&mut self.pass);

if !self.pass.changed() {
break;
}
}

node
}

fn fold_module(&mut self, mut node: Module) -> Module {
loop {
self.pass.reset();
Expand Down Expand Up @@ -100,6 +129,17 @@ impl<V> VisitMut for Repeat<V>
where
V: VisitMut + Repeated,
{
fn visit_mut_program(&mut self, node: &mut Program) {
loop {
self.pass.reset();
node.visit_mut_with(&mut self.pass);

if !self.pass.changed() {
break;
}
}
}

fn visit_mut_module(&mut self, node: &mut Module) {
loop {
self.pass.reset();
Expand Down
31 changes: 31 additions & 0 deletions crates/swc_ecma_visit/tests/main.rs
@@ -0,0 +1,31 @@
use swc_common::{chain, DUMMY_SP};
use swc_ecma_ast::{Module, Program};
use swc_ecma_visit::{Visit, VisitWith};

#[test]
fn should_visit_program() {
struct Pass1<'a>(&'a mut usize);
struct Pass2;

impl<'a> Visit for Pass1<'a> {
fn visit_program(&mut self, _program: &Program) {
*self.0 += 1;
}
}

impl Visit for Pass2 {}

let n = Program::Module(Module {
span: DUMMY_SP,
body: vec![],
shebang: None,
});

let mut counter = 0;
let p1 = Pass1(&mut counter);
let p2 = Pass2;
let mut pass = chain!(p1, p2);
n.visit_with(&mut pass);

assert_eq!(counter, 1);
}

0 comments on commit 7cd9674

Please sign in to comment.