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 | 1
1
630
630
630
1
12
8
4
4
4
1
12
12
12
1
12
1
18
18
1
12
1
578
578
6
6
6
6
6
6
1
141
52
6
6
6
6
6
6
6
| var t = require("../../types");
var isMemo = function (node) {
var is = t.isAssignmentExpression(node) && node.operator === "?=";
if (is) t.assertMemberExpression(node.left);
return is;
};
var getPropRef = function (nodes, prop, file, scope) {
if (t.isIdentifier(prop)) {
return t.literal(prop.name);
} else {
var temp = scope.generateUidBasedOnNode(prop, file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, prop)
]));
return temp;
}
};
var getObjRef = function (nodes, obj, file, scope) {
var temp = scope.generateUidBasedOnNode(obj, file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, obj)
]));
return temp;
};
var buildHasOwn = function (obj, prop, file) {
return t.unaryExpression(
"!",
t.callExpression(
t.memberExpression(file.addHelper("has-own"), t.identifier("call")),
[obj, prop]
),
true
);
};
var buildAbsoluteRef = function (left, obj, prop) {
var computed = left.computed || t.isLiteral(prop);
return t.memberExpression(obj, prop, computed);
};
var buildAssignment = function (expr, obj, prop) {
return t.assignmentExpression("=", buildAbsoluteRef(expr.left, obj, prop), expr.right);
};
exports.ExpressionStatement = function (node, parent, file, scope) {
var expr = node.expression;
if (!isMemo(expr)) return;
var nodes = [];
var left = expr.left;
var obj = getObjRef(nodes, left.object, file, scope);
var prop = getPropRef(nodes, left.property, file, scope);
nodes.push(t.ifStatement(
buildHasOwn(obj, prop, file),
t.expressionStatement(buildAssignment(expr, obj, prop))
));
return nodes;
};
exports.AssignmentExpression = function (node, parent, file, scope) {
if (t.isExpressionStatement(parent)) return;
if (!isMemo(node)) return;
var nodes = [];
var left = node.left;
var obj = getObjRef(nodes, left.object, file, scope);
var prop = getPropRef(nodes, left.property, file, scope);
nodes.push(t.logicalExpression(
"&&",
buildHasOwn(obj, prop, file),
buildAssignment(node, obj, prop)
));
nodes.push(buildAbsoluteRef(left, obj, prop));
return t.toSequenceExpression(nodes, scope);
};
|