-
Notifications
You must be signed in to change notification settings - Fork 20
/
renderer-ast-walker.ts
105 lines (103 loc) · 3.36 KB
/
renderer-ast-walker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* Renderer AST 遍历器
*
* 用来遍历 Renderer 里的每一个节点,方便做查找、移除等逻辑
*/
import { Statement, SyntaxKind, Expression } from './renderer-ast-dfn'
import { assertNever } from '../utils/lang'
export function * walk (node: Expression | Statement): Iterable<Expression | Statement> {
yield node
switch (node.kind) {
case SyntaxKind.JSONStringify:
case SyntaxKind.UnaryExpression:
case SyntaxKind.ComponentRendererReference:
case SyntaxKind.ComponentClassReference:
case SyntaxKind.EncodeURIComponent:
case SyntaxKind.ReturnStatement:
case SyntaxKind.ExpressionStatement:
yield * walk(node.value)
break
case SyntaxKind.Literal:
case SyntaxKind.Identifier:
case SyntaxKind.CreateComponentInstance:
case SyntaxKind.Null:
case SyntaxKind.Undefined:
case SyntaxKind.ImportHelper:
case SyntaxKind.ComputedCall:
case SyntaxKind.ComponentReferenceLiteral:
break
case SyntaxKind.ArrayIncludes:
yield * walk(node.arr)
yield * walk(node.item)
break
case SyntaxKind.MapAssign:
yield * walk(node.dest)
for (const src of node.srcs) yield * walk(src)
break
case SyntaxKind.RegexpReplace:
yield * walk(node.original)
yield * walk(node.replacement)
break
case SyntaxKind.ConditionalExpression:
yield * walk(node.cond)
yield * walk(node.falseValue)
yield * walk(node.trueValue)
break
case SyntaxKind.FilterCall:
case SyntaxKind.GetRootCtxCall:
case SyntaxKind.HelperCall:
for (const arg of node.args) yield * walk(arg)
break
case SyntaxKind.FunctionDefinition:
case SyntaxKind.SlotRendererDefinition:
for (const arg of node.args) yield * walk(arg)
for (const stmt of node.body) yield * walk(stmt)
break
case SyntaxKind.FunctionCall:
case SyntaxKind.SlotRenderCall:
for (const arg of node.args) yield * walk(arg)
yield * walk(node.fn)
break
case SyntaxKind.NewExpression:
for (const arg of node.args) yield * walk(arg)
yield * walk(node.name)
break
case SyntaxKind.ArrayLiteral:
for (const [expr] of node.items) yield * walk(expr)
break
case SyntaxKind.MapLiteral:
for (const [key, val] of node.items) {
yield * walk(key)
yield * walk(val)
}
break
case SyntaxKind.AssignmentStatement:
case SyntaxKind.BinaryExpression:
yield * walk(node.lhs)
yield * walk(node.rhs)
break
case SyntaxKind.VariableDefinition:
if (node.initial) yield * walk(node.initial)
break
case SyntaxKind.If:
case SyntaxKind.ElseIf:
yield * walk(node.cond)
for (const stmt of node.body) yield * walk(stmt)
break
case SyntaxKind.Else:
for (const stmt of node.body) yield * walk(stmt)
break
case SyntaxKind.Foreach:
yield * walk(node.key)
yield * walk(node.value)
yield * walk(node.iterable)
for (const stmt of node.body) yield * walk(stmt)
break
case SyntaxKind.TryStatement:
for (const stmt of node.block) yield * walk(stmt)
yield * walk(node.handler.param)
for (const stmt of node.handler.body) yield * walk(stmt)
break
default: assertNever(node)
}
}