| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.matchesPattern = matchesPattern; |
| exports.has = has; |
| exports.isStatic = isStatic; |
| exports.isnt = isnt; |
| exports.equals = equals; |
| exports.isNodeType = isNodeType; |
| exports.canHaveVariableDeclarationOrExpression = canHaveVariableDeclarationOrExpression; |
| exports.canSwapBetweenExpressionAndStatement = canSwapBetweenExpressionAndStatement; |
| exports.isCompletionRecord = isCompletionRecord; |
| exports.isStatementOrBlock = isStatementOrBlock; |
| exports.referencesImport = referencesImport; |
| exports.getSource = getSource; |
| exports.willIMaybeExecuteBefore = willIMaybeExecuteBefore; |
| exports._guessExecutionStatusRelativeTo = _guessExecutionStatusRelativeTo; |
| exports._guessExecutionStatusRelativeToDifferentFunctions = _guessExecutionStatusRelativeToDifferentFunctions; |
| exports.resolve = resolve; |
| exports._resolve = _resolve; |
| exports.isConstantExpression = isConstantExpression; |
| exports.isInStrictMode = isInStrictMode; |
| exports.is = void 0; |
| |
| var _includes = _interopRequireDefault(require("lodash/includes")); |
| |
| var t = _interopRequireWildcard(require("@babel/types")); |
| |
| function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } |
| |
| function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { 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; } |
| |
| function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
| |
| function matchesPattern(pattern, allowPartial) { |
| return t.matchesPattern(this.node, pattern, allowPartial); |
| } |
| |
| function has(key) { |
| const val = this.node && this.node[key]; |
| |
| if (val && Array.isArray(val)) { |
| return !!val.length; |
| } else { |
| return !!val; |
| } |
| } |
| |
| function isStatic() { |
| return this.scope.isStatic(this.node); |
| } |
| |
| const is = has; |
| exports.is = is; |
| |
| function isnt(key) { |
| return !this.has(key); |
| } |
| |
| function equals(key, value) { |
| return this.node[key] === value; |
| } |
| |
| function isNodeType(type) { |
| return t.isType(this.type, type); |
| } |
| |
| function canHaveVariableDeclarationOrExpression() { |
| return (this.key === "init" || this.key === "left") && this.parentPath.isFor(); |
| } |
| |
| function canSwapBetweenExpressionAndStatement(replacement) { |
| if (this.key !== "body" || !this.parentPath.isArrowFunctionExpression()) { |
| return false; |
| } |
| |
| if (this.isExpression()) { |
| return t.isBlockStatement(replacement); |
| } else if (this.isBlockStatement()) { |
| return t.isExpression(replacement); |
| } |
| |
| return false; |
| } |
| |
| function isCompletionRecord(allowInsideFunction) { |
| let path = this; |
| let first = true; |
| |
| do { |
| const container = path.container; |
| |
| if (path.isFunction() && !first) { |
| return !!allowInsideFunction; |
| } |
| |
| first = false; |
| |
| if (Array.isArray(container) && path.key !== container.length - 1) { |
| return false; |
| } |
| } while ((path = path.parentPath) && !path.isProgram()); |
| |
| return true; |
| } |
| |
| function isStatementOrBlock() { |
| if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) { |
| return false; |
| } else { |
| return (0, _includes.default)(t.STATEMENT_OR_BLOCK_KEYS, this.key); |
| } |
| } |
| |
| function referencesImport(moduleSource, importName) { |
| if (!this.isReferencedIdentifier()) return false; |
| const binding = this.scope.getBinding(this.node.name); |
| if (!binding || binding.kind !== "module") return false; |
| const path = binding.path; |
| const parent = path.parentPath; |
| if (!parent.isImportDeclaration()) return false; |
| |
| if (parent.node.source.value === moduleSource) { |
| if (!importName) return true; |
| } else { |
| return false; |
| } |
| |
| if (path.isImportDefaultSpecifier() && importName === "default") { |
| return true; |
| } |
| |
| if (path.isImportNamespaceSpecifier() && importName === "*") { |
| return true; |
| } |
| |
| if (path.isImportSpecifier() && path.node.imported.name === importName) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| function getSource() { |
| const node = this.node; |
| |
| if (node.end) { |
| const code = this.hub.getCode(); |
| if (code) return code.slice(node.start, node.end); |
| } |
| |
| return ""; |
| } |
| |
| function willIMaybeExecuteBefore(target) { |
| return this._guessExecutionStatusRelativeTo(target) !== "after"; |
| } |
| |
| function getOuterFunction(path) { |
| return (path.scope.getFunctionParent() || path.scope.getProgramParent()).path; |
| } |
| |
| function isExecutionUncertain(type, key) { |
| switch (type) { |
| case "LogicalExpression": |
| return key === "right"; |
| |
| case "ConditionalExpression": |
| case "IfStatement": |
| return key === "consequent" || key === "alternate"; |
| |
| case "WhileStatement": |
| case "DoWhileStatement": |
| case "ForInStatement": |
| case "ForOfStatement": |
| return key === "body"; |
| |
| case "ForStatement": |
| return key === "body" || key === "update"; |
| |
| case "SwitchStatement": |
| return key === "cases"; |
| |
| case "TryStatement": |
| return key === "handler"; |
| |
| case "AssignmentPattern": |
| return key === "right"; |
| |
| case "OptionalMemberExpression": |
| return key === "property"; |
| |
| case "OptionalCallExpression": |
| return key === "arguments"; |
| |
| default: |
| return false; |
| } |
| } |
| |
| function isExecutionUncertainInList(paths, maxIndex) { |
| for (let i = 0; i < maxIndex; i++) { |
| const path = paths[i]; |
| |
| if (isExecutionUncertain(path.parent.type, path.parentKey)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| function _guessExecutionStatusRelativeTo(target) { |
| const funcParent = { |
| this: getOuterFunction(this), |
| target: getOuterFunction(target) |
| }; |
| |
| if (funcParent.target.node !== funcParent.this.node) { |
| return this._guessExecutionStatusRelativeToDifferentFunctions(funcParent.target); |
| } |
| |
| const paths = { |
| target: target.getAncestry(), |
| this: this.getAncestry() |
| }; |
| if (paths.target.indexOf(this) >= 0) return "after"; |
| if (paths.this.indexOf(target) >= 0) return "before"; |
| let commonPath; |
| const commonIndex = { |
| target: 0, |
| this: 0 |
| }; |
| |
| while (!commonPath && commonIndex.this < paths.this.length) { |
| const path = paths.this[commonIndex.this]; |
| commonIndex.target = paths.target.indexOf(path); |
| |
| if (commonIndex.target >= 0) { |
| commonPath = path; |
| } else { |
| commonIndex.this++; |
| } |
| } |
| |
| if (!commonPath) { |
| throw new Error("Internal Babel error - The two compared nodes" + " don't appear to belong to the same program."); |
| } |
| |
| if (isExecutionUncertainInList(paths.this, commonIndex.this - 1) || isExecutionUncertainInList(paths.target, commonIndex.target - 1)) { |
| return "unknown"; |
| } |
| |
| const divergence = { |
| this: paths.this[commonIndex.this - 1], |
| target: paths.target[commonIndex.target - 1] |
| }; |
| |
| if (divergence.target.listKey && divergence.this.listKey && divergence.target.container === divergence.this.container) { |
| return divergence.target.key > divergence.this.key ? "before" : "after"; |
| } |
| |
| const keys = t.VISITOR_KEYS[commonPath.type]; |
| const keyPosition = { |
| this: keys.indexOf(divergence.this.parentKey), |
| target: keys.indexOf(divergence.target.parentKey) |
| }; |
| return keyPosition.target > keyPosition.this ? "before" : "after"; |
| } |
| |
| const executionOrderCheckedNodes = new WeakSet(); |
| |
| function _guessExecutionStatusRelativeToDifferentFunctions(target) { |
| if (!target.isFunctionDeclaration() || target.parentPath.isExportDeclaration()) { |
| return "unknown"; |
| } |
| |
| const binding = target.scope.getBinding(target.node.id.name); |
| if (!binding.references) return "before"; |
| const referencePaths = binding.referencePaths; |
| let allStatus; |
| |
| for (const path of referencePaths) { |
| const childOfFunction = !!path.find(path => path.node === target.node); |
| if (childOfFunction) continue; |
| |
| if (path.key !== "callee" || !path.parentPath.isCallExpression()) { |
| return "unknown"; |
| } |
| |
| if (executionOrderCheckedNodes.has(path.node)) continue; |
| executionOrderCheckedNodes.add(path.node); |
| |
| const status = this._guessExecutionStatusRelativeTo(path); |
| |
| executionOrderCheckedNodes.delete(path.node); |
| |
| if (allStatus && allStatus !== status) { |
| return "unknown"; |
| } else { |
| allStatus = status; |
| } |
| } |
| |
| return allStatus; |
| } |
| |
| function resolve(dangerous, resolved) { |
| return this._resolve(dangerous, resolved) || this; |
| } |
| |
| function _resolve(dangerous, resolved) { |
| if (resolved && resolved.indexOf(this) >= 0) return; |
| resolved = resolved || []; |
| resolved.push(this); |
| |
| if (this.isVariableDeclarator()) { |
| if (this.get("id").isIdentifier()) { |
| return this.get("init").resolve(dangerous, resolved); |
| } else {} |
| } else if (this.isReferencedIdentifier()) { |
| const binding = this.scope.getBinding(this.node.name); |
| if (!binding) return; |
| if (!binding.constant) return; |
| if (binding.kind === "module") return; |
| |
| if (binding.path !== this) { |
| const ret = binding.path.resolve(dangerous, resolved); |
| if (this.find(parent => parent.node === ret.node)) return; |
| return ret; |
| } |
| } else if (this.isTypeCastExpression()) { |
| return this.get("expression").resolve(dangerous, resolved); |
| } else if (dangerous && this.isMemberExpression()) { |
| const targetKey = this.toComputedKey(); |
| if (!t.isLiteral(targetKey)) return; |
| const targetName = targetKey.value; |
| const target = this.get("object").resolve(dangerous, resolved); |
| |
| if (target.isObjectExpression()) { |
| const props = target.get("properties"); |
| |
| for (const prop of props) { |
| if (!prop.isProperty()) continue; |
| const key = prop.get("key"); |
| let match = prop.isnt("computed") && key.isIdentifier({ |
| name: targetName |
| }); |
| match = match || key.isLiteral({ |
| value: targetName |
| }); |
| if (match) return prop.get("value").resolve(dangerous, resolved); |
| } |
| } else if (target.isArrayExpression() && !isNaN(+targetName)) { |
| const elems = target.get("elements"); |
| const elem = elems[targetName]; |
| if (elem) return elem.resolve(dangerous, resolved); |
| } |
| } |
| } |
| |
| function isConstantExpression() { |
| if (this.isIdentifier()) { |
| const binding = this.scope.getBinding(this.node.name); |
| if (!binding) return false; |
| return binding.constant; |
| } |
| |
| if (this.isLiteral()) { |
| if (this.isRegExpLiteral()) { |
| return false; |
| } |
| |
| if (this.isTemplateLiteral()) { |
| return this.get("expressions").every(expression => expression.isConstantExpression()); |
| } |
| |
| return true; |
| } |
| |
| if (this.isUnaryExpression()) { |
| if (this.get("operator").node !== "void") { |
| return false; |
| } |
| |
| return this.get("argument").isConstantExpression(); |
| } |
| |
| if (this.isBinaryExpression()) { |
| return this.get("left").isConstantExpression() && this.get("right").isConstantExpression(); |
| } |
| |
| return false; |
| } |
| |
| function isInStrictMode() { |
| const start = this.isProgram() ? this : this.parentPath; |
| const strictParent = start.find(path => { |
| if (path.isProgram({ |
| sourceType: "module" |
| })) return true; |
| if (path.isClass()) return true; |
| if (!path.isProgram() && !path.isFunction()) return false; |
| |
| if (path.isArrowFunctionExpression() && !path.get("body").isBlockStatement()) { |
| return false; |
| } |
| |
| let { |
| node |
| } = path; |
| if (path.isFunction()) node = node.body; |
| |
| for (const directive of node.directives) { |
| if (directive.value.value === "use strict") { |
| return true; |
| } |
| } |
| }); |
| return !!strictParent; |
| } |