"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; }