Skip to content

Commit 93fb47c

Browse files
authored
fix(ast): walk missing nodes (#471)
Fix ast.Walk missing out: * DotExpressions.Identifier * LabelledStatement.Label Fixes #299
1 parent 8d121dc commit 93fb47c

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

ast/walk.go

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func Walk(v Visitor, n Node) {
9393
case *DotExpression:
9494
if n != nil {
9595
Walk(v, n.Left)
96+
Walk(v, n.Identifier)
9697
}
9798
case *EmptyExpression:
9899
case *EmptyStatement:
@@ -134,6 +135,7 @@ func Walk(v Visitor, n Node) {
134135
}
135136
case *LabelledStatement:
136137
if n != nil {
138+
Walk(v, n.Label)
137139
Walk(v, n.Statement)
138140
}
139141
case *NewExpression:

ast/walk_test.go

+35-22
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
package ast_test
22

33
import (
4-
"log"
54
"testing"
65

76
"github.com/robertkrimen/otto/ast"
87
"github.com/robertkrimen/otto/file"
98
"github.com/robertkrimen/otto/parser"
9+
"github.com/stretchr/testify/require"
1010
)
1111

1212
type walker struct {
13-
stack []ast.Node
14-
source string
15-
shift file.Idx
13+
stack []ast.Node
14+
source string
15+
shift file.Idx
16+
seen map[ast.Node]struct{}
17+
duplicate int
1618
}
1719

1820
// push and pop below are to prove the symmetry of Enter/Exit calls
@@ -38,18 +40,25 @@ func (w *walker) pop(n ast.Node) {
3840

3941
func (w *walker) Enter(n ast.Node) ast.Visitor {
4042
w.push(n)
43+
if _, ok := w.seen[n]; ok {
44+
// Skip items we've already seen which occurs due to declarations.
45+
w.duplicate++
46+
return w
47+
}
48+
49+
w.seen[n] = struct{}{}
4150

4251
if id, ok := n.(*ast.Identifier); ok && id != nil {
4352
idx := n.Idx0() + w.shift - 1
44-
s := w.source[:idx] + "new_" + w.source[idx:]
53+
s := w.source[:idx] + "IDENT_" + w.source[idx:]
4554
w.source = s
46-
w.shift += 4
55+
w.shift += 6
4756
}
4857
if v, ok := n.(*ast.VariableExpression); ok && v != nil {
4958
idx := n.Idx0() + w.shift - 1
50-
s := w.source[:idx] + "varnew_" + w.source[idx:]
59+
s := w.source[:idx] + "VAR_" + w.source[idx:]
5160
w.source = s
52-
w.shift += 7
61+
w.shift += 4
5362
}
5463

5564
return w
@@ -60,23 +69,27 @@ func (w *walker) Exit(n ast.Node) {
6069
}
6170

6271
func TestVisitorRewrite(t *testing.T) {
63-
source := `var b = function() {test(); try {} catch(e) {} var test = "test(); var test = 1"} // test`
72+
source := `var b = function() {
73+
test();
74+
try {} catch(e) {}
75+
var test = "test(); var test = 1"
76+
} // test`
6477
program, err := parser.ParseFile(nil, "", source, 0)
65-
if err != nil {
66-
log.Fatal(err)
67-
}
68-
69-
w := &walker{source: source}
78+
require.NoError(t, err)
7079

80+
w := &walker{
81+
source: source,
82+
seen: make(map[ast.Node]struct{}),
83+
}
7184
ast.Walk(w, program)
7285

73-
xformed := `var varnew_b = function() {new_test(); try {} catch(new_e) {} var varnew_test = "test(); var test = 1"} // test`
86+
xformed := `var VAR_b = function() {
87+
IDENT_test();
88+
try {} catch(IDENT_e) {}
89+
var VAR_test = "test(); var test = 1"
90+
} // test`
7491

75-
if w.source != xformed {
76-
t.Errorf("source is `%s` not `%s`", w.source, xformed)
77-
}
78-
79-
if len(w.stack) != 0 {
80-
t.Errorf("stack should be empty, but is length: %d", len(w.stack))
81-
}
92+
require.Equal(t, xformed, w.source)
93+
require.Len(t, w.stack, 0)
94+
require.Equal(t, w.duplicate, 0)
8295
}

0 commit comments

Comments
 (0)