index.js
2.87 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
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = function (_ref) {
var Plugin = _ref.Plugin;
var t = _ref.types;
return new Plugin("constant-folding", {
metadata: {
group: "builtin-prepass",
experimental: true
},
visitor: {
AssignmentExpression: function AssignmentExpression() {
var left = this.get("left");
if (!left.isIdentifier()) return;
var binding = this.scope.getBinding(left.node.name);
if (!binding || binding.hasDeoptValue) return;
var evaluated = this.get("right").evaluate();
if (evaluated.confident) {
binding.setValue(evaluated.value);
} else {
binding.deoptValue();
}
},
IfStatement: function IfStatement() {
var evaluated = this.get("test").evaluate();
if (!evaluated.confident) {
// todo: deopt binding values for constant violations inside
return this.skip();
}
if (evaluated.value) {
this.skipKey("alternate");
} else {
this.skipKey("consequent");
}
},
Scopable: {
enter: function enter() {
var funcScope = this.scope.getFunctionParent();
for (var name in this.scope.bindings) {
var binding = this.scope.bindings[name];
var deopt = false;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = binding.constantViolations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var path = _step.value;
var funcViolationScope = path.scope.getFunctionParent();
if (funcViolationScope !== funcScope) {
deopt = true;
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"]) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (deopt) binding.deoptValue();
}
},
exit: function exit() {
for (var name in this.scope.bindings) {
var binding = this.scope.bindings[name];
binding.clearValue();
}
}
},
Expression: {
exit: function exit() {
var res = this.evaluate();
if (res.confident) return t.valueToNode(res.value);
}
}
}
});
};
module.exports = exports["default"];