File tree 5 files changed +60
-28
lines changed
5 files changed +60
-28
lines changed Original file line number Diff line number Diff line change @@ -41,3 +41,5 @@ func (BaseVisitor) ArrayNode(node *ArrayNode) {}
41
41
func (BaseVisitor ) MapNode (node * MapNode ) {}
42
42
43
43
func (BaseVisitor ) PairNode (node * PairNode ) {}
44
+
45
+ func (BaseVisitor ) Node (node * Node ) {}
Original file line number Diff line number Diff line change @@ -23,21 +23,24 @@ type Visitor interface {
23
23
ArrayNode (node * ArrayNode )
24
24
MapNode (node * MapNode )
25
25
PairNode (node * PairNode )
26
+ Node (node * Node )
26
27
}
27
28
28
29
type walker struct {
29
30
visitor Visitor
30
31
}
31
32
32
- func Walk (node Node , visitor Visitor ) {
33
+ func Walk (node * Node , visitor Visitor ) {
33
34
w := walker {
34
35
visitor : visitor ,
35
36
}
36
37
w .walk (node )
37
38
}
38
39
39
- func (w * walker ) walk (node Node ) {
40
- switch n := node .(type ) {
40
+ func (w * walker ) walk (node * Node ) {
41
+ w .visitor .Node (node )
42
+
43
+ switch n := (* node ).(type ) {
41
44
case * NilNode :
42
45
w .visitor .NilNode (n )
43
46
case * IdentifierNode :
@@ -51,61 +54,62 @@ func (w *walker) walk(node Node) {
51
54
case * StringNode :
52
55
w .visitor .StringNode (n )
53
56
case * UnaryNode :
54
- w .walk (n .Node )
57
+ w .walk (& n .Node )
55
58
w .visitor .UnaryNode (n )
56
59
case * BinaryNode :
57
- w .walk (n .Left )
58
- w .walk (n .Right )
60
+ w .walk (& n .Left )
61
+ w .walk (& n .Right )
59
62
w .visitor .BinaryNode (n )
60
63
case * MatchesNode :
61
- w .walk (n .Left )
62
- w .walk (n .Right )
64
+ w .walk (& n .Left )
65
+ w .walk (& n .Right )
63
66
w .visitor .MatchesNode (n )
64
67
case * PropertyNode :
65
- w .walk (n .Node )
68
+ w .walk (& n .Node )
66
69
w .visitor .PropertyNode (n )
67
70
case * IndexNode :
68
- w .walk (n .Node )
69
- w .walk (n .Index )
71
+ w .walk (& n .Node )
72
+ w .walk (& n .Index )
70
73
w .visitor .IndexNode (n )
71
74
case * MethodNode :
72
- w .walk (n .Node )
75
+ w .walk (& n .Node )
73
76
for _ , arg := range n .Arguments {
74
- w .walk (arg )
77
+ w .walk (& arg )
75
78
}
76
79
w .visitor .MethodNode (n )
77
80
case * FunctionNode :
78
81
for _ , arg := range n .Arguments {
79
- w .walk (arg )
82
+ w .walk (& arg )
80
83
}
81
84
w .visitor .FunctionNode (n )
82
85
case * BuiltinNode :
83
86
for _ , arg := range n .Arguments {
84
- w .walk (arg )
87
+ w .walk (& arg )
85
88
}
86
89
w .visitor .BuiltinNode (n )
87
90
case * ClosureNode :
88
- w .walk (n .Node )
91
+ w .walk (& n .Node )
89
92
w .visitor .ClosureNode (n )
90
93
case * PointerNode :
91
94
w .visitor .PointerNode (n )
92
95
case * ConditionalNode :
93
- w .walk (n .Cond )
94
- w .walk (n .Exp1 )
95
- w .walk (n .Exp2 )
96
+ w .walk (& n .Cond )
97
+ w .walk (& n .Exp1 )
98
+ w .walk (& n .Exp2 )
96
99
w .visitor .ConditionalNode (n )
97
100
case * ArrayNode :
98
101
for _ , node := range n .Nodes {
99
- w .walk (node )
102
+ w .walk (& node )
100
103
}
101
104
w .visitor .ArrayNode (n )
102
105
case * MapNode :
103
- for _ , pair := range n .Pairs {
104
- w .walk (pair )
106
+ var pair Node
107
+ for _ , pair = range n .Pairs {
108
+ w .walk (& pair )
105
109
}
106
110
w .visitor .MapNode (n )
107
111
case * PairNode :
108
- w .walk (n .Value )
112
+ w .walk (& n .Value )
109
113
w .visitor .PairNode (n )
110
114
default :
111
115
panic (fmt .Sprintf ("undefined node type (%T)" , node ))
Original file line number Diff line number Diff line change @@ -16,13 +16,38 @@ func (v *visitor) IdentifierNode(node *ast.IdentifierNode) {
16
16
}
17
17
18
18
func TestWalk (t * testing.T ) {
19
- node := & ast.BinaryNode {
19
+ var node ast.Node
20
+ node = & ast.BinaryNode {
20
21
Operator : "+" ,
21
22
Left : & ast.IdentifierNode {Value : "foo" },
22
23
Right : & ast.IdentifierNode {Value : "bar" },
23
24
}
24
25
25
26
visitor := & visitor {}
26
- ast .Walk (node , visitor )
27
+ ast .Walk (& node , visitor )
27
28
assert .Equal (t , []string {"foo" , "bar" }, visitor .identifiers )
28
29
}
30
+
31
+ type patcher struct {
32
+ ast.BaseVisitor
33
+ }
34
+
35
+ func (p * patcher ) Node (node * ast.Node ) {
36
+ if _ , ok := (* node ).(* ast.IdentifierNode ); ok {
37
+ * node = & ast.NilNode {}
38
+ }
39
+ }
40
+
41
+ func TestWalk_patch (t * testing.T ) {
42
+ var node ast.Node
43
+ node = & ast.BinaryNode {
44
+ Operator : "+" ,
45
+ Left : & ast.IdentifierNode {Value : "foo" },
46
+ Right : & ast.IdentifierNode {Value : "bar" },
47
+ }
48
+
49
+ patcher := & patcher {}
50
+ ast .Walk (& node , patcher )
51
+ assert .IsType (t , & ast.NilNode {}, node .(* ast.BinaryNode ).Left )
52
+ assert .IsType (t , & ast.NilNode {}, node .(* ast.BinaryNode ).Right )
53
+ }
Original file line number Diff line number Diff line change @@ -281,7 +281,7 @@ func (v setVisitor) IntegerNode(node *ast.IntegerNode) {
281
281
}
282
282
283
283
func setUncertainType (node ast.Node , t reflect.Type ) {
284
- ast .Walk (node , setVisitor {t : dereference (t )})
284
+ ast .Walk (& node , setVisitor {t : dereference (t )})
285
285
}
286
286
287
287
type hasVisitor struct {
@@ -295,6 +295,6 @@ func (v *hasVisitor) IntegerNode(node *ast.IntegerNode) {
295
295
296
296
func isCertain (node ast.Node ) bool {
297
297
v := & hasVisitor {certain : true }
298
- ast .Walk (node , v )
298
+ ast .Walk (& node , v )
299
299
return v .certain
300
300
}
Original file line number Diff line number Diff line change @@ -18,12 +18,13 @@ const format = `digraph {
18
18
19
19
func dotAst (node Node ) {
20
20
v := & visitor {}
21
- Walk (node , v )
21
+ Walk (& node , v )
22
22
dot := fmt .Sprintf (format , v .nodes , v .links )
23
23
_ , _ = fmt .Fprintf (os .Stdout , dot )
24
24
}
25
25
26
26
type visitor struct {
27
+ BaseVisitor
27
28
nodes string
28
29
links string
29
30
index int
You can’t perform that action at this time.
0 commit comments