"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports._guessExecutionStatusRelativeTo = _guessExecutionStatusRelativeTo; exports._resolve = _resolve; exports.canHaveVariableDeclarationOrExpression = canHaveVariableDeclarationOrExpression; exports.canSwapBetweenExpressionAndStatement = canSwapBetweenExpressionAndStatement; exports.equals = equals; exports.getSource = getSource; exports.has = has; exports.is = void 0; exports.isCompletionRecord = isCompletionRecord; exports.isConstantExpression = isConstantExpression; exports.isInStrictMode = isInStrictMode; exports.isNodeType = isNodeType; exports.isStatementOrBlock = isStatementOrBlock; exports.isStatic = isStatic; exports.isnt = isnt; exports.matchesPattern = matchesPattern; exports.referencesImport = referencesImport; exports.resolve = resolve; exports.willIMaybeExecuteBefore = willIMaybeExecuteBefore; var _t = require("@babel/types"); const { STATEMENT_OR_BLOCK_KEYS, VISITOR_KEYS, isBlockStatement, isExpression, isIdentifier, isLiteral, isStringLiteral, isType, matchesPattern: _matchesPattern } = _t; function matchesPattern(pattern, allowPartial) { return _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 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 isBlockStatement(replacement); } else if (this.isBlockStatement()) { return isExpression(replacement); } return false; } function isCompletionRecord(allowInsideFunction) { let path = this; let first = true; do { const { type, container } = path; if (!first && (path.isFunction() || type === "StaticBlock")) { return !!allowInsideFunction; } first = false; if (Array.isArray(container) && path.key !== container.length - 1) { return false; } } while ((path = path.parentPath) && !path.isProgram() && !path.isDoExpression()); return true; } function isStatementOrBlock() { if (this.parentPath.isLabeledStatement() || isBlockStatement(this.container)) { return false; } else { return STATEMENT_OR_BLOCK_KEYS.includes(this.key); } } function referencesImport(moduleSource, importName) { if (!this.isReferencedIdentifier()) { if (this.isJSXMemberExpression() && this.node.property.name === importName || (this.isMemberExpression() || this.isOptionalMemberExpression()) && (this.node.computed ? isStringLiteral(this.node.property, { value: importName }) : this.node.property.name === importName)) { const object = this.get("object"); return object.isReferencedIdentifier() && object.referencesImport(moduleSource, "*"); } 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() && isIdentifier(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.isProgram() ? path : (path.parentPath.scope.getFunctionParent() || path.parentPath.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; } const SYMBOL_CHECKING = Symbol(); function _guessExecutionStatusRelativeTo(target) { return _guessExecutionStatusRelativeToCached(this, target, new Map()); } function _guessExecutionStatusRelativeToCached(base, target, cache) { const funcParent = { this: getOuterFunction(base), target: getOuterFunction(target) }; if (funcParent.target.node !== funcParent.this.node) { return _guessExecutionStatusRelativeToDifferentFunctionsCached(base, funcParent.target, cache); } const paths = { target: target.getAncestry(), this: base.getAncestry() }; if (paths.target.indexOf(base) >= 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 = 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"; } function _guessExecutionStatusRelativeToDifferentFunctionsInternal(base, target, cache) { if (!target.isFunctionDeclaration()) { if (_guessExecutionStatusRelativeToCached(base, target, cache) === "before") { return "before"; } return "unknown"; } else if (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"; } const status = _guessExecutionStatusRelativeToCached(base, path, cache); if (allStatus && allStatus !== status) { return "unknown"; } else { allStatus = status; } } return allStatus; } function _guessExecutionStatusRelativeToDifferentFunctionsCached(base, target, cache) { let nodeMap = cache.get(base.node); let cached; if (!nodeMap) { cache.set(base.node, nodeMap = new Map()); } else if (cached = nodeMap.get(target.node)) { if (cached === SYMBOL_CHECKING) { return "unknown"; } return cached; } nodeMap.set(target.node, SYMBOL_CHECKING); const result = _guessExecutionStatusRelativeToDifferentFunctionsInternal(base, target, cache); nodeMap.set(target.node, result); return result; } 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 (!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.node.operator !== "void") { return false; } return this.get("argument").isConstantExpression(); } if (this.isBinaryExpression()) { const { operator } = this.node; return operator !== "in" && operator !== "instanceof" && 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.isArrowFunctionExpression() && !path.get("body").isBlockStatement()) { return false; } let body; if (path.isFunction()) { body = path.node.body; } else if (path.isProgram()) { body = path.node; } else { return false; } for (const directive of body.directives) { if (directive.value.value === "use strict") { return true; } } }); return !!strictParent; } //# sourceMappingURL=introspection.js.map