-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfor.lsc
More file actions
117 lines (102 loc) · 3.5 KB
/
for.lsc
File metadata and controls
117 lines (102 loc) · 3.5 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
import t from '../types'
import { ensureBlockBody } from '../helpers/blocks'
import { undeclaredRef } from '../helpers/variables'
import { getLoc, placeAtLoc as atLoc, placeAtNode as atNode, span, placeTreeAtLocWhenUnplaced as allAtLoc } from 'ast-loc-utils'
generateForInIterator(path, type: "array" | "object") ->
{ node } = path
forKwdLoc = node~getLoc()~span(3)
iterable = node[type]
iterableLoc = iterable~getLoc()
idx = node.idx || path.scope.generateUidIdentifier("i")~t.clone()~atLoc(forKwdLoc)
// _i = 0
initDeclarations = [
t.variableDeclarator(idx, t.numericLiteral(0)~atNode(idx))~atNode(idx)
]
// (_obj|_arr) = <expr>
{ ref: iterableRef, declarator, isComplex } = undeclaredRef(path, iterable, type === "object" ? "obj" : "arr")
if isComplex: initDeclarations.unshift(declarator)
// _keys = Object.keys(_obj)
let keys;
if (type === "object") {
now keys = path.scope.generateUidIdentifier("keys")~t.clone()~atLoc(iterableLoc);
initDeclarations.push(
t.variableDeclarator(keys,
t.callExpression(
t.memberExpression(
t.identifier("Object")~atLoc(iterableLoc),
t.identifier("keys")~atLoc(iterableLoc)
)~atLoc(iterableLoc)
[iterableRef]
)~atLoc(iterableLoc)
)~atLoc(iterableLoc)
)
}
// _len = (_keys | _arr).length
len = path.scope.generateUidIdentifier("len")~t.clone()~atLoc(iterableLoc)
initDeclarations.push(
t.variableDeclarator(
len,
t.memberExpression(
type === "object" ? keys : iterableRef,
t.identifier("length")~atLoc(iterableLoc)
)~atLoc(iterableLoc)
)~atLoc(iterableLoc)
)
init = t.variableDeclaration("let", initDeclarations)~atLoc(forKwdLoc)
// _i < _len
test = t.binaryExpression("<", idx, len)~atLoc(forKwdLoc)
// _i++
update = t.updateExpression("++", idx)~atLoc(forKwdLoc)
ensureBlockBody(path)
innerDeclarations = []
if (type === "object") {
// _k = _keys[_i]
key = path.node.key || path.scope.generateUidIdentifier("k")~t.clone()~atLoc(iterableLoc)
innerDeclarations.push(
t.variableDeclaration("const", [
t.variableDeclarator(key,
t.memberExpression(keys, idx, true)
)
])~allAtLoc(iterableLoc)
);
// val = _obj[_k]
if (path.node.val) {
innerDeclarations.push(
t.variableDeclaration("const", [
t.variableDeclarator(
path.node.val,
t.memberExpression(iterableRef, key, true)
)
])~allAtLoc(iterableLoc)
)
}
} else {
// elem = _arr[_i]
if (path.node.elem) {
innerDeclarations.push(
t.variableDeclaration("const", [
t.variableDeclarator(
path.node.elem,
t.memberExpression(iterableRef, idx, true)
)
])~allAtLoc(iterableLoc)
)
}
}
if (innerDeclarations.length > 0) {
path.get("body").unshiftContainer("body", innerDeclarations)
}
t.forStatement(init, test, update, path.node.body)~atNode(node)
export transformForInArrayStatement(path) ->
path.replaceWith(generateForInIterator(path, "array"))
export transformForInObjectStatement(path) ->
path.replaceWith(generateForInIterator(path, "object"))
export maybeTransformAutoConstDeclaration(path) ->
{ node } = path; { left } = node
if left.type != "VariableDeclaration" and (not left.isNowAssign):
path.get("left").replaceWith(
t.variableDeclaration(
"const"
[t.variableDeclarator(left)~atNode(left)]
)~atNode(left)
)