webpack 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -132
- package/lib/APIPlugin.js +0 -6
- package/lib/AsyncDependenciesBlock.js +1 -1
- package/lib/AutomaticPrefetchPlugin.js +2 -2
- package/lib/CachePlugin.js +2 -2
- package/lib/CaseSensitiveModulesWarning.js +6 -3
- package/lib/ChunkRenderError.js +3 -1
- package/lib/ChunkTemplate.js +2 -2
- package/lib/Compilation.js +3 -3
- package/lib/Compiler.js +1 -1
- package/lib/ContextModule.js +3 -2
- package/lib/ContextModuleFactory.js +5 -5
- package/lib/DelegatedModule.js +67 -63
- package/lib/DependenciesBlock.js +65 -59
- package/lib/Dependency.js +1 -0
- package/lib/EntryModuleNotFoundError.js +16 -10
- package/lib/ExtendedAPIPlugin.js +7 -2
- package/lib/ExternalModuleFactoryPlugin.js +26 -23
- package/lib/FlagDependencyUsagePlugin.js +63 -75
- package/lib/HotModuleReplacement.runtime.js +25 -27
- package/lib/HotModuleReplacementPlugin.js +3 -5
- package/lib/IgnorePlugin.js +48 -17
- package/lib/JsonpChunkTemplatePlugin.js +24 -24
- package/lib/JsonpMainTemplatePlugin.js +182 -182
- package/lib/LibManifestPlugin.js +51 -46
- package/lib/MainTemplate.js +17 -18
- package/lib/Module.js +158 -160
- package/lib/ModuleBuildError.js +4 -2
- package/lib/ModuleDependencyError.js +2 -1
- package/lib/ModuleDependencyWarning.js +2 -1
- package/lib/ModuleError.js +2 -2
- package/lib/ModuleFilenameHelpers.js +27 -27
- package/lib/ModuleNotFoundError.js +3 -1
- package/lib/ModuleParseError.js +6 -4
- package/lib/ModuleWarning.js +2 -2
- package/lib/MultiCompiler.js +3 -4
- package/lib/MultiStats.js +3 -3
- package/lib/MultiWatching.js +2 -2
- package/lib/NamedChunksPlugin.js +30 -0
- package/lib/NodeStuffPlugin.js +80 -79
- package/lib/NormalModule.js +6 -2
- package/lib/NormalModuleFactory.js +244 -240
- package/lib/Parser.js +1256 -1079
- package/lib/ProgressPlugin.js +1 -1
- package/lib/RecordIdsPlugin.js +5 -9
- package/lib/SetVarMainTemplatePlugin.js +1 -1
- package/lib/SourceMapDevToolPlugin.js +153 -157
- package/lib/Stats.js +32 -5
- package/lib/TemplatedPathPlugin.js +1 -0
- package/lib/UnsupportedFeatureWarning.js +2 -1
- package/lib/WebpackError.js +11 -0
- package/lib/WebpackOptionsApply.js +1 -1
- package/lib/WebpackOptionsValidationError.js +8 -4
- package/lib/dependencies/AMDDefineDependency.js +10 -6
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +8 -1
- package/lib/dependencies/AMDPlugin.js +3 -3
- package/lib/dependencies/ContextDependencyHelpers.js +19 -16
- package/lib/dependencies/CriticalDependencyWarning.js +4 -1
- package/lib/dependencies/DepBlockHelpers.js +3 -3
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -2
- package/lib/dependencies/ImportContextDependency.js +2 -1
- package/lib/dependencies/ImportDependenciesBlock.js +2 -2
- package/lib/dependencies/ImportParserPlugin.js +16 -2
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +11 -3
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +42 -13
- package/lib/dependencies/RequireEnsureDependency.js +9 -2
- package/lib/optimize/AggressiveSplittingPlugin.js +10 -17
- package/lib/optimize/CommonsChunkPlugin.js +1 -1
- package/lib/performance/AssetsOverSizeLimitWarning.js +4 -1
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +5 -1
- package/lib/performance/NoAsyncChunksWarning.js +5 -1
- package/lib/removeAndDo.js +6 -4
- package/lib/util/identifier.js +16 -0
- package/lib/webpack.js +2 -1
- package/package.json +4 -3
- package/schemas/ajv.absolutePath.js +1 -1
- package/schemas/webpackOptionsSchema.json +27 -0
package/lib/Parser.js
CHANGED
@@ -2,1213 +2,1390 @@
|
|
2
2
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
3
|
Author Tobias Koppers @sokra
|
4
4
|
*/
|
5
|
-
|
6
|
-
var Tapable = require("tapable");
|
7
|
-
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
8
|
-
|
9
|
-
function Parser(options) {
|
10
|
-
Tapable.call(this);
|
11
|
-
this.options = options;
|
12
|
-
this.initializeEvaluating();
|
13
|
-
}
|
14
|
-
module.exports = Parser;
|
5
|
+
"use strict";
|
15
6
|
|
16
7
|
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
17
8
|
|
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
|
-
|
9
|
+
const acorn = require("acorn-dynamic-import").default;
|
10
|
+
const Tapable = require("tapable");
|
11
|
+
const json5 = require("json5");
|
12
|
+
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
13
|
+
|
14
|
+
function joinRanges(startRange, endRange) {
|
15
|
+
if(!endRange) return startRange;
|
16
|
+
if(!startRange) return endRange;
|
17
|
+
return [startRange[0], endRange[1]];
|
18
|
+
}
|
19
|
+
|
20
|
+
const POSSIBLE_AST_OPTIONS = [{
|
21
|
+
ranges: true,
|
22
|
+
locations: true,
|
23
|
+
ecmaVersion: 2017,
|
24
|
+
sourceType: "module",
|
25
|
+
plugins: {
|
26
|
+
dynamicImport: true
|
27
|
+
}
|
28
|
+
}, {
|
29
|
+
ranges: true,
|
30
|
+
locations: true,
|
31
|
+
ecmaVersion: 2017,
|
32
|
+
sourceType: "script",
|
33
|
+
plugins: {
|
34
|
+
dynamicImport: true
|
35
|
+
}
|
36
|
+
}];
|
37
|
+
|
38
|
+
class Parser extends Tapable {
|
39
|
+
constructor(options) {
|
40
|
+
super();
|
41
|
+
this.options = options;
|
42
|
+
this.scope = undefined;
|
43
|
+
this.state = undefined;
|
44
|
+
this.comments = undefined;
|
45
|
+
this.initializeEvaluating();
|
46
|
+
}
|
47
|
+
|
48
|
+
initializeEvaluating() {
|
49
|
+
this.plugin("evaluate Literal", expr => {
|
50
|
+
switch(typeof expr.value) {
|
51
|
+
case "number":
|
52
|
+
return new BasicEvaluatedExpression().setNumber(expr.value).setRange(expr.range);
|
53
|
+
case "string":
|
54
|
+
return new BasicEvaluatedExpression().setString(expr.value).setRange(expr.range);
|
55
|
+
case "boolean":
|
56
|
+
return new BasicEvaluatedExpression().setBoolean(expr.value).setRange(expr.range);
|
57
|
+
}
|
58
|
+
if(expr.value === null)
|
59
|
+
return new BasicEvaluatedExpression().setNull().setRange(expr.range);
|
60
|
+
if(expr.value instanceof RegExp)
|
61
|
+
return new BasicEvaluatedExpression().setRegExp(expr.value).setRange(expr.range);
|
62
|
+
});
|
63
|
+
this.plugin("evaluate LogicalExpression", function(expr) {
|
64
|
+
let left;
|
65
|
+
let leftAsBool;
|
66
|
+
let right;
|
67
|
+
if(expr.operator === "&&") {
|
68
|
+
left = this.evaluateExpression(expr.left);
|
69
|
+
leftAsBool = left && left.asBool();
|
70
|
+
if(leftAsBool === false) return left.setRange(expr.range);
|
71
|
+
if(leftAsBool !== true) return;
|
72
|
+
right = this.evaluateExpression(expr.right);
|
73
|
+
return right.setRange(expr.range);
|
74
|
+
} else if(expr.operator === "||") {
|
75
|
+
left = this.evaluateExpression(expr.left);
|
76
|
+
leftAsBool = left && left.asBool();
|
77
|
+
if(leftAsBool === true) return left.setRange(expr.range);
|
78
|
+
if(leftAsBool !== false) return;
|
79
|
+
right = this.evaluateExpression(expr.right);
|
80
|
+
return right.setRange(expr.range);
|
81
|
+
}
|
82
|
+
});
|
83
|
+
this.plugin("evaluate BinaryExpression", function(expr) {
|
84
|
+
let left;
|
85
|
+
let right;
|
86
|
+
let res;
|
87
|
+
if(expr.operator === "+") {
|
88
|
+
left = this.evaluateExpression(expr.left);
|
89
|
+
right = this.evaluateExpression(expr.right);
|
90
|
+
if(!left || !right) return;
|
91
|
+
res = new BasicEvaluatedExpression();
|
92
|
+
if(left.isString()) {
|
93
|
+
if(right.isString()) {
|
94
|
+
res.setString(left.string + right.string);
|
95
|
+
} else if(right.isNumber()) {
|
96
|
+
res.setString(left.string + right.number);
|
97
|
+
} else if(right.isWrapped() && right.prefix && right.prefix.isString()) {
|
98
|
+
res.setWrapped(
|
99
|
+
new BasicEvaluatedExpression()
|
100
|
+
.setString(left.string + right.prefix.string)
|
101
|
+
.setRange(joinRanges(left.range, right.prefix.range)),
|
102
|
+
right.postfix);
|
103
|
+
} else if(right.isWrapped()) {
|
104
|
+
res.setWrapped(
|
105
|
+
new BasicEvaluatedExpression()
|
106
|
+
.setString(left.string)
|
107
|
+
.setRange(left.range),
|
108
|
+
right.postfix);
|
109
|
+
} else {
|
110
|
+
res.setWrapped(left, null);
|
111
|
+
}
|
112
|
+
} else if(left.isNumber()) {
|
113
|
+
if(right.isString()) {
|
114
|
+
res.setString(left.number + right.string);
|
115
|
+
} else if(right.isNumber()) {
|
116
|
+
res.setNumber(left.number + right.number);
|
117
|
+
}
|
118
|
+
} else if(left.isWrapped()) {
|
119
|
+
if(left.postfix && left.postfix.isString() && right.isString()) {
|
120
|
+
res.setWrapped(left.prefix,
|
121
|
+
new BasicEvaluatedExpression()
|
122
|
+
.setString(left.postfix.string + right.string)
|
123
|
+
.setRange(joinRanges(left.postfix.range, right.range))
|
124
|
+
);
|
125
|
+
} else if(left.postfix && left.postfix.isString() && right.isNumber()) {
|
126
|
+
res.setWrapped(left.prefix,
|
127
|
+
new BasicEvaluatedExpression()
|
128
|
+
.setString(left.postfix.string + right.number)
|
129
|
+
.setRange(joinRanges(left.postfix.range, right.range))
|
130
|
+
);
|
131
|
+
} else if(right.isString()) {
|
132
|
+
res.setWrapped(left.prefix, right);
|
133
|
+
} else if(right.isNumber()) {
|
134
|
+
res.setWrapped(left.prefix,
|
135
|
+
new BasicEvaluatedExpression()
|
136
|
+
.setString(right.number + "")
|
137
|
+
.setRange(right.range));
|
138
|
+
} else {
|
139
|
+
res.setWrapped(left.prefix, new BasicEvaluatedExpression());
|
140
|
+
}
|
110
141
|
} else {
|
111
|
-
|
142
|
+
if(right.isString()) {
|
143
|
+
res.setWrapped(null, right);
|
144
|
+
}
|
112
145
|
}
|
113
|
-
|
114
|
-
|
115
|
-
|
146
|
+
res.setRange(expr.range);
|
147
|
+
return res;
|
148
|
+
} else if(expr.operator === "-") {
|
149
|
+
left = this.evaluateExpression(expr.left);
|
150
|
+
right = this.evaluateExpression(expr.right);
|
151
|
+
if(!left || !right) return;
|
152
|
+
if(!left.isNumber() || !right.isNumber()) return;
|
153
|
+
res = new BasicEvaluatedExpression();
|
154
|
+
res.setNumber(left.number - right.number);
|
155
|
+
res.setRange(expr.range);
|
156
|
+
return res;
|
157
|
+
} else if(expr.operator === "*") {
|
158
|
+
left = this.evaluateExpression(expr.left);
|
159
|
+
right = this.evaluateExpression(expr.right);
|
160
|
+
if(!left || !right) return;
|
161
|
+
if(!left.isNumber() || !right.isNumber()) return;
|
162
|
+
res = new BasicEvaluatedExpression();
|
163
|
+
res.setNumber(left.number * right.number);
|
164
|
+
res.setRange(expr.range);
|
165
|
+
return res;
|
166
|
+
} else if(expr.operator === "/") {
|
167
|
+
left = this.evaluateExpression(expr.left);
|
168
|
+
right = this.evaluateExpression(expr.right);
|
169
|
+
if(!left || !right) return;
|
170
|
+
if(!left.isNumber() || !right.isNumber()) return;
|
171
|
+
res = new BasicEvaluatedExpression();
|
172
|
+
res.setNumber(left.number / right.number);
|
173
|
+
res.setRange(expr.range);
|
174
|
+
return res;
|
175
|
+
} else if(expr.operator === "==" || expr.operator === "===") {
|
176
|
+
left = this.evaluateExpression(expr.left);
|
177
|
+
right = this.evaluateExpression(expr.right);
|
178
|
+
if(!left || !right) return;
|
179
|
+
res = new BasicEvaluatedExpression();
|
180
|
+
res.setRange(expr.range);
|
181
|
+
if(left.isString() && right.isString()) {
|
182
|
+
return res.setBoolean(left.string === right.string);
|
183
|
+
} else if(left.isNumber() && right.isNumber()) {
|
184
|
+
return res.setBoolean(left.number === right.number);
|
185
|
+
} else if(left.isBoolean() && right.isBoolean()) {
|
186
|
+
return res.setBoolean(left.bool === right.bool);
|
116
187
|
}
|
117
|
-
}
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
} else if(expr.operator === "*") {
|
130
|
-
left = this.evaluateExpression(expr.left);
|
131
|
-
right = this.evaluateExpression(expr.right);
|
132
|
-
if(!left || !right) return;
|
133
|
-
if(!left.isNumber() || !right.isNumber()) return;
|
134
|
-
res = new BasicEvaluatedExpression();
|
135
|
-
res.setNumber(left.number * right.number);
|
136
|
-
res.setRange(expr.range);
|
137
|
-
return res;
|
138
|
-
} else if(expr.operator === "/") {
|
139
|
-
left = this.evaluateExpression(expr.left);
|
140
|
-
right = this.evaluateExpression(expr.right);
|
141
|
-
if(!left || !right) return;
|
142
|
-
if(!left.isNumber() || !right.isNumber()) return;
|
143
|
-
res = new BasicEvaluatedExpression();
|
144
|
-
res.setNumber(left.number / right.number);
|
145
|
-
res.setRange(expr.range);
|
146
|
-
return res;
|
147
|
-
} else if(expr.operator === "==" || expr.operator === "===") {
|
148
|
-
left = this.evaluateExpression(expr.left);
|
149
|
-
right = this.evaluateExpression(expr.right);
|
150
|
-
if(!left || !right) return;
|
151
|
-
res = new BasicEvaluatedExpression();
|
152
|
-
res.setRange(expr.range);
|
153
|
-
if(left.isString() && right.isString()) {
|
154
|
-
return res.setBoolean(left.string === right.string);
|
155
|
-
} else if(left.isNumber() && right.isNumber()) {
|
156
|
-
return res.setBoolean(left.number === right.number);
|
157
|
-
} else if(left.isBoolean() && right.isBoolean()) {
|
158
|
-
return res.setBoolean(left.bool === right.bool);
|
159
|
-
}
|
160
|
-
} else if(expr.operator === "!=" || expr.operator === "!==") {
|
161
|
-
left = this.evaluateExpression(expr.left);
|
162
|
-
right = this.evaluateExpression(expr.right);
|
163
|
-
if(!left || !right) return;
|
164
|
-
res = new BasicEvaluatedExpression();
|
165
|
-
res.setRange(expr.range);
|
166
|
-
if(left.isString() && right.isString()) {
|
167
|
-
return res.setBoolean(left.string !== right.string);
|
168
|
-
} else if(left.isNumber() && right.isNumber()) {
|
169
|
-
return res.setBoolean(left.number !== right.number);
|
170
|
-
} else if(left.isBoolean() && right.isBoolean()) {
|
171
|
-
return res.setBoolean(left.bool !== right.bool);
|
172
|
-
}
|
173
|
-
}
|
174
|
-
});
|
175
|
-
this.plugin("evaluate UnaryExpression", function(expr) {
|
176
|
-
if(expr.operator === "typeof") {
|
177
|
-
var res;
|
178
|
-
if(expr.argument.type === "Identifier") {
|
179
|
-
var name = this.scope.renames["$" + expr.argument.name] || expr.argument.name;
|
180
|
-
if(this.scope.definitions.indexOf(name) === -1) {
|
181
|
-
res = this.applyPluginsBailResult1("evaluate typeof " + name, expr);
|
182
|
-
if(res !== undefined) return res;
|
188
|
+
} else if(expr.operator === "!=" || expr.operator === "!==") {
|
189
|
+
left = this.evaluateExpression(expr.left);
|
190
|
+
right = this.evaluateExpression(expr.right);
|
191
|
+
if(!left || !right) return;
|
192
|
+
res = new BasicEvaluatedExpression();
|
193
|
+
res.setRange(expr.range);
|
194
|
+
if(left.isString() && right.isString()) {
|
195
|
+
return res.setBoolean(left.string !== right.string);
|
196
|
+
} else if(left.isNumber() && right.isNumber()) {
|
197
|
+
return res.setBoolean(left.number !== right.number);
|
198
|
+
} else if(left.isBoolean() && right.isBoolean()) {
|
199
|
+
return res.setBoolean(left.bool !== right.bool);
|
183
200
|
}
|
184
201
|
}
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
if(expression.type === "Identifier") {
|
193
|
-
exprName.unshift(this.scope.renames["$" + expression.name] || expression.name);
|
202
|
+
});
|
203
|
+
this.plugin("evaluate UnaryExpression", function(expr) {
|
204
|
+
if(expr.operator === "typeof") {
|
205
|
+
let res;
|
206
|
+
let name;
|
207
|
+
if(expr.argument.type === "Identifier") {
|
208
|
+
name = this.scope.renames["$" + expr.argument.name] || expr.argument.name;
|
194
209
|
if(this.scope.definitions.indexOf(name) === -1) {
|
195
|
-
|
196
|
-
res = this.applyPluginsBailResult1("evaluate typeof " + exprName, expr);
|
210
|
+
res = this.applyPluginsBailResult1("evaluate typeof " + name, expr);
|
197
211
|
if(res !== undefined) return res;
|
198
212
|
}
|
199
213
|
}
|
214
|
+
if(expr.argument.type === "MemberExpression") {
|
215
|
+
let expression = expr.argument;
|
216
|
+
let exprName = [];
|
217
|
+
while(expression.type === "MemberExpression" && !expression.computed) {
|
218
|
+
exprName.unshift(this.scope.renames["$" + expression.property.name] || expression.property.name);
|
219
|
+
expression = expression.object;
|
220
|
+
}
|
221
|
+
if(expression.type === "Identifier") {
|
222
|
+
exprName.unshift(this.scope.renames["$" + expression.name] || expression.name);
|
223
|
+
if(this.scope.definitions.indexOf(name) === -1) {
|
224
|
+
exprName = exprName.join(".");
|
225
|
+
res = this.applyPluginsBailResult1("evaluate typeof " + exprName, expr);
|
226
|
+
if(res !== undefined) return res;
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
if(expr.argument.type === "FunctionExpression") {
|
231
|
+
return new BasicEvaluatedExpression().setString("function").setRange(expr.range);
|
232
|
+
}
|
233
|
+
const arg = this.evaluateExpression(expr.argument);
|
234
|
+
if(arg.isString() || arg.isWrapped()) return new BasicEvaluatedExpression().setString("string").setRange(expr.range);
|
235
|
+
else if(arg.isNumber()) return new BasicEvaluatedExpression().setString("number").setRange(expr.range);
|
236
|
+
else if(arg.isBoolean()) return new BasicEvaluatedExpression().setString("boolean").setRange(expr.range);
|
237
|
+
else if(arg.isArray() || arg.isConstArray() || arg.isRegExp()) return new BasicEvaluatedExpression().setString("object").setRange(expr.range);
|
238
|
+
} else if(expr.operator === "!") {
|
239
|
+
const argument = this.evaluateExpression(expr.argument);
|
240
|
+
if(!argument) return;
|
241
|
+
if(argument.isBoolean()) {
|
242
|
+
return new BasicEvaluatedExpression().setBoolean(!argument.bool).setRange(expr.range);
|
243
|
+
} else if(argument.isString()) {
|
244
|
+
return new BasicEvaluatedExpression().setBoolean(!argument.string).setRange(expr.range);
|
245
|
+
} else if(argument.isNumber()) {
|
246
|
+
return new BasicEvaluatedExpression().setBoolean(!argument.number).setRange(expr.range);
|
247
|
+
}
|
200
248
|
}
|
201
|
-
|
202
|
-
|
249
|
+
});
|
250
|
+
this.plugin("evaluate typeof undefined", function(expr) {
|
251
|
+
return new BasicEvaluatedExpression().setString("undefined").setRange(expr.range);
|
252
|
+
});
|
253
|
+
this.plugin("evaluate Identifier", function(expr) {
|
254
|
+
const name = this.scope.renames["$" + expr.name] || expr.name;
|
255
|
+
if(this.scope.definitions.indexOf(expr.name) === -1) {
|
256
|
+
const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr);
|
257
|
+
if(result) return result;
|
258
|
+
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
|
259
|
+
} else {
|
260
|
+
return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr);
|
203
261
|
}
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
if(!argument) return;
|
212
|
-
if(argument.isBoolean()) {
|
213
|
-
return new BasicEvaluatedExpression().setBoolean(!argument.bool).setRange(expr.range);
|
214
|
-
} else if(argument.isString()) {
|
215
|
-
return new BasicEvaluatedExpression().setBoolean(!argument.string).setRange(expr.range);
|
216
|
-
} else if(argument.isNumber()) {
|
217
|
-
return new BasicEvaluatedExpression().setBoolean(!argument.number).setRange(expr.range);
|
262
|
+
});
|
263
|
+
this.plugin("evaluate MemberExpression", function(expression) {
|
264
|
+
let expr = expression;
|
265
|
+
let exprName = [];
|
266
|
+
while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
|
267
|
+
exprName.unshift(expr.property.name || expr.property.value);
|
268
|
+
expr = expr.object;
|
218
269
|
}
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr);
|
232
|
-
}
|
233
|
-
});
|
234
|
-
this.plugin("evaluate MemberExpression", function(expression) {
|
235
|
-
var expr = expression;
|
236
|
-
var exprName = [];
|
237
|
-
while(expr.type === "MemberExpression" &&
|
238
|
-
expr.property.type === (expr.computed ? "Literal" : "Identifier")
|
239
|
-
) {
|
240
|
-
exprName.unshift(expr.property.name || expr.property.value);
|
241
|
-
expr = expr.object;
|
242
|
-
}
|
243
|
-
if(expr.type === "Identifier") {
|
244
|
-
var name = this.scope.renames["$" + expr.name] || expr.name;
|
245
|
-
if(this.scope.definitions.indexOf(name) === -1) {
|
246
|
-
exprName.unshift(name);
|
247
|
-
exprName = exprName.join(".");
|
248
|
-
if(this.scope.definitions.indexOf(expr.name) === -1) {
|
249
|
-
var result = this.applyPluginsBailResult1("evaluate Identifier " + exprName, expression);
|
250
|
-
if(result) return result;
|
251
|
-
return new BasicEvaluatedExpression().setIdentifier(exprName).setRange(expression.range);
|
252
|
-
} else {
|
253
|
-
return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName, expression);
|
270
|
+
if(expr.type === "Identifier") {
|
271
|
+
const name = this.scope.renames["$" + expr.name] || expr.name;
|
272
|
+
if(this.scope.definitions.indexOf(name) === -1) {
|
273
|
+
exprName.unshift(name);
|
274
|
+
exprName = exprName.join(".");
|
275
|
+
if(this.scope.definitions.indexOf(expr.name) === -1) {
|
276
|
+
const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName, expression);
|
277
|
+
if(result) return result;
|
278
|
+
return new BasicEvaluatedExpression().setIdentifier(exprName).setRange(expression.range);
|
279
|
+
} else {
|
280
|
+
return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName, expression);
|
281
|
+
}
|
254
282
|
}
|
255
283
|
}
|
256
|
-
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
this.plugin("evaluate CallExpression .replace", function(expr, param) {
|
267
|
-
if(!param.isString()) return;
|
268
|
-
if(expr.arguments.length !== 2) return;
|
269
|
-
var arg1 = this.evaluateExpression(expr.arguments[0]);
|
270
|
-
var arg2 = this.evaluateExpression(expr.arguments[1]);
|
271
|
-
if(!arg1.isString() && !arg1.isRegExp()) return;
|
272
|
-
arg1 = arg1.regExp || arg1.string;
|
273
|
-
if(!arg2.isString()) return;
|
274
|
-
arg2 = arg2.string;
|
275
|
-
return new BasicEvaluatedExpression().setString(param.string.replace(arg1, arg2)).setRange(expr.range);
|
276
|
-
});
|
277
|
-
["substr", "substring"].forEach(function(fn) {
|
278
|
-
this.plugin("evaluate CallExpression ." + fn, function(expr, param) {
|
284
|
+
});
|
285
|
+
this.plugin("evaluate CallExpression", function(expr) {
|
286
|
+
if(expr.callee.type !== "MemberExpression") return;
|
287
|
+
if(expr.callee.property.type !== (expr.callee.computed ? "Literal" : "Identifier")) return;
|
288
|
+
const param = this.evaluateExpression(expr.callee.object);
|
289
|
+
if(!param) return;
|
290
|
+
const property = expr.callee.property.name || expr.callee.property.value;
|
291
|
+
return this.applyPluginsBailResult("evaluate CallExpression ." + property, expr, param);
|
292
|
+
});
|
293
|
+
this.plugin("evaluate CallExpression .replace", function(expr, param) {
|
279
294
|
if(!param.isString()) return;
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
case 2:
|
289
|
-
arg1 = this.evaluateExpression(expr.arguments[0]);
|
290
|
-
var arg2 = this.evaluateExpression(expr.arguments[1]);
|
291
|
-
if(!arg1.isNumber()) return;
|
292
|
-
if(!arg2.isNumber()) return;
|
293
|
-
result = str[fn](arg1.number, arg2.number);
|
294
|
-
break;
|
295
|
-
default:
|
296
|
-
return;
|
297
|
-
}
|
298
|
-
return new BasicEvaluatedExpression().setString(result).setRange(expr.range);
|
295
|
+
if(expr.arguments.length !== 2) return;
|
296
|
+
let arg1 = this.evaluateExpression(expr.arguments[0]);
|
297
|
+
let arg2 = this.evaluateExpression(expr.arguments[1]);
|
298
|
+
if(!arg1.isString() && !arg1.isRegExp()) return;
|
299
|
+
arg1 = arg1.regExp || arg1.string;
|
300
|
+
if(!arg2.isString()) return;
|
301
|
+
arg2 = arg2.string;
|
302
|
+
return new BasicEvaluatedExpression().setString(param.string.replace(arg1, arg2)).setRange(expr.range);
|
299
303
|
});
|
304
|
+
["substr", "substring"].forEach(fn => {
|
305
|
+
this.plugin("evaluate CallExpression ." + fn, function(expr, param) {
|
306
|
+
if(!param.isString()) return;
|
307
|
+
let arg1;
|
308
|
+
let result, str = param.string;
|
309
|
+
switch(expr.arguments.length) {
|
310
|
+
case 1:
|
311
|
+
arg1 = this.evaluateExpression(expr.arguments[0]);
|
312
|
+
if(!arg1.isNumber()) return;
|
313
|
+
result = str[fn](arg1.number);
|
314
|
+
break;
|
315
|
+
case 2:
|
316
|
+
{
|
317
|
+
arg1 = this.evaluateExpression(expr.arguments[0]);
|
318
|
+
const arg2 = this.evaluateExpression(expr.arguments[1]);
|
319
|
+
if(!arg1.isNumber()) return;
|
320
|
+
if(!arg2.isNumber()) return;
|
321
|
+
result = str[fn](arg1.number, arg2.number);
|
322
|
+
break;
|
323
|
+
}
|
324
|
+
default:
|
325
|
+
return;
|
326
|
+
}
|
327
|
+
return new BasicEvaluatedExpression().setString(result).setRange(expr.range);
|
328
|
+
});
|
300
329
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
330
|
+
/**
|
331
|
+
* @param {string} kind "cooked" | "raw"
|
332
|
+
* @param {any[]} quasis quasis
|
333
|
+
* @param {any[]} expressions expressions
|
334
|
+
* @return {BasicEvaluatedExpression[]} Simplified template
|
335
|
+
*/
|
336
|
+
function getSimplifiedTemplateResult(kind, quasis, expressions) {
|
337
|
+
const parts = [];
|
338
|
+
|
339
|
+
for(let i = 0; i < quasis.length; i++) {
|
340
|
+
parts.push(new BasicEvaluatedExpression().setString(quasis[i].value[kind]).setRange(quasis[i].range));
|
341
|
+
|
342
|
+
if(i > 0) {
|
343
|
+
const prevExpr = parts[parts.length - 2],
|
344
|
+
lastExpr = parts[parts.length - 1];
|
345
|
+
const expr = this.evaluateExpression(expressions[i - 1]);
|
346
|
+
if(!(expr.isString() || expr.isNumber())) continue;
|
347
|
+
|
348
|
+
prevExpr.setString(prevExpr.string + (expr.isString() ? expr.string : expr.number) + lastExpr.string);
|
349
|
+
prevExpr.setRange([prevExpr.range[0], lastExpr.range[1]]);
|
350
|
+
parts.pop();
|
351
|
+
}
|
323
352
|
}
|
353
|
+
return parts;
|
324
354
|
}
|
325
|
-
return parts;
|
326
|
-
}
|
327
355
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
356
|
+
this.plugin("evaluate TemplateLiteral", function(node) {
|
357
|
+
const parts = getSimplifiedTemplateResult.call(this, "cooked", node.quasis, node.expressions);
|
358
|
+
if(parts.length === 1) {
|
359
|
+
return parts[0].setRange(node.range);
|
360
|
+
}
|
361
|
+
return new BasicEvaluatedExpression().setTemplateString(parts).setRange(node.range);
|
362
|
+
});
|
363
|
+
this.plugin("evaluate TaggedTemplateExpression", function(node) {
|
364
|
+
if(this.evaluateExpression(node.tag).identifier !== "String.raw") return;
|
365
|
+
const parts = getSimplifiedTemplateResult.call(this, "raw", node.quasi.quasis, node.quasi.expressions);
|
366
|
+
return new BasicEvaluatedExpression().setTemplateString(parts).setRange(node.range);
|
367
|
+
});
|
368
|
+
});
|
369
|
+
this.plugin("evaluate CallExpression .split", function(expr, param) {
|
370
|
+
if(!param.isString()) return;
|
371
|
+
if(expr.arguments.length !== 1) return;
|
372
|
+
let result;
|
373
|
+
const arg = this.evaluateExpression(expr.arguments[0]);
|
374
|
+
if(arg.isString()) {
|
375
|
+
result = param.string.split(arg.string);
|
376
|
+
} else if(arg.isRegExp()) {
|
377
|
+
result = param.string.split(arg.regExp);
|
378
|
+
} else return;
|
379
|
+
return new BasicEvaluatedExpression().setArray(result).setRange(expr.range);
|
380
|
+
});
|
381
|
+
this.plugin("evaluate ConditionalExpression", function(expr) {
|
382
|
+
const condition = this.evaluateExpression(expr.test);
|
383
|
+
const conditionValue = condition.asBool();
|
384
|
+
let res;
|
385
|
+
if(conditionValue === undefined) {
|
386
|
+
const consequent = this.evaluateExpression(expr.consequent);
|
387
|
+
const alternate = this.evaluateExpression(expr.alternate);
|
388
|
+
if(!consequent || !alternate) return;
|
389
|
+
res = new BasicEvaluatedExpression();
|
390
|
+
if(consequent.isConditional())
|
391
|
+
res.setOptions(consequent.options);
|
392
|
+
else
|
393
|
+
res.setOptions([consequent]);
|
394
|
+
if(alternate.isConditional())
|
395
|
+
res.addOptions(alternate.options);
|
396
|
+
else
|
397
|
+
res.addOptions([alternate]);
|
398
|
+
} else {
|
399
|
+
res = this.evaluateExpression(conditionValue ? expr.consequent : expr.alternate);
|
332
400
|
}
|
333
|
-
|
401
|
+
res.setRange(expr.range);
|
402
|
+
return res;
|
334
403
|
});
|
335
|
-
this.plugin("evaluate
|
336
|
-
|
337
|
-
|
338
|
-
|
404
|
+
this.plugin("evaluate ArrayExpression", function(expr) {
|
405
|
+
const items = expr.elements.map(function(element) {
|
406
|
+
return element !== null && this.evaluateExpression(element);
|
407
|
+
}, this);
|
408
|
+
if(!items.every(Boolean)) return;
|
409
|
+
return new BasicEvaluatedExpression().setItems(items).setRange(expr.range);
|
339
410
|
});
|
340
|
-
}
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
if(conditionValue === undefined) {
|
358
|
-
var consequent = this.evaluateExpression(expr.consequent);
|
359
|
-
var alternate = this.evaluateExpression(expr.alternate);
|
360
|
-
if(!consequent || !alternate) return;
|
361
|
-
res = new BasicEvaluatedExpression();
|
362
|
-
if(consequent.isConditional())
|
363
|
-
res.setOptions(consequent.options);
|
364
|
-
else
|
365
|
-
res.setOptions([consequent]);
|
366
|
-
if(alternate.isConditional())
|
367
|
-
res.addOptions(alternate.options);
|
368
|
-
else
|
369
|
-
res.addOptions([alternate]);
|
370
|
-
} else {
|
371
|
-
res = this.evaluateExpression(conditionValue ? expr.consequent : expr.alternate);
|
411
|
+
}
|
412
|
+
|
413
|
+
getRenameIdentifier(expr) {
|
414
|
+
const result = this.evaluateExpression(expr);
|
415
|
+
if(!result) return;
|
416
|
+
if(result.isIdentifier()) return result.identifier;
|
417
|
+
return;
|
418
|
+
}
|
419
|
+
|
420
|
+
walkClass(classy) {
|
421
|
+
if(classy.superClass)
|
422
|
+
this.walkExpression(classy.superClass);
|
423
|
+
if(classy.body && classy.body.type === "ClassBody") {
|
424
|
+
classy.body.body.forEach(methodDefinition => {
|
425
|
+
if(methodDefinition.type === "MethodDefinition")
|
426
|
+
this.walkMethodDefinition(methodDefinition);
|
427
|
+
});
|
372
428
|
}
|
373
|
-
res.setRange(expr.range);
|
374
|
-
return res;
|
375
|
-
});
|
376
|
-
this.plugin("evaluate ArrayExpression", function(expr) {
|
377
|
-
var items = expr.elements.map(function(element) {
|
378
|
-
return element !== null && this.evaluateExpression(element);
|
379
|
-
}, this);
|
380
|
-
if(!items.every(Boolean)) return;
|
381
|
-
return new BasicEvaluatedExpression().setItems(items).setRange(expr.range);
|
382
|
-
});
|
383
|
-
};
|
384
|
-
|
385
|
-
Parser.prototype.getRenameIdentifier = function getRenameIdentifier(expr) {
|
386
|
-
var result = this.evaluateExpression(expr);
|
387
|
-
if(!result) return;
|
388
|
-
if(result.isIdentifier()) return result.identifier;
|
389
|
-
return;
|
390
|
-
};
|
391
|
-
|
392
|
-
Parser.prototype.walkClass = function walkClass(classy) {
|
393
|
-
if(classy.superClass)
|
394
|
-
this.walkExpression(classy.superClass);
|
395
|
-
if(classy.body && classy.body.type === "ClassBody") {
|
396
|
-
classy.body.body.forEach(function(methodDefinition) {
|
397
|
-
if(methodDefinition.type === "MethodDefinition")
|
398
|
-
this.walkMethodDefinition(methodDefinition);
|
399
|
-
}, this);
|
400
429
|
}
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
}
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
}
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
this.
|
430
|
+
|
431
|
+
walkMethodDefinition(methodDefinition) {
|
432
|
+
if(methodDefinition.computed && methodDefinition.key)
|
433
|
+
this.walkExpression(methodDefinition.key);
|
434
|
+
if(methodDefinition.value)
|
435
|
+
this.walkExpression(methodDefinition.value);
|
436
|
+
}
|
437
|
+
|
438
|
+
// Prewalking iterates the scope for variable declarations
|
439
|
+
prewalkStatements(statements) {
|
440
|
+
for(let index = 0, len = statements.length; index < len; index++) {
|
441
|
+
const statement = statements[index];
|
442
|
+
this.prewalkStatement(statement);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
// Walking iterates the statements and expressions and processes them
|
447
|
+
walkStatements(statements) {
|
448
|
+
for(let index = 0, len = statements.length; index < len; index++) {
|
449
|
+
const statement = statements[index];
|
450
|
+
this.walkStatement(statement);
|
451
|
+
}
|
452
|
+
}
|
453
|
+
|
454
|
+
prewalkStatement(statement) {
|
455
|
+
const handler = this["prewalk" + statement.type];
|
456
|
+
if(handler)
|
457
|
+
handler.call(this, statement);
|
458
|
+
}
|
459
|
+
|
460
|
+
walkStatement(statement) {
|
461
|
+
if(this.applyPluginsBailResult1("statement", statement) !== undefined) return;
|
462
|
+
const handler = this["walk" + statement.type];
|
463
|
+
if(handler)
|
464
|
+
handler.call(this, statement);
|
465
|
+
}
|
466
|
+
|
467
|
+
// Real Statements
|
468
|
+
prewalkBlockStatement(statement) {
|
469
|
+
this.prewalkStatements(statement.body);
|
470
|
+
}
|
471
|
+
|
472
|
+
walkBlockStatement(statement) {
|
473
|
+
this.walkStatements(statement.body);
|
474
|
+
}
|
475
|
+
|
476
|
+
walkExpressionStatement(statement) {
|
477
|
+
this.walkExpression(statement.expression);
|
478
|
+
}
|
479
|
+
|
480
|
+
prewalkIfStatement(statement) {
|
481
|
+
this.prewalkStatement(statement.consequent);
|
453
482
|
if(statement.alternate)
|
454
|
-
this.
|
455
|
-
}
|
456
|
-
|
483
|
+
this.prewalkStatement(statement.alternate);
|
484
|
+
}
|
485
|
+
|
486
|
+
walkIfStatement(statement) {
|
487
|
+
const result = this.applyPluginsBailResult1("statement if", statement);
|
488
|
+
if(result === undefined) {
|
489
|
+
this.walkExpression(statement.test);
|
457
490
|
this.walkStatement(statement.consequent);
|
458
|
-
|
459
|
-
|
491
|
+
if(statement.alternate)
|
492
|
+
this.walkStatement(statement.alternate);
|
493
|
+
} else {
|
494
|
+
if(result)
|
495
|
+
this.walkStatement(statement.consequent);
|
496
|
+
else if(statement.alternate)
|
497
|
+
this.walkStatement(statement.alternate);
|
498
|
+
}
|
499
|
+
}
|
500
|
+
|
501
|
+
prewalkLabeledStatement(statement) {
|
502
|
+
this.prewalkStatement(statement.body);
|
460
503
|
}
|
461
|
-
};
|
462
504
|
|
463
|
-
|
464
|
-
|
465
|
-
|
505
|
+
walkLabeledStatement(statement) {
|
506
|
+
const result = this.applyPluginsBailResult1("label " + statement.label.name, statement);
|
507
|
+
if(result !== true)
|
508
|
+
this.walkStatement(statement.body);
|
509
|
+
}
|
510
|
+
|
511
|
+
prewalkWithStatement(statement) {
|
512
|
+
this.prewalkStatement(statement.body);
|
513
|
+
}
|
514
|
+
|
515
|
+
walkWithStatement(statement) {
|
516
|
+
this.walkExpression(statement.object);
|
466
517
|
this.walkStatement(statement.body);
|
467
|
-
}
|
518
|
+
}
|
468
519
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
};
|
520
|
+
prewalkSwitchStatement(statement) {
|
521
|
+
this.prewalkSwitchCases(statement.cases);
|
522
|
+
}
|
473
523
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
}
|
524
|
+
walkSwitchStatement(statement) {
|
525
|
+
this.walkExpression(statement.discriminant);
|
526
|
+
this.walkSwitchCases(statement.cases);
|
527
|
+
}
|
478
528
|
|
479
|
-
|
480
|
-
Parser.prototype.walkThrowStatement = function walkArgumentStatement(statement) {
|
529
|
+
walkTerminatingStatement(statement) {
|
481
530
|
if(statement.argument)
|
482
531
|
this.walkExpression(statement.argument);
|
483
|
-
}
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
this.
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
this.
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
532
|
+
}
|
533
|
+
|
534
|
+
walkReturnStatement(statement) {
|
535
|
+
this.walkTerminatingStatement(statement);
|
536
|
+
}
|
537
|
+
|
538
|
+
walkThrowStatement(statement) {
|
539
|
+
this.walkTerminatingStatement(statement);
|
540
|
+
}
|
541
|
+
|
542
|
+
prewalkTryStatement(statement) {
|
543
|
+
this.prewalkStatement(statement.block);
|
544
|
+
}
|
545
|
+
|
546
|
+
walkTryStatement(statement) {
|
547
|
+
if(this.scope.inTry) {
|
548
|
+
this.walkStatement(statement.block);
|
549
|
+
} else {
|
550
|
+
this.scope.inTry = true;
|
551
|
+
this.walkStatement(statement.block);
|
552
|
+
this.scope.inTry = false;
|
553
|
+
}
|
554
|
+
if(statement.handler)
|
555
|
+
this.walkCatchClause(statement.handler);
|
556
|
+
if(statement.finalizer)
|
557
|
+
this.walkStatement(statement.finalizer);
|
558
|
+
}
|
559
|
+
|
560
|
+
prewalkWhileStatement(statement) {
|
561
|
+
this.prewalkStatement(statement.body);
|
562
|
+
}
|
563
|
+
|
564
|
+
walkWhileStatement(statement) {
|
501
565
|
this.walkExpression(statement.test);
|
502
566
|
this.walkStatement(statement.body);
|
503
|
-
}
|
567
|
+
}
|
504
568
|
|
505
|
-
|
506
|
-
|
507
|
-
if(statement.init.type === "VariableDeclaration")
|
508
|
-
this.walkStatement(statement.init);
|
509
|
-
else
|
510
|
-
this.walkExpression(statement.init);
|
569
|
+
prewalkDoWhileStatement(statement) {
|
570
|
+
this.prewalkStatement(statement.body);
|
511
571
|
}
|
512
|
-
|
572
|
+
|
573
|
+
walkDoWhileStatement(statement) {
|
574
|
+
this.walkStatement(statement.body);
|
513
575
|
this.walkExpression(statement.test);
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
this.
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
576
|
+
}
|
577
|
+
|
578
|
+
prewalkForStatement(statement) {
|
579
|
+
if(statement.init) {
|
580
|
+
if(statement.init.type === "VariableDeclaration")
|
581
|
+
this.prewalkStatement(statement.init);
|
582
|
+
}
|
583
|
+
this.prewalkStatement(statement.body);
|
584
|
+
}
|
585
|
+
|
586
|
+
walkForStatement(statement) {
|
587
|
+
if(statement.init) {
|
588
|
+
if(statement.init.type === "VariableDeclaration")
|
589
|
+
this.walkStatement(statement.init);
|
590
|
+
else
|
591
|
+
this.walkExpression(statement.init);
|
592
|
+
}
|
593
|
+
if(statement.test)
|
594
|
+
this.walkExpression(statement.test);
|
595
|
+
if(statement.update)
|
596
|
+
this.walkExpression(statement.update);
|
597
|
+
this.walkStatement(statement.body);
|
598
|
+
}
|
599
|
+
|
600
|
+
prewalkForInStatement(statement) {
|
601
|
+
if(statement.left.type === "VariableDeclaration")
|
602
|
+
this.prewalkStatement(statement.left);
|
603
|
+
this.prewalkStatement(statement.body);
|
604
|
+
}
|
605
|
+
|
606
|
+
walkForInStatement(statement) {
|
607
|
+
if(statement.left.type === "VariableDeclaration")
|
608
|
+
this.walkStatement(statement.left);
|
544
609
|
else
|
545
|
-
this.walkExpression(statement.
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
610
|
+
this.walkExpression(statement.left);
|
611
|
+
this.walkExpression(statement.right);
|
612
|
+
this.walkStatement(statement.body);
|
613
|
+
}
|
614
|
+
|
615
|
+
prewalkForOfStatement(statement) {
|
616
|
+
if(statement.left.type === "VariableDeclaration")
|
617
|
+
this.prewalkStatement(statement.left);
|
618
|
+
this.prewalkStatement(statement.body);
|
619
|
+
}
|
620
|
+
|
621
|
+
walkForOfStatement(statement) {
|
622
|
+
if(statement.left.type === "VariableDeclaration")
|
623
|
+
this.walkStatement(statement.left);
|
624
|
+
else
|
625
|
+
this.walkExpression(statement.left);
|
626
|
+
this.walkExpression(statement.right);
|
627
|
+
this.walkStatement(statement.body);
|
628
|
+
}
|
629
|
+
|
630
|
+
// Declarations
|
631
|
+
prewalkFunctionDeclaration(statement) {
|
632
|
+
if(statement.id) {
|
633
|
+
this.scope.renames["$" + statement.id.name] = undefined;
|
634
|
+
this.scope.definitions.push(statement.id.name);
|
566
635
|
}
|
567
|
-
}
|
568
|
-
};
|
636
|
+
}
|
569
637
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
638
|
+
walkFunctionDeclaration(statement) {
|
639
|
+
this.inScope(statement.params, function() {
|
640
|
+
if(statement.body.type === "BlockStatement") {
|
641
|
+
this.prewalkStatement(statement.body);
|
642
|
+
this.walkStatement(statement.body);
|
643
|
+
} else {
|
644
|
+
this.walkExpression(statement.body);
|
645
|
+
}
|
646
|
+
}.bind(this));
|
576
647
|
}
|
577
|
-
|
578
|
-
|
579
|
-
|
648
|
+
|
649
|
+
prewalkImportDeclaration(statement) {
|
650
|
+
const source = statement.source.value;
|
651
|
+
this.applyPluginsBailResult("import", statement, source);
|
652
|
+
statement.specifiers.forEach(function(specifier) {
|
653
|
+
const name = specifier.local.name;
|
654
|
+
this.scope.renames["$" + name] = undefined;
|
655
|
+
this.scope.definitions.push(name);
|
656
|
+
switch(specifier.type) {
|
657
|
+
case "ImportDefaultSpecifier":
|
658
|
+
this.applyPluginsBailResult("import specifier", statement, source, "default", name);
|
659
|
+
break;
|
660
|
+
case "ImportSpecifier":
|
661
|
+
this.applyPluginsBailResult("import specifier", statement, source, specifier.imported.name, name);
|
662
|
+
break;
|
663
|
+
case "ImportNamespaceSpecifier":
|
664
|
+
this.applyPluginsBailResult("import specifier", statement, source, null, name);
|
665
|
+
break;
|
666
|
+
}
|
667
|
+
}, this);
|
668
|
+
}
|
669
|
+
|
670
|
+
prewalkExportNamedDeclaration(statement) {
|
671
|
+
let source;
|
672
|
+
if(statement.source) {
|
673
|
+
source = statement.source.value;
|
674
|
+
this.applyPluginsBailResult("export import", statement, source);
|
580
675
|
} else {
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
676
|
+
this.applyPluginsBailResult1("export", statement);
|
677
|
+
}
|
678
|
+
if(statement.declaration) {
|
679
|
+
if(/Expression$/.test(statement.declaration.type)) {
|
680
|
+
throw new Error("Doesn't occur?");
|
681
|
+
} else {
|
682
|
+
if(!this.applyPluginsBailResult("export declaration", statement, statement.declaration)) {
|
683
|
+
const pos = this.scope.definitions.length;
|
684
|
+
this.prewalkStatement(statement.declaration);
|
685
|
+
const newDefs = this.scope.definitions.slice(pos);
|
686
|
+
for(let index = newDefs.length - 1; index >= 0; index--) {
|
687
|
+
const def = newDefs[index];
|
688
|
+
this.applyPluginsBailResult("export specifier", statement, def, def, index);
|
689
|
+
}
|
588
690
|
}
|
589
691
|
}
|
590
692
|
}
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
693
|
+
if(statement.specifiers) {
|
694
|
+
for(let specifierIndex = 0; specifierIndex < statement.specifiers.length; specifierIndex++) {
|
695
|
+
const specifier = statement.specifiers[specifierIndex];
|
696
|
+
switch(specifier.type) {
|
697
|
+
case "ExportSpecifier":
|
698
|
+
{
|
699
|
+
const name = specifier.exported.name;
|
700
|
+
if(source)
|
701
|
+
this.applyPluginsBailResult("export import specifier", statement, source, specifier.local.name, name, specifierIndex);
|
702
|
+
else
|
703
|
+
this.applyPluginsBailResult("export specifier", statement, specifier.local.name, name, specifierIndex);
|
704
|
+
break;
|
705
|
+
}
|
706
|
+
}
|
603
707
|
}
|
604
708
|
}
|
605
709
|
}
|
606
|
-
};
|
607
710
|
|
608
|
-
|
609
|
-
|
610
|
-
if(/Declaration$/.test(statement.declaration.type)) {
|
611
|
-
if(!this.applyPluginsBailResult("export declaration", statement, statement.declaration)) {
|
612
|
-
var pos = this.scope.definitions.length;
|
711
|
+
walkExportNamedDeclaration(statement) {
|
712
|
+
if(statement.declaration) {
|
613
713
|
this.walkStatement(statement.declaration);
|
614
|
-
|
615
|
-
|
616
|
-
|
714
|
+
}
|
715
|
+
}
|
716
|
+
|
717
|
+
prewalkExportDefaultDeclaration(statement) {
|
718
|
+
if(/Declaration$/.test(statement.declaration.type)) {
|
719
|
+
const pos = this.scope.definitions.length;
|
720
|
+
this.prewalkStatement(statement.declaration);
|
721
|
+
const newDefs = this.scope.definitions.slice(pos);
|
722
|
+
for(let index = 0, len = newDefs.length; index < len; index++) {
|
723
|
+
const def = newDefs[index];
|
617
724
|
this.applyPluginsBailResult("export specifier", statement, def, "default");
|
618
725
|
}
|
619
726
|
}
|
620
|
-
}
|
621
|
-
|
622
|
-
|
623
|
-
|
727
|
+
}
|
728
|
+
|
729
|
+
walkExportDefaultDeclaration(statement) {
|
730
|
+
this.applyPluginsBailResult1("export", statement);
|
731
|
+
if(/Declaration$/.test(statement.declaration.type)) {
|
732
|
+
if(!this.applyPluginsBailResult("export declaration", statement, statement.declaration)) {
|
733
|
+
this.walkStatement(statement.declaration);
|
734
|
+
}
|
735
|
+
} else {
|
736
|
+
this.walkExpression(statement.declaration);
|
737
|
+
if(!this.applyPluginsBailResult("export expression", statement, statement.declaration)) {
|
738
|
+
this.applyPluginsBailResult("export specifier", statement, statement.declaration, "default");
|
739
|
+
}
|
624
740
|
}
|
625
741
|
}
|
626
|
-
};
|
627
742
|
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
}
|
743
|
+
prewalkExportAllDeclaration(statement) {
|
744
|
+
const source = statement.source.value;
|
745
|
+
this.applyPluginsBailResult("export import", statement, source);
|
746
|
+
this.applyPluginsBailResult("export import specifier", statement, source, null, null, 0);
|
747
|
+
}
|
748
|
+
|
749
|
+
prewalkVariableDeclaration(statement) {
|
750
|
+
if(statement.declarations)
|
751
|
+
this.prewalkVariableDeclarators(statement.declarations);
|
752
|
+
}
|
753
|
+
|
754
|
+
walkVariableDeclaration(statement) {
|
755
|
+
if(statement.declarations)
|
756
|
+
this.walkVariableDeclarators(statement.declarations);
|
757
|
+
}
|
758
|
+
|
759
|
+
prewalkClassDeclaration(statement) {
|
760
|
+
if(statement.id) {
|
761
|
+
this.scope.renames["$" + statement.id.name] = undefined;
|
762
|
+
this.scope.definitions.push(statement.id.name);
|
763
|
+
}
|
764
|
+
}
|
633
765
|
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
};
|
766
|
+
walkClassDeclaration(statement) {
|
767
|
+
this.walkClass(statement);
|
768
|
+
}
|
638
769
|
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
}
|
770
|
+
prewalkSwitchCases(switchCases) {
|
771
|
+
for(let index = 0, len = switchCases.length; index < len; index++) {
|
772
|
+
const switchCase = switchCases[index];
|
773
|
+
this.prewalkStatements(switchCase.consequent);
|
774
|
+
}
|
775
|
+
}
|
644
776
|
|
645
|
-
|
646
|
-
|
647
|
-
|
777
|
+
walkSwitchCases(switchCases) {
|
778
|
+
for(let index = 0, len = switchCases.length; index < len; index++) {
|
779
|
+
const switchCase = switchCases[index];
|
648
780
|
|
649
|
-
|
650
|
-
|
781
|
+
if(switchCase.test) {
|
782
|
+
this.walkExpression(switchCase.test);
|
783
|
+
}
|
784
|
+
this.walkStatements(switchCase.consequent);
|
651
785
|
}
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
786
|
+
}
|
787
|
+
|
788
|
+
walkCatchClause(catchClause) {
|
789
|
+
this.inScope([catchClause.param], function() {
|
790
|
+
this.prewalkStatement(catchClause.body);
|
791
|
+
this.walkStatement(catchClause.body);
|
792
|
+
}.bind(this));
|
793
|
+
}
|
794
|
+
|
795
|
+
prewalkVariableDeclarators(declarators) {
|
796
|
+
declarators.forEach(declarator => {
|
797
|
+
switch(declarator.type) {
|
798
|
+
case "VariableDeclarator":
|
799
|
+
{
|
800
|
+
const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);
|
801
|
+
if(renameIdentifier && declarator.id.type === "Identifier" && this.applyPluginsBailResult1("can-rename " + renameIdentifier, declarator.init)) {
|
802
|
+
// renaming with "var a = b;"
|
803
|
+
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, declarator.init)) {
|
804
|
+
this.scope.renames["$" + declarator.id.name] = this.scope.renames["$" + renameIdentifier] || renameIdentifier;
|
805
|
+
const idx = this.scope.definitions.indexOf(declarator.id.name);
|
806
|
+
if(idx >= 0) this.scope.definitions.splice(idx, 1);
|
807
|
+
}
|
808
|
+
} else {
|
809
|
+
this.enterPattern(declarator.id, (name, decl) => {
|
810
|
+
if(!this.applyPluginsBailResult1("var-" + declarator.kind + " " + name, decl)) {
|
811
|
+
if(!this.applyPluginsBailResult1("var " + name, decl)) {
|
812
|
+
this.scope.renames["$" + name] = undefined;
|
813
|
+
this.scope.definitions.push(name);
|
814
|
+
}
|
815
|
+
}
|
816
|
+
});
|
817
|
+
}
|
818
|
+
break;
|
676
819
|
}
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
820
|
+
}
|
821
|
+
});
|
822
|
+
}
|
823
|
+
|
824
|
+
walkVariableDeclarators(declarators) {
|
825
|
+
declarators.forEach(declarator => {
|
826
|
+
switch(declarator.type) {
|
827
|
+
case "VariableDeclarator":
|
828
|
+
{
|
829
|
+
const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);
|
830
|
+
if(!renameIdentifier || declarator.id.type !== "Identifier" || !this.applyPluginsBailResult1("can-rename " + renameIdentifier, declarator.init)) {
|
831
|
+
this.walkPattern(declarator.id);
|
832
|
+
if(declarator.init)
|
833
|
+
this.walkExpression(declarator.init);
|
683
834
|
}
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
835
|
+
break;
|
836
|
+
}
|
837
|
+
}
|
838
|
+
});
|
839
|
+
}
|
840
|
+
|
841
|
+
walkPattern(pattern) {
|
842
|
+
if(pattern.type === "Identifier")
|
843
|
+
return;
|
844
|
+
if(this["walk" + pattern.type])
|
845
|
+
this["walk" + pattern.type](pattern);
|
846
|
+
}
|
847
|
+
|
848
|
+
walkObjectPattern(pattern) {
|
849
|
+
for(let i = 0, len = pattern.properties.length; i < len; i++) {
|
850
|
+
const prop = pattern.properties[i];
|
851
|
+
if(prop) {
|
852
|
+
if(prop.computed)
|
853
|
+
this.walkExpression(prop.key);
|
854
|
+
if(prop.value)
|
855
|
+
this.walkPattern(prop.value);
|
856
|
+
}
|
689
857
|
}
|
690
|
-
}
|
691
|
-
};
|
858
|
+
}
|
692
859
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
}
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
860
|
+
walkArrayPattern(pattern) {
|
861
|
+
for(let i = 0, len = pattern.elements.length; i < len; i++) {
|
862
|
+
const element = pattern.elements[i];
|
863
|
+
if(element)
|
864
|
+
this.walkPattern(element);
|
865
|
+
}
|
866
|
+
}
|
867
|
+
|
868
|
+
walkRestElement(pattern) {
|
869
|
+
this.walkPattern(pattern.argument);
|
870
|
+
}
|
871
|
+
|
872
|
+
walkExpressions(expressions) {
|
873
|
+
for(let expressionsIndex = 0, len = expressions.length; expressionsIndex < len; expressionsIndex++) {
|
874
|
+
const expression = expressions[expressionsIndex];
|
875
|
+
if(expression)
|
876
|
+
this.walkExpression(expression);
|
877
|
+
}
|
878
|
+
}
|
879
|
+
|
880
|
+
walkExpression(expression) {
|
881
|
+
if(this["walk" + expression.type])
|
882
|
+
return this["walk" + expression.type](expression);
|
883
|
+
}
|
884
|
+
|
885
|
+
walkAwaitExpression(expression) {
|
886
|
+
const argument = expression.argument;
|
887
|
+
if(this["walk" + argument.type])
|
888
|
+
return this["walk" + argument.type](argument);
|
889
|
+
}
|
890
|
+
|
891
|
+
walkArrayExpression(expression) {
|
892
|
+
if(expression.elements)
|
893
|
+
this.walkExpressions(expression.elements);
|
894
|
+
}
|
895
|
+
|
896
|
+
walkSpreadElement(expression) {
|
897
|
+
if(expression.argument)
|
898
|
+
this.walkExpression(expression.argument);
|
899
|
+
}
|
900
|
+
|
901
|
+
walkObjectExpression(expression) {
|
902
|
+
for(let propIndex = 0, len = expression.properties.length; propIndex < len; propIndex++) {
|
903
|
+
const prop = expression.properties[propIndex];
|
704
904
|
if(prop.computed)
|
705
905
|
this.walkExpression(prop.key);
|
706
|
-
if(prop.
|
707
|
-
this.
|
906
|
+
if(prop.shorthand)
|
907
|
+
this.scope.inShorthand = true;
|
908
|
+
this.walkExpression(prop.value);
|
909
|
+
if(prop.shorthand)
|
910
|
+
this.scope.inShorthand = false;
|
911
|
+
}
|
912
|
+
}
|
913
|
+
|
914
|
+
walkFunctionExpression(expression) {
|
915
|
+
this.inScope(expression.params, function() {
|
916
|
+
if(expression.body.type === "BlockStatement") {
|
917
|
+
this.prewalkStatement(expression.body);
|
918
|
+
this.walkStatement(expression.body);
|
919
|
+
} else {
|
920
|
+
this.walkExpression(expression.body);
|
921
|
+
}
|
922
|
+
}.bind(this));
|
923
|
+
}
|
924
|
+
|
925
|
+
walkArrowFunctionExpression(expression) {
|
926
|
+
this.inScope(expression.params, function() {
|
927
|
+
if(expression.body.type === "BlockStatement") {
|
928
|
+
this.prewalkStatement(expression.body);
|
929
|
+
this.walkStatement(expression.body);
|
930
|
+
} else {
|
931
|
+
this.walkExpression(expression.body);
|
932
|
+
}
|
933
|
+
}.bind(this));
|
934
|
+
}
|
935
|
+
|
936
|
+
walkSequenceExpression(expression) {
|
937
|
+
if(expression.expressions)
|
938
|
+
this.walkExpressions(expression.expressions);
|
939
|
+
}
|
940
|
+
|
941
|
+
walkUpdateExpression(expression) {
|
942
|
+
this.walkExpression(expression.argument);
|
943
|
+
}
|
944
|
+
|
945
|
+
walkUnaryExpression(expression) {
|
946
|
+
if(expression.operator === "typeof") {
|
947
|
+
let expr = expression.argument;
|
948
|
+
let exprName = [];
|
949
|
+
while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
|
950
|
+
exprName.unshift(expr.property.name || expr.property.value);
|
951
|
+
expr = expr.object;
|
952
|
+
}
|
953
|
+
if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) {
|
954
|
+
exprName.unshift(this.scope.renames["$" + expr.name] || expr.name);
|
955
|
+
exprName = exprName.join(".");
|
956
|
+
const result = this.applyPluginsBailResult1("typeof " + exprName, expression);
|
957
|
+
if(result === true)
|
958
|
+
return;
|
959
|
+
}
|
708
960
|
}
|
961
|
+
this.walkExpression(expression.argument);
|
709
962
|
}
|
710
|
-
};
|
711
963
|
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
if(element)
|
716
|
-
this.walkPattern(element);
|
964
|
+
walkLeftRightExpression(expression) {
|
965
|
+
this.walkExpression(expression.left);
|
966
|
+
this.walkExpression(expression.right);
|
717
967
|
}
|
718
|
-
};
|
719
968
|
|
720
|
-
|
721
|
-
|
722
|
-
}
|
969
|
+
walkBinaryExpression(expression) {
|
970
|
+
this.walkLeftRightExpression(expression);
|
971
|
+
}
|
723
972
|
|
724
|
-
|
725
|
-
|
726
|
-
var expression = expressions[expressionsIndex];
|
727
|
-
if(expression)
|
728
|
-
this.walkExpression(expression);
|
973
|
+
walkLogicalExpression(expression) {
|
974
|
+
this.walkLeftRightExpression(expression);
|
729
975
|
}
|
730
|
-
};
|
731
976
|
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
977
|
+
walkAssignmentExpression(expression) {
|
978
|
+
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
979
|
+
if(expression.left.type === "Identifier" && renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, expression.right)) {
|
980
|
+
// renaming "a = b;"
|
981
|
+
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, expression.right)) {
|
982
|
+
this.scope.renames["$" + expression.left.name] = renameIdentifier;
|
983
|
+
const idx = this.scope.definitions.indexOf(expression.left.name);
|
984
|
+
if(idx >= 0) this.scope.definitions.splice(idx, 1);
|
985
|
+
}
|
986
|
+
} else if(expression.left.type === "Identifier") {
|
987
|
+
if(!this.applyPluginsBailResult1("assigned " + expression.left.name, expression)) {
|
988
|
+
this.walkExpression(expression.right);
|
989
|
+
}
|
990
|
+
this.scope.renames["$" + expression.left.name] = undefined;
|
991
|
+
if(!this.applyPluginsBailResult1("assign " + expression.left.name, expression)) {
|
992
|
+
this.walkExpression(expression.left);
|
993
|
+
}
|
994
|
+
} else {
|
995
|
+
this.walkExpression(expression.right);
|
996
|
+
this.scope.renames["$" + expression.left.name] = undefined;
|
997
|
+
this.walkExpression(expression.left);
|
998
|
+
}
|
999
|
+
}
|
736
1000
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
1001
|
+
walkConditionalExpression(expression) {
|
1002
|
+
const result = this.applyPluginsBailResult1("expression ?:", expression);
|
1003
|
+
if(result === undefined) {
|
1004
|
+
this.walkExpression(expression.test);
|
1005
|
+
this.walkExpression(expression.consequent);
|
1006
|
+
if(expression.alternate)
|
1007
|
+
this.walkExpression(expression.alternate);
|
1008
|
+
} else {
|
1009
|
+
if(result)
|
1010
|
+
this.walkExpression(expression.consequent);
|
1011
|
+
else if(expression.alternate)
|
1012
|
+
this.walkExpression(expression.alternate);
|
1013
|
+
}
|
1014
|
+
}
|
742
1015
|
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
1016
|
+
walkNewExpression(expression) {
|
1017
|
+
this.walkExpression(expression.callee);
|
1018
|
+
if(expression.arguments)
|
1019
|
+
this.walkExpressions(expression.arguments);
|
1020
|
+
}
|
747
1021
|
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
}
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
if(
|
762
|
-
this.
|
763
|
-
}
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
1022
|
+
walkYieldExpression(expression) {
|
1023
|
+
if(expression.argument)
|
1024
|
+
this.walkExpression(expression.argument);
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
walkTemplateLiteral(expression) {
|
1028
|
+
if(expression.expressions)
|
1029
|
+
this.walkExpressions(expression.expressions);
|
1030
|
+
}
|
1031
|
+
|
1032
|
+
walkTaggedTemplateExpression(expression) {
|
1033
|
+
if(expression.tag)
|
1034
|
+
this.walkExpression(expression.tag);
|
1035
|
+
if(expression.quasi && expression.quasi.expressions)
|
1036
|
+
this.walkExpressions(expression.quasi.expressions);
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
walkClassExpression(expression) {
|
1040
|
+
this.walkClass(expression);
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
walkCallExpression(expression) {
|
1044
|
+
let result;
|
1045
|
+
|
1046
|
+
function walkIIFE(functionExpression, options) {
|
1047
|
+
const params = functionExpression.params;
|
1048
|
+
const args = options.map(function(arg) {
|
1049
|
+
const renameIdentifier = this.getRenameIdentifier(arg);
|
1050
|
+
if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, arg)) {
|
1051
|
+
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, arg))
|
1052
|
+
return renameIdentifier;
|
1053
|
+
}
|
1054
|
+
this.walkExpression(arg);
|
1055
|
+
}, this);
|
1056
|
+
this.inScope(params.filter(function(identifier, idx) {
|
1057
|
+
return !args[idx];
|
1058
|
+
}), function() {
|
1059
|
+
for(let i = 0; i < args.length; i++) {
|
1060
|
+
const param = args[i];
|
1061
|
+
if(!param) continue;
|
1062
|
+
if(!params[i] || params[i].type !== "Identifier") continue;
|
1063
|
+
this.scope.renames["$" + params[i].name] = param;
|
1064
|
+
}
|
1065
|
+
if(functionExpression.body.type === "BlockStatement") {
|
1066
|
+
this.prewalkStatement(functionExpression.body);
|
1067
|
+
this.walkStatement(functionExpression.body);
|
1068
|
+
} else
|
1069
|
+
this.walkExpression(functionExpression.body);
|
1070
|
+
}.bind(this));
|
1071
|
+
}
|
1072
|
+
if(expression.callee.type === "MemberExpression" &&
|
1073
|
+
expression.callee.object.type === "FunctionExpression" &&
|
1074
|
+
!expression.callee.computed &&
|
1075
|
+
(["call", "bind"]).indexOf(expression.callee.property.name) >= 0 &&
|
1076
|
+
expression.arguments &&
|
1077
|
+
expression.arguments.length > 1
|
799
1078
|
) {
|
1079
|
+
// (function(...) { }.call/bind(?, ...))
|
1080
|
+
walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1));
|
1081
|
+
this.walkExpression(expression.arguments[0]);
|
1082
|
+
} else if(expression.callee.type === "FunctionExpression" && expression.arguments) {
|
1083
|
+
// (function(...) { }(...))
|
1084
|
+
walkIIFE.call(this, expression.callee, expression.arguments);
|
1085
|
+
} else if(expression.callee.type === "Import") {
|
1086
|
+
result = this.applyPluginsBailResult1("import-call", expression);
|
1087
|
+
if(result === true)
|
1088
|
+
return;
|
1089
|
+
|
1090
|
+
if(expression.arguments)
|
1091
|
+
this.walkExpressions(expression.arguments);
|
1092
|
+
} else {
|
1093
|
+
|
1094
|
+
const callee = this.evaluateExpression(expression.callee);
|
1095
|
+
if(callee.isIdentifier()) {
|
1096
|
+
result = this.applyPluginsBailResult1("call " + callee.identifier, expression);
|
1097
|
+
if(result === true)
|
1098
|
+
return;
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
if(expression.callee)
|
1102
|
+
this.walkExpression(expression.callee);
|
1103
|
+
if(expression.arguments)
|
1104
|
+
this.walkExpressions(expression.arguments);
|
1105
|
+
}
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
walkMemberExpression(expression) {
|
1109
|
+
let expr = expression;
|
1110
|
+
let exprName = [];
|
1111
|
+
while(expr.type === "MemberExpression" && expr.property.type === (expr.computed ? "Literal" : "Identifier")) {
|
800
1112
|
exprName.unshift(expr.property.name || expr.property.value);
|
801
1113
|
expr = expr.object;
|
802
1114
|
}
|
803
1115
|
if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) {
|
804
1116
|
exprName.unshift(this.scope.renames["$" + expr.name] || expr.name);
|
805
|
-
|
806
|
-
|
1117
|
+
let result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
|
1118
|
+
if(result === true)
|
1119
|
+
return;
|
1120
|
+
exprName[exprName.length - 1] = "*";
|
1121
|
+
result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
|
807
1122
|
if(result === true)
|
808
1123
|
return;
|
809
1124
|
}
|
1125
|
+
this.walkExpression(expression.object);
|
1126
|
+
if(expression.computed === true)
|
1127
|
+
this.walkExpression(expression.property);
|
810
1128
|
}
|
811
|
-
this.walkExpression(expression.argument);
|
812
|
-
};
|
813
1129
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
Parser.prototype.walkAssignmentExpression = function walkAssignmentExpression(expression) {
|
821
|
-
var renameIdentifier = this.getRenameIdentifier(expression.right);
|
822
|
-
if(expression.left.type === "Identifier" && renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, expression.right)) {
|
823
|
-
// renaming "a = b;"
|
824
|
-
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, expression.right)) {
|
825
|
-
this.scope.renames["$" + expression.left.name] = renameIdentifier;
|
826
|
-
var idx = this.scope.definitions.indexOf(expression.left.name);
|
827
|
-
if(idx >= 0) this.scope.definitions.splice(idx, 1);
|
828
|
-
}
|
829
|
-
} else if(expression.left.type === "Identifier") {
|
830
|
-
if(!this.applyPluginsBailResult1("assigned " + expression.left.name, expression)) {
|
831
|
-
this.walkExpression(expression.right);
|
832
|
-
}
|
833
|
-
this.scope.renames["$" + expression.left.name] = undefined;
|
834
|
-
if(!this.applyPluginsBailResult1("assign " + expression.left.name, expression)) {
|
835
|
-
this.walkExpression(expression.left);
|
1130
|
+
walkIdentifier(expression) {
|
1131
|
+
if(this.scope.definitions.indexOf(expression.name) === -1) {
|
1132
|
+
const result = this.applyPluginsBailResult1("expression " + (this.scope.renames["$" + expression.name] || expression.name), expression);
|
1133
|
+
if(result === true)
|
1134
|
+
return;
|
836
1135
|
}
|
837
|
-
} else {
|
838
|
-
this.walkExpression(expression.right);
|
839
|
-
this.scope.renames["$" + expression.left.name] = undefined;
|
840
|
-
this.walkExpression(expression.left);
|
841
1136
|
}
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
1137
|
+
|
1138
|
+
inScope(params, fn) {
|
1139
|
+
const oldScope = this.scope;
|
1140
|
+
this.scope = {
|
1141
|
+
inTry: false,
|
1142
|
+
inShorthand: false,
|
1143
|
+
definitions: oldScope.definitions.slice(),
|
1144
|
+
renames: Object.create(oldScope.renames)
|
1145
|
+
};
|
1146
|
+
|
1147
|
+
for(let paramIndex = 0, len = params.length; paramIndex < len; paramIndex++) {
|
1148
|
+
const param = params[paramIndex];
|
1149
|
+
|
1150
|
+
if(typeof param !== "string") {
|
1151
|
+
this.enterPattern(param, param => {
|
1152
|
+
this.scope.renames["$" + param] = undefined;
|
1153
|
+
this.scope.definitions.push(param);
|
1154
|
+
});
|
1155
|
+
} else {
|
1156
|
+
this.scope.renames["$" + param] = undefined;
|
1157
|
+
this.scope.definitions.push(param);
|
1158
|
+
}
|
1159
|
+
}
|
1160
|
+
|
1161
|
+
fn();
|
1162
|
+
this.scope = oldScope;
|
856
1163
|
}
|
857
|
-
};
|
858
1164
|
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
};
|
1165
|
+
enterPattern(pattern, onIdent) {
|
1166
|
+
if(pattern && this["enter" + pattern.type])
|
1167
|
+
this["enter" + pattern.type](pattern, onIdent);
|
1168
|
+
}
|
864
1169
|
|
865
|
-
|
866
|
-
|
867
|
-
this.walkExpression(expression.argument);
|
868
|
-
};
|
869
|
-
|
870
|
-
Parser.prototype.walkTemplateLiteral = function walkTemplateLiteral(expression) {
|
871
|
-
if(expression.expressions)
|
872
|
-
this.walkExpressions(expression.expressions);
|
873
|
-
};
|
874
|
-
|
875
|
-
Parser.prototype.walkTaggedTemplateExpression = function walkTaggedTemplateExpression(expression) {
|
876
|
-
if(expression.tag)
|
877
|
-
this.walkExpression(expression.tag);
|
878
|
-
if(expression.quasi && expression.quasi.expressions)
|
879
|
-
this.walkExpressions(expression.quasi.expressions);
|
880
|
-
};
|
881
|
-
|
882
|
-
Parser.prototype.walkClassExpression = function walkClassExpression(expression) {
|
883
|
-
this.walkClass(expression);
|
884
|
-
};
|
885
|
-
|
886
|
-
Parser.prototype.walkCallExpression = function walkCallExpression(expression) {
|
887
|
-
var result;
|
888
|
-
|
889
|
-
function walkIIFE(functionExpression, options) {
|
890
|
-
var params = functionExpression.params;
|
891
|
-
var args = options.map(function(arg) {
|
892
|
-
var renameIdentifier = this.getRenameIdentifier(arg);
|
893
|
-
if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, arg)) {
|
894
|
-
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, arg))
|
895
|
-
return renameIdentifier;
|
896
|
-
}
|
897
|
-
this.walkExpression(arg);
|
898
|
-
}, this);
|
899
|
-
this.inScope(params.filter(function(identifier, idx) {
|
900
|
-
return !args[idx];
|
901
|
-
}), function() {
|
902
|
-
for(var i = 0; i < args.length; i++) {
|
903
|
-
var param = args[i];
|
904
|
-
if(!param) continue;
|
905
|
-
if(!params[i] || params[i].type !== "Identifier") continue;
|
906
|
-
this.scope.renames["$" + params[i].name] = param;
|
907
|
-
}
|
908
|
-
if(functionExpression.body.type === "BlockStatement")
|
909
|
-
this.walkStatement(functionExpression.body);
|
910
|
-
else
|
911
|
-
this.walkExpression(functionExpression.body);
|
912
|
-
}.bind(this));
|
1170
|
+
enterIdentifier(pattern, onIdent) {
|
1171
|
+
onIdent(pattern.name, pattern);
|
913
1172
|
}
|
914
|
-
if(expression.callee.type === "MemberExpression" &&
|
915
|
-
expression.callee.object.type === "FunctionExpression" &&
|
916
|
-
!expression.callee.computed &&
|
917
|
-
(["call", "bind"]).indexOf(expression.callee.property.name) >= 0 &&
|
918
|
-
expression.arguments &&
|
919
|
-
expression.arguments.length > 1
|
920
|
-
) {
|
921
|
-
// (function(...) { }.call/bind(?, ...))
|
922
|
-
walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1));
|
923
|
-
this.walkExpression(expression.arguments[0]);
|
924
|
-
} else if(expression.callee.type === "FunctionExpression" && expression.arguments) {
|
925
|
-
// (function(...) { }(...))
|
926
|
-
walkIIFE.call(this, expression.callee, expression.arguments);
|
927
|
-
} else if(expression.callee.type === "Import") {
|
928
|
-
result = this.applyPluginsBailResult1("import-call", expression);
|
929
|
-
if(result === true)
|
930
|
-
return;
|
931
1173
|
|
932
|
-
|
933
|
-
|
934
|
-
|
1174
|
+
enterObjectPattern(pattern, onIdent) {
|
1175
|
+
for(let propIndex = 0, len = pattern.properties.length; propIndex < len; propIndex++) {
|
1176
|
+
const prop = pattern.properties[propIndex];
|
1177
|
+
this.enterPattern(prop.value, onIdent);
|
1178
|
+
}
|
1179
|
+
}
|
935
1180
|
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
return;
|
1181
|
+
enterArrayPattern(pattern, onIdent) {
|
1182
|
+
for(let elementIndex = 0, len = pattern.elements.length; elementIndex < len; elementIndex++) {
|
1183
|
+
const element = pattern.elements[elementIndex];
|
1184
|
+
this.enterPattern(element, onIdent);
|
941
1185
|
}
|
1186
|
+
}
|
942
1187
|
|
943
|
-
|
944
|
-
|
945
|
-
if(expression.arguments)
|
946
|
-
this.walkExpressions(expression.arguments);
|
1188
|
+
enterRestElement(pattern, onIdent) {
|
1189
|
+
this.enterPattern(pattern.argument, onIdent);
|
947
1190
|
}
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
var exprName = [];
|
953
|
-
while(expr.type === "MemberExpression" &&
|
954
|
-
expr.property.type === (expr.computed ? "Literal" : "Identifier")
|
955
|
-
) {
|
956
|
-
exprName.unshift(expr.property.name || expr.property.value);
|
957
|
-
expr = expr.object;
|
958
|
-
}
|
959
|
-
if(expr.type === "Identifier" && this.scope.definitions.indexOf(expr.name) === -1) {
|
960
|
-
exprName.unshift(this.scope.renames["$" + expr.name] || expr.name);
|
961
|
-
var result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
|
962
|
-
if(result === true)
|
963
|
-
return;
|
964
|
-
exprName[exprName.length - 1] = "*";
|
965
|
-
result = this.applyPluginsBailResult1("expression " + exprName.join("."), expression);
|
966
|
-
if(result === true)
|
967
|
-
return;
|
1191
|
+
|
1192
|
+
enterAssignmentPattern(pattern, onIdent) {
|
1193
|
+
this.enterPattern(pattern.left, onIdent);
|
1194
|
+
this.walkExpression(pattern.right);
|
968
1195
|
}
|
969
|
-
this.walkExpression(expression.object);
|
970
|
-
if(expression.computed === true)
|
971
|
-
this.walkExpression(expression.property);
|
972
|
-
};
|
973
1196
|
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
1197
|
+
evaluateExpression(expression) {
|
1198
|
+
try {
|
1199
|
+
const result = this.applyPluginsBailResult1("evaluate " + expression.type, expression);
|
1200
|
+
if(result !== undefined)
|
1201
|
+
return result;
|
1202
|
+
} catch(e) {
|
1203
|
+
console.warn(e);
|
1204
|
+
// ignore error
|
1205
|
+
}
|
1206
|
+
return new BasicEvaluatedExpression().setRange(expression.range);
|
979
1207
|
}
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
renames: Object.create(oldScope.renames)
|
990
|
-
};
|
991
|
-
|
992
|
-
for(var paramIndex = 0, len = params.length; paramIndex < len; paramIndex++) {
|
993
|
-
var param = params[paramIndex];
|
994
|
-
|
995
|
-
if(typeof param !== "string") {
|
996
|
-
_this.enterPattern(param, function(param) {
|
997
|
-
_this.scope.renames["$" + param] = undefined;
|
998
|
-
_this.scope.definitions.push(param);
|
999
|
-
});
|
1000
|
-
} else {
|
1001
|
-
_this.scope.renames["$" + param] = undefined;
|
1002
|
-
_this.scope.definitions.push(param);
|
1208
|
+
|
1209
|
+
parseString(expression) {
|
1210
|
+
switch(expression.type) {
|
1211
|
+
case "BinaryExpression":
|
1212
|
+
if(expression.operator === "+")
|
1213
|
+
return this.parseString(expression.left) + this.parseString(expression.right);
|
1214
|
+
break;
|
1215
|
+
case "Literal":
|
1216
|
+
return expression.value + "";
|
1003
1217
|
}
|
1218
|
+
throw new Error(expression.type + " is not supported as parameter for require");
|
1004
1219
|
}
|
1005
1220
|
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
};
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
}
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
} catch(e) {
|
1048
|
-
console.warn(e);
|
1049
|
-
// ignore error
|
1050
|
-
}
|
1051
|
-
return new BasicEvaluatedExpression().setRange(expression.range);
|
1052
|
-
};
|
1053
|
-
|
1054
|
-
Parser.prototype.parseString = function parseString(expression) {
|
1055
|
-
switch(expression.type) {
|
1056
|
-
case "BinaryExpression":
|
1057
|
-
if(expression.operator === "+")
|
1058
|
-
return this.parseString(expression.left) + this.parseString(expression.right);
|
1059
|
-
break;
|
1060
|
-
case "Literal":
|
1061
|
-
return expression.value + "";
|
1062
|
-
}
|
1063
|
-
throw new Error(expression.type + " is not supported as parameter for require");
|
1064
|
-
};
|
1065
|
-
|
1066
|
-
Parser.prototype.parseCalculatedString = function parseCalculatedString(expression) {
|
1067
|
-
switch(expression.type) {
|
1068
|
-
case "BinaryExpression":
|
1069
|
-
if(expression.operator === "+") {
|
1070
|
-
var left = this.parseCalculatedString(expression.left);
|
1071
|
-
var right = this.parseCalculatedString(expression.right);
|
1072
|
-
if(left.code) {
|
1073
|
-
return {
|
1074
|
-
range: left.range,
|
1075
|
-
value: left.value,
|
1076
|
-
code: true
|
1077
|
-
};
|
1078
|
-
} else if(right.code) {
|
1079
|
-
return {
|
1080
|
-
range: [left.range[0], right.range ? right.range[1] : left.range[1]],
|
1081
|
-
value: left.value + right.value,
|
1082
|
-
code: true
|
1083
|
-
};
|
1084
|
-
} else {
|
1221
|
+
parseCalculatedString(expression) {
|
1222
|
+
switch(expression.type) {
|
1223
|
+
case "BinaryExpression":
|
1224
|
+
if(expression.operator === "+") {
|
1225
|
+
const left = this.parseCalculatedString(expression.left);
|
1226
|
+
const right = this.parseCalculatedString(expression.right);
|
1227
|
+
if(left.code) {
|
1228
|
+
return {
|
1229
|
+
range: left.range,
|
1230
|
+
value: left.value,
|
1231
|
+
code: true
|
1232
|
+
};
|
1233
|
+
} else if(right.code) {
|
1234
|
+
return {
|
1235
|
+
range: [left.range[0], right.range ? right.range[1] : left.range[1]],
|
1236
|
+
value: left.value + right.value,
|
1237
|
+
code: true
|
1238
|
+
};
|
1239
|
+
} else {
|
1240
|
+
return {
|
1241
|
+
range: [left.range[0], right.range[1]],
|
1242
|
+
value: left.value + right.value
|
1243
|
+
};
|
1244
|
+
}
|
1245
|
+
}
|
1246
|
+
break;
|
1247
|
+
case "ConditionalExpression":
|
1248
|
+
{
|
1249
|
+
const consequent = this.parseCalculatedString(expression.consequent);
|
1250
|
+
const alternate = this.parseCalculatedString(expression.alternate);
|
1251
|
+
const items = [];
|
1252
|
+
if(consequent.conditional)
|
1253
|
+
Array.prototype.push.apply(items, consequent.conditional);
|
1254
|
+
else if(!consequent.code)
|
1255
|
+
items.push(consequent);
|
1256
|
+
else break;
|
1257
|
+
if(alternate.conditional)
|
1258
|
+
Array.prototype.push.apply(items, alternate.conditional);
|
1259
|
+
else if(!alternate.code)
|
1260
|
+
items.push(alternate);
|
1261
|
+
else break;
|
1085
1262
|
return {
|
1086
|
-
|
1087
|
-
|
1263
|
+
value: "",
|
1264
|
+
code: true,
|
1265
|
+
conditional: items
|
1088
1266
|
};
|
1089
1267
|
}
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
var items = [];
|
1096
|
-
if(consequent.conditional)
|
1097
|
-
Array.prototype.push.apply(items, consequent.conditional);
|
1098
|
-
else if(!consequent.code)
|
1099
|
-
items.push(consequent);
|
1100
|
-
else break;
|
1101
|
-
if(alternate.conditional)
|
1102
|
-
Array.prototype.push.apply(items, alternate.conditional);
|
1103
|
-
else if(!alternate.code)
|
1104
|
-
items.push(alternate);
|
1105
|
-
else break;
|
1106
|
-
return {
|
1107
|
-
value: "",
|
1108
|
-
code: true,
|
1109
|
-
conditional: items
|
1110
|
-
};
|
1111
|
-
case "Literal":
|
1112
|
-
return {
|
1113
|
-
range: expression.range,
|
1114
|
-
value: expression.value + ""
|
1115
|
-
};
|
1116
|
-
}
|
1117
|
-
return {
|
1118
|
-
value: "",
|
1119
|
-
code: true
|
1120
|
-
};
|
1121
|
-
};
|
1122
|
-
|
1123
|
-
["parseString", "parseCalculatedString"].forEach(function(fn) {
|
1124
|
-
Parser.prototype[fn + "Array"] = function parseXXXArray(expression) {
|
1125
|
-
switch(expression.type) {
|
1126
|
-
case "ArrayExpression":
|
1127
|
-
var arr = [];
|
1128
|
-
if(expression.elements)
|
1129
|
-
expression.elements.forEach(function(expr) {
|
1130
|
-
arr.push(this[fn](expr));
|
1131
|
-
}, this);
|
1132
|
-
return arr;
|
1268
|
+
case "Literal":
|
1269
|
+
return {
|
1270
|
+
range: expression.range,
|
1271
|
+
value: expression.value + ""
|
1272
|
+
};
|
1133
1273
|
}
|
1134
|
-
return
|
1135
|
-
|
1136
|
-
|
1274
|
+
return {
|
1275
|
+
value: "",
|
1276
|
+
code: true
|
1277
|
+
};
|
1278
|
+
}
|
1137
1279
|
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1280
|
+
parseStringArray(expression) {
|
1281
|
+
if(expression.type !== "ArrayExpression") {
|
1282
|
+
return [this.parseString(expression)];
|
1283
|
+
}
|
1284
|
+
|
1285
|
+
const arr = [];
|
1286
|
+
if(expression.elements)
|
1287
|
+
expression.elements.forEach(function(expr) {
|
1288
|
+
arr.push(this.parseString(expr));
|
1289
|
+
}, this);
|
1290
|
+
return arr;
|
1145
1291
|
}
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1292
|
+
|
1293
|
+
parseCalculatedStringArray(expression) {
|
1294
|
+
if(expression.type !== "ArrayExpression") {
|
1295
|
+
return [this.parseCalculatedString(expression)];
|
1296
|
+
}
|
1297
|
+
|
1298
|
+
const arr = [];
|
1299
|
+
if(expression.elements)
|
1300
|
+
expression.elements.forEach(function(expr) {
|
1301
|
+
arr.push(this.parseCalculatedString(expr));
|
1302
|
+
}, this);
|
1303
|
+
return arr;
|
1153
1304
|
}
|
1154
|
-
}];
|
1155
1305
|
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1306
|
+
parse(source, initialState) {
|
1307
|
+
let ast;
|
1308
|
+
const comments = [];
|
1309
|
+
for(let i = 0, len = POSSIBLE_AST_OPTIONS.length; i < len; i++) {
|
1310
|
+
if(!ast) {
|
1311
|
+
try {
|
1312
|
+
comments.length = 0;
|
1313
|
+
POSSIBLE_AST_OPTIONS[i].onComment = comments;
|
1314
|
+
ast = acorn.parse(source, POSSIBLE_AST_OPTIONS[i]);
|
1315
|
+
} catch(e) {
|
1316
|
+
// ignore the error
|
1317
|
+
}
|
1166
1318
|
}
|
1167
1319
|
}
|
1320
|
+
if(!ast) {
|
1321
|
+
// for the error
|
1322
|
+
ast = acorn.parse(source, {
|
1323
|
+
ranges: true,
|
1324
|
+
locations: true,
|
1325
|
+
ecmaVersion: 2017,
|
1326
|
+
sourceType: "module",
|
1327
|
+
plugins: {
|
1328
|
+
dynamicImport: true
|
1329
|
+
},
|
1330
|
+
onComment: comments
|
1331
|
+
});
|
1332
|
+
}
|
1333
|
+
if(!ast || typeof ast !== "object")
|
1334
|
+
throw new Error("Source couldn't be parsed");
|
1335
|
+
const oldScope = this.scope;
|
1336
|
+
const oldState = this.state;
|
1337
|
+
const oldComments = this.comments;
|
1338
|
+
this.scope = {
|
1339
|
+
inTry: false,
|
1340
|
+
definitions: [],
|
1341
|
+
renames: {}
|
1342
|
+
};
|
1343
|
+
const state = this.state = initialState || {};
|
1344
|
+
this.comments = comments;
|
1345
|
+
if(this.applyPluginsBailResult("program", ast, comments) === undefined) {
|
1346
|
+
this.prewalkStatements(ast.body);
|
1347
|
+
this.walkStatements(ast.body);
|
1348
|
+
}
|
1349
|
+
this.scope = oldScope;
|
1350
|
+
this.state = oldState;
|
1351
|
+
this.comments = oldComments;
|
1352
|
+
return state;
|
1168
1353
|
}
|
1169
|
-
|
1170
|
-
|
1171
|
-
ast = acorn.parse(source, {
|
1354
|
+
|
1355
|
+
evaluate(source) {
|
1356
|
+
const ast = acorn.parse("(" + source + ")", {
|
1172
1357
|
ranges: true,
|
1173
1358
|
locations: true,
|
1174
1359
|
ecmaVersion: 2017,
|
1175
1360
|
sourceType: "module",
|
1176
1361
|
plugins: {
|
1177
1362
|
dynamicImport: true
|
1178
|
-
}
|
1179
|
-
onComment: comments
|
1363
|
+
}
|
1180
1364
|
});
|
1365
|
+
if(!ast || typeof ast !== "object" || ast.type !== "Program")
|
1366
|
+
throw new Error("evaluate: Source couldn't be parsed");
|
1367
|
+
if(ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement")
|
1368
|
+
throw new Error("evaluate: Source is not a expression");
|
1369
|
+
return this.evaluateExpression(ast.body[0].expression);
|
1181
1370
|
}
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
};
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
ecmaVersion: 2017,
|
1204
|
-
sourceType: "module",
|
1205
|
-
plugins: {
|
1206
|
-
dynamicImport: true
|
1207
|
-
}
|
1208
|
-
});
|
1209
|
-
if(!ast || typeof ast !== "object" || ast.type !== "Program")
|
1210
|
-
throw new Error("evaluate: Source couldn't be parsed");
|
1211
|
-
if(ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement")
|
1212
|
-
throw new Error("evaluate: Source is not a expression");
|
1213
|
-
return this.evaluateExpression(ast.body[0].expression);
|
1214
|
-
};
|
1371
|
+
|
1372
|
+
getComments(range) {
|
1373
|
+
return this.comments.filter(comment => comment.range[0] >= range[0] && comment.range[1] <= range[1]);
|
1374
|
+
}
|
1375
|
+
|
1376
|
+
getCommentOptions(range) {
|
1377
|
+
const comments = this.getComments(range);
|
1378
|
+
if(comments.length === 0) return null;
|
1379
|
+
const options = comments.map(comment => {
|
1380
|
+
try {
|
1381
|
+
return json5.parse(`{${comment.value}}`);
|
1382
|
+
} catch(e) {
|
1383
|
+
return {};
|
1384
|
+
}
|
1385
|
+
});
|
1386
|
+
return options.reduce((o, i) => Object.assign(o, i), {});
|
1387
|
+
}
|
1388
|
+
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
module.exports = Parser;
|