"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getOpposite = getOpposite; exports.getCompletionRecords = getCompletionRecords; exports.getSibling = getSibling; exports.getPrevSibling = getPrevSibling; exports.getNextSibling = getNextSibling; exports.getAllNextSiblings = getAllNextSiblings; exports.getAllPrevSiblings = getAllPrevSiblings; exports.get = get; exports._getKey = _getKey; exports._getPattern = _getPattern; exports.getBindingIdentifiers = getBindingIdentifiers; exports.getOuterBindingIdentifiers = getOuterBindingIdentifiers; exports.getBindingIdentifierPaths = getBindingIdentifierPaths; exports.getOuterBindingIdentifierPaths = getOuterBindingIdentifierPaths; var _index = _interopRequireDefault(require("./index")); 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 getOpposite() { if (this.key === "left") { return this.getSibling("right"); } else if (this.key === "right") { return this.getSibling("left"); } } function addCompletionRecords(path, paths) { if (path) return paths.concat(path.getCompletionRecords()); return paths; } function completionRecordForSwitch(cases, paths) { let isLastCaseWithConsequent = true; for (let i = cases.length - 1; i >= 0; i--) { const switchCase = cases[i]; const consequent = switchCase.get("consequent"); let breakStatement; findBreak: for (const statement of consequent) { if (statement.isBlockStatement()) { for (const statementInBlock of statement.get("body")) { if (statementInBlock.isBreakStatement()) { breakStatement = statementInBlock; break findBreak; } } } else if (statement.isBreakStatement()) { breakStatement = statement; break; } } if (breakStatement) { while (breakStatement.key === 0 && breakStatement.parentPath.isBlockStatement()) { breakStatement = breakStatement.parentPath; } const prevSibling = breakStatement.getPrevSibling(); if (breakStatement.key > 0 && (prevSibling.isExpressionStatement() || prevSibling.isBlockStatement())) { paths = addCompletionRecords(prevSibling, paths); breakStatement.remove(); } else { breakStatement.replaceWith(breakStatement.scope.buildUndefinedNode()); paths = addCompletionRecords(breakStatement, paths); } } else if (isLastCaseWithConsequent) { const statementFinder = statement => !statement.isBlockStatement() || statement.get("body").some(statementFinder); const hasConsequent = consequent.some(statementFinder); if (hasConsequent) { paths = addCompletionRecords(consequent[consequent.length - 1], paths); isLastCaseWithConsequent = false; } } } return paths; } function getCompletionRecords() { let paths = []; if (this.isIfStatement()) { paths = addCompletionRecords(this.get("consequent"), paths); paths = addCompletionRecords(this.get("alternate"), paths); } else if (this.isDoExpression() || this.isFor() || this.isWhile()) { paths = addCompletionRecords(this.get("body"), paths); } else if (this.isProgram() || this.isBlockStatement()) { paths = addCompletionRecords(this.get("body").pop(), paths); } else if (this.isFunction()) { return this.get("body").getCompletionRecords(); } else if (this.isTryStatement()) { paths = addCompletionRecords(this.get("block"), paths); paths = addCompletionRecords(this.get("handler"), paths); } else if (this.isCatchClause()) { paths = addCompletionRecords(this.get("body"), paths); } else if (this.isSwitchStatement()) { paths = completionRecordForSwitch(this.get("cases"), paths); } else { paths.push(this); } return paths; } function getSibling(key) { return _index.default.get({ parentPath: this.parentPath, parent: this.parent, container: this.container, listKey: this.listKey, key: key }); } function getPrevSibling() { return this.getSibling(this.key - 1); } function getNextSibling() { return this.getSibling(this.key + 1); } function getAllNextSiblings() { let _key = this.key; let sibling = this.getSibling(++_key); const siblings = []; while (sibling.node) { siblings.push(sibling); sibling = this.getSibling(++_key); } return siblings; } function getAllPrevSiblings() { let _key = this.key; let sibling = this.getSibling(--_key); const siblings = []; while (sibling.node) { siblings.push(sibling); sibling = this.getSibling(--_key); } return siblings; } function get(key, context) { if (context === true) context = this.context; const parts = key.split("."); if (parts.length === 1) { return this._getKey(key, context); } else { return this._getPattern(parts, context); } } function _getKey(key, context) { const node = this.node; const container = node[key]; if (Array.isArray(container)) { return container.map((_, i) => { return _index.default.get({ listKey: key, parentPath: this, parent: node, container: container, key: i }).setContext(context); }); } else { return _index.default.get({ parentPath: this, parent: node, container: node, key: key }).setContext(context); } } function _getPattern(parts, context) { let path = this; for (const part of parts) { if (part === ".") { path = path.parentPath; } else { if (Array.isArray(path)) { path = path[part]; } else { path = path.get(part, context); } } } return path; } function getBindingIdentifiers(duplicates) { return t.getBindingIdentifiers(this.node, duplicates); } function getOuterBindingIdentifiers(duplicates) { return t.getOuterBindingIdentifiers(this.node, duplicates); } function getBindingIdentifierPaths(duplicates = false, outerOnly = false) { const path = this; let search = [].concat(path); const ids = Object.create(null); while (search.length) { const id = search.shift(); if (!id) continue; if (!id.node) continue; const keys = t.getBindingIdentifiers.keys[id.node.type]; if (id.isIdentifier()) { if (duplicates) { const _ids = ids[id.node.name] = ids[id.node.name] || []; _ids.push(id); } else { ids[id.node.name] = id; } continue; } if (id.isExportDeclaration()) { const declaration = id.get("declaration"); if (declaration.isDeclaration()) { search.push(declaration); } continue; } if (outerOnly) { if (id.isFunctionDeclaration()) { search.push(id.get("id")); continue; } if (id.isFunctionExpression()) { continue; } } if (keys) { for (let i = 0; i < keys.length; i++) { const key = keys[i]; const child = id.get(key); if (Array.isArray(child) || child.node) { search = search.concat(child); } } } } return ids; } function getOuterBindingIdentifierPaths(duplicates) { return this.getBindingIdentifierPaths(duplicates, true); }