1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.matchesPattern = matchesPattern;
|
7 | exports.has = has;
|
8 | exports.isStatic = isStatic;
|
9 | exports.isnt = isnt;
|
10 | exports.equals = equals;
|
11 | exports.isNodeType = isNodeType;
|
12 | exports.canHaveVariableDeclarationOrExpression = canHaveVariableDeclarationOrExpression;
|
13 | exports.canSwapBetweenExpressionAndStatement = canSwapBetweenExpressionAndStatement;
|
14 | exports.isCompletionRecord = isCompletionRecord;
|
15 | exports.isStatementOrBlock = isStatementOrBlock;
|
16 | exports.referencesImport = referencesImport;
|
17 | exports.getSource = getSource;
|
18 | exports.willIMaybeExecuteBefore = willIMaybeExecuteBefore;
|
19 | exports._guessExecutionStatusRelativeTo = _guessExecutionStatusRelativeTo;
|
20 | exports._guessExecutionStatusRelativeToDifferentFunctions = _guessExecutionStatusRelativeToDifferentFunctions;
|
21 | exports.resolve = resolve;
|
22 | exports._resolve = _resolve;
|
23 | exports.isConstantExpression = isConstantExpression;
|
24 | exports.isInStrictMode = isInStrictMode;
|
25 | exports.is = void 0;
|
26 |
|
27 | var _includes = _interopRequireDefault(require("lodash/includes"));
|
28 |
|
29 | var t = _interopRequireWildcard(require("@babel/types"));
|
30 |
|
31 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
32 |
|
33 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
34 |
|
35 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
36 |
|
37 | function matchesPattern(pattern, allowPartial) {
|
38 | return t.matchesPattern(this.node, pattern, allowPartial);
|
39 | }
|
40 |
|
41 | function has(key) {
|
42 | const val = this.node && this.node[key];
|
43 |
|
44 | if (val && Array.isArray(val)) {
|
45 | return !!val.length;
|
46 | } else {
|
47 | return !!val;
|
48 | }
|
49 | }
|
50 |
|
51 | function isStatic() {
|
52 | return this.scope.isStatic(this.node);
|
53 | }
|
54 |
|
55 | const is = has;
|
56 | exports.is = is;
|
57 |
|
58 | function isnt(key) {
|
59 | return !this.has(key);
|
60 | }
|
61 |
|
62 | function equals(key, value) {
|
63 | return this.node[key] === value;
|
64 | }
|
65 |
|
66 | function isNodeType(type) {
|
67 | return t.isType(this.type, type);
|
68 | }
|
69 |
|
70 | function canHaveVariableDeclarationOrExpression() {
|
71 | return (this.key === "init" || this.key === "left") && this.parentPath.isFor();
|
72 | }
|
73 |
|
74 | function canSwapBetweenExpressionAndStatement(replacement) {
|
75 | if (this.key !== "body" || !this.parentPath.isArrowFunctionExpression()) {
|
76 | return false;
|
77 | }
|
78 |
|
79 | if (this.isExpression()) {
|
80 | return t.isBlockStatement(replacement);
|
81 | } else if (this.isBlockStatement()) {
|
82 | return t.isExpression(replacement);
|
83 | }
|
84 |
|
85 | return false;
|
86 | }
|
87 |
|
88 | function isCompletionRecord(allowInsideFunction) {
|
89 | let path = this;
|
90 | let first = true;
|
91 |
|
92 | do {
|
93 | const container = path.container;
|
94 |
|
95 | if (path.isFunction() && !first) {
|
96 | return !!allowInsideFunction;
|
97 | }
|
98 |
|
99 | first = false;
|
100 |
|
101 | if (Array.isArray(container) && path.key !== container.length - 1) {
|
102 | return false;
|
103 | }
|
104 | } while ((path = path.parentPath) && !path.isProgram());
|
105 |
|
106 | return true;
|
107 | }
|
108 |
|
109 | function isStatementOrBlock() {
|
110 | if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) {
|
111 | return false;
|
112 | } else {
|
113 | return (0, _includes.default)(t.STATEMENT_OR_BLOCK_KEYS, this.key);
|
114 | }
|
115 | }
|
116 |
|
117 | function referencesImport(moduleSource, importName) {
|
118 | if (!this.isReferencedIdentifier()) return false;
|
119 | const binding = this.scope.getBinding(this.node.name);
|
120 | if (!binding || binding.kind !== "module") return false;
|
121 | const path = binding.path;
|
122 | const parent = path.parentPath;
|
123 | if (!parent.isImportDeclaration()) return false;
|
124 |
|
125 | if (parent.node.source.value === moduleSource) {
|
126 | if (!importName) return true;
|
127 | } else {
|
128 | return false;
|
129 | }
|
130 |
|
131 | if (path.isImportDefaultSpecifier() && importName === "default") {
|
132 | return true;
|
133 | }
|
134 |
|
135 | if (path.isImportNamespaceSpecifier() && importName === "*") {
|
136 | return true;
|
137 | }
|
138 |
|
139 | if (path.isImportSpecifier() && path.node.imported.name === importName) {
|
140 | return true;
|
141 | }
|
142 |
|
143 | return false;
|
144 | }
|
145 |
|
146 | function getSource() {
|
147 | const node = this.node;
|
148 |
|
149 | if (node.end) {
|
150 | const code = this.hub.getCode();
|
151 | if (code) return code.slice(node.start, node.end);
|
152 | }
|
153 |
|
154 | return "";
|
155 | }
|
156 |
|
157 | function willIMaybeExecuteBefore(target) {
|
158 | return this._guessExecutionStatusRelativeTo(target) !== "after";
|
159 | }
|
160 |
|
161 | function getOuterFunction(path) {
|
162 | return (path.scope.getFunctionParent() || path.scope.getProgramParent()).path;
|
163 | }
|
164 |
|
165 | function isExecutionUncertain(type, key) {
|
166 | switch (type) {
|
167 | case "LogicalExpression":
|
168 | return key === "right";
|
169 |
|
170 | case "ConditionalExpression":
|
171 | case "IfStatement":
|
172 | return key === "consequent" || key === "alternate";
|
173 |
|
174 | case "WhileStatement":
|
175 | case "DoWhileStatement":
|
176 | case "ForInStatement":
|
177 | case "ForOfStatement":
|
178 | return key === "body";
|
179 |
|
180 | case "ForStatement":
|
181 | return key === "body" || key === "update";
|
182 |
|
183 | case "SwitchStatement":
|
184 | return key === "cases";
|
185 |
|
186 | case "TryStatement":
|
187 | return key === "handler";
|
188 |
|
189 | case "AssignmentPattern":
|
190 | return key === "right";
|
191 |
|
192 | case "OptionalMemberExpression":
|
193 | return key === "property";
|
194 |
|
195 | case "OptionalCallExpression":
|
196 | return key === "arguments";
|
197 |
|
198 | default:
|
199 | return false;
|
200 | }
|
201 | }
|
202 |
|
203 | function isExecutionUncertainInList(paths, maxIndex) {
|
204 | for (let i = 0; i < maxIndex; i++) {
|
205 | const path = paths[i];
|
206 |
|
207 | if (isExecutionUncertain(path.parent.type, path.parentKey)) {
|
208 | return true;
|
209 | }
|
210 | }
|
211 |
|
212 | return false;
|
213 | }
|
214 |
|
215 | function _guessExecutionStatusRelativeTo(target) {
|
216 | const funcParent = {
|
217 | this: getOuterFunction(this),
|
218 | target: getOuterFunction(target)
|
219 | };
|
220 |
|
221 | if (funcParent.target.node !== funcParent.this.node) {
|
222 | return this._guessExecutionStatusRelativeToDifferentFunctions(funcParent.target);
|
223 | }
|
224 |
|
225 | const paths = {
|
226 | target: target.getAncestry(),
|
227 | this: this.getAncestry()
|
228 | };
|
229 | if (paths.target.indexOf(this) >= 0) return "after";
|
230 | if (paths.this.indexOf(target) >= 0) return "before";
|
231 | let commonPath;
|
232 | const commonIndex = {
|
233 | target: 0,
|
234 | this: 0
|
235 | };
|
236 |
|
237 | while (!commonPath && commonIndex.this < paths.this.length) {
|
238 | const path = paths.this[commonIndex.this];
|
239 | commonIndex.target = paths.target.indexOf(path);
|
240 |
|
241 | if (commonIndex.target >= 0) {
|
242 | commonPath = path;
|
243 | } else {
|
244 | commonIndex.this++;
|
245 | }
|
246 | }
|
247 |
|
248 | if (!commonPath) {
|
249 | throw new Error("Internal Babel error - The two compared nodes" + " don't appear to belong to the same program.");
|
250 | }
|
251 |
|
252 | if (isExecutionUncertainInList(paths.this, commonIndex.this - 1) || isExecutionUncertainInList(paths.target, commonIndex.target - 1)) {
|
253 | return "unknown";
|
254 | }
|
255 |
|
256 | const divergence = {
|
257 | this: paths.this[commonIndex.this - 1],
|
258 | target: paths.target[commonIndex.target - 1]
|
259 | };
|
260 |
|
261 | if (divergence.target.listKey && divergence.this.listKey && divergence.target.container === divergence.this.container) {
|
262 | return divergence.target.key > divergence.this.key ? "before" : "after";
|
263 | }
|
264 |
|
265 | const keys = t.VISITOR_KEYS[commonPath.type];
|
266 | const keyPosition = {
|
267 | this: keys.indexOf(divergence.this.parentKey),
|
268 | target: keys.indexOf(divergence.target.parentKey)
|
269 | };
|
270 | return keyPosition.target > keyPosition.this ? "before" : "after";
|
271 | }
|
272 |
|
273 | const executionOrderCheckedNodes = new WeakSet();
|
274 |
|
275 | function _guessExecutionStatusRelativeToDifferentFunctions(target) {
|
276 | if (!target.isFunctionDeclaration() || target.parentPath.isExportDeclaration()) {
|
277 | return "unknown";
|
278 | }
|
279 |
|
280 | const binding = target.scope.getBinding(target.node.id.name);
|
281 | if (!binding.references) return "before";
|
282 | const referencePaths = binding.referencePaths;
|
283 | let allStatus;
|
284 |
|
285 | for (const path of referencePaths) {
|
286 | const childOfFunction = !!path.find(path => path.node === target.node);
|
287 | if (childOfFunction) continue;
|
288 |
|
289 | if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
|
290 | return "unknown";
|
291 | }
|
292 |
|
293 | if (executionOrderCheckedNodes.has(path.node)) continue;
|
294 | executionOrderCheckedNodes.add(path.node);
|
295 |
|
296 | const status = this._guessExecutionStatusRelativeTo(path);
|
297 |
|
298 | executionOrderCheckedNodes.delete(path.node);
|
299 |
|
300 | if (allStatus && allStatus !== status) {
|
301 | return "unknown";
|
302 | } else {
|
303 | allStatus = status;
|
304 | }
|
305 | }
|
306 |
|
307 | return allStatus;
|
308 | }
|
309 |
|
310 | function resolve(dangerous, resolved) {
|
311 | return this._resolve(dangerous, resolved) || this;
|
312 | }
|
313 |
|
314 | function _resolve(dangerous, resolved) {
|
315 | if (resolved && resolved.indexOf(this) >= 0) return;
|
316 | resolved = resolved || [];
|
317 | resolved.push(this);
|
318 |
|
319 | if (this.isVariableDeclarator()) {
|
320 | if (this.get("id").isIdentifier()) {
|
321 | return this.get("init").resolve(dangerous, resolved);
|
322 | } else {}
|
323 | } else if (this.isReferencedIdentifier()) {
|
324 | const binding = this.scope.getBinding(this.node.name);
|
325 | if (!binding) return;
|
326 | if (!binding.constant) return;
|
327 | if (binding.kind === "module") return;
|
328 |
|
329 | if (binding.path !== this) {
|
330 | const ret = binding.path.resolve(dangerous, resolved);
|
331 | if (this.find(parent => parent.node === ret.node)) return;
|
332 | return ret;
|
333 | }
|
334 | } else if (this.isTypeCastExpression()) {
|
335 | return this.get("expression").resolve(dangerous, resolved);
|
336 | } else if (dangerous && this.isMemberExpression()) {
|
337 | const targetKey = this.toComputedKey();
|
338 | if (!t.isLiteral(targetKey)) return;
|
339 | const targetName = targetKey.value;
|
340 | const target = this.get("object").resolve(dangerous, resolved);
|
341 |
|
342 | if (target.isObjectExpression()) {
|
343 | const props = target.get("properties");
|
344 |
|
345 | for (const prop of props) {
|
346 | if (!prop.isProperty()) continue;
|
347 | const key = prop.get("key");
|
348 | let match = prop.isnt("computed") && key.isIdentifier({
|
349 | name: targetName
|
350 | });
|
351 | match = match || key.isLiteral({
|
352 | value: targetName
|
353 | });
|
354 | if (match) return prop.get("value").resolve(dangerous, resolved);
|
355 | }
|
356 | } else if (target.isArrayExpression() && !isNaN(+targetName)) {
|
357 | const elems = target.get("elements");
|
358 | const elem = elems[targetName];
|
359 | if (elem) return elem.resolve(dangerous, resolved);
|
360 | }
|
361 | }
|
362 | }
|
363 |
|
364 | function isConstantExpression() {
|
365 | if (this.isIdentifier()) {
|
366 | const binding = this.scope.getBinding(this.node.name);
|
367 | if (!binding) return false;
|
368 | return binding.constant;
|
369 | }
|
370 |
|
371 | if (this.isLiteral()) {
|
372 | if (this.isRegExpLiteral()) {
|
373 | return false;
|
374 | }
|
375 |
|
376 | if (this.isTemplateLiteral()) {
|
377 | return this.get("expressions").every(expression => expression.isConstantExpression());
|
378 | }
|
379 |
|
380 | return true;
|
381 | }
|
382 |
|
383 | if (this.isUnaryExpression()) {
|
384 | if (this.get("operator").node !== "void") {
|
385 | return false;
|
386 | }
|
387 |
|
388 | return this.get("argument").isConstantExpression();
|
389 | }
|
390 |
|
391 | if (this.isBinaryExpression()) {
|
392 | return this.get("left").isConstantExpression() && this.get("right").isConstantExpression();
|
393 | }
|
394 |
|
395 | return false;
|
396 | }
|
397 |
|
398 | function isInStrictMode() {
|
399 | const start = this.isProgram() ? this : this.parentPath;
|
400 | const strictParent = start.find(path => {
|
401 | if (path.isProgram({
|
402 | sourceType: "module"
|
403 | })) return true;
|
404 | if (path.isClass()) return true;
|
405 | if (!path.isProgram() && !path.isFunction()) return false;
|
406 |
|
407 | if (path.isArrowFunctionExpression() && !path.get("body").isBlockStatement()) {
|
408 | return false;
|
409 | }
|
410 |
|
411 | let {
|
412 | node
|
413 | } = path;
|
414 | if (path.isFunction()) node = node.body;
|
415 |
|
416 | for (const directive of node.directives) {
|
417 | if (directive.value.value === "use strict") {
|
418 | return true;
|
419 | }
|
420 | }
|
421 | });
|
422 | return !!strictParent;
|
423 | } |
\ | No newline at end of file |