ecma-search
Version:
Search ECMAScript Structurally
257 lines (196 loc) • 7.24 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _traverse = _interopRequireDefault(require("@babel/traverse"));
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isSingleWildcard(node) {
return node.name === '_esSearch_' || node.type === 'ExpressionStatement' && node.expression.name === '_esSearch_' || node.type === 'JSXAttribute' && node.name.name === '_esSearch_' || node.type === 'JSXText' && node.raw === '_esSearch_' || node.type === 'JSXIdentifier' && node.name === '_esSearch_' || node.type === 'JSXExpressionContainer' && node.expression.value === '_esSearch_';
}
function isSpreadWildcard(node) {
return node.name === '_esSearchRest_' || node.type === 'ExpressionStatement' && node.expression.name === '_esSearchRest_' || node.type === 'JSXText' && node.raw === '_esSearchRest_' || node.type === 'JSXAttribute' && node.name.name === '_esSearchRest_' || node.type === 'JSXIdentifier' && node.name === '_esSearchRest_' || node.type === 'JSXExpressionContainer' && node.expression.value === '_esSearchRest_';
}
function flattenTestNode(ast) {
var flattened = [];
if (ast.left) {
flattened = flattened.concat(flattenTestNode(ast.left));
}
if (ast.right) {
flattened = flattened.concat(flattenTestNode(ast.right));
}
if (!ast.left) {
flattened.push(ast);
}
return flattened;
}
function checkForTestNodes(queryAst, toSearchAst) {
if (queryAst.test && toSearchAst.test) {
var queryFlattended = flattenTestNode(queryAst.test);
var toSearchFlattened = flattenTestNode(toSearchAst.test);
var shortCircuit = false;
var mustMatch = false;
var all = toSearchFlattened.every(function (node, index) {
var queryNode = queryFlattended[index] || {};
if (isSingleWildcard(queryNode)) {
return true;
}
if (isSpreadWildcard(queryNode)) {
shortCircuit = true;
} else if (shortCircuit || mustMatch) {
mustMatch = true;
shortCircuit = false;
if (_lodash.default.isEqual(queryNode, node)) {
mustMatch = false;
}
return true;
}
return shortCircuit || _lodash.default.isEqual(queryNode, node);
});
if (all && !mustMatch) {
return true;
}
return false;
}
}
function checkForAttributeNodes(queryAst, toSearchAst) {
if (queryAst.attributes && queryAst.attributes.length && toSearchAst.attributes && toSearchAst.attributes.length) {
var shortCircuit = false;
var mustMatch = false;
var containsWildcard = false;
var all = toSearchAst.attributes.every(function (node, index) {
var queryNode = queryAst.attributes[index] || {};
if (isSingleWildcard(queryNode)) {
return true;
}
if (isSpreadWildcard(queryNode)) {
shortCircuit = true;
containsWildcard = true;
} else if (shortCircuit || mustMatch) {
mustMatch = true;
shortCircuit = false;
if (performTreeEqualityTests(queryNode, node)) {
mustMatch = false;
}
return true;
}
return shortCircuit || performTreeEqualityTests(queryNode, node);
});
if (all && !mustMatch) {
if (queryAst.attributes.length !== toSearchAst.attributes.length) {
return containsWildcard;
}
return true;
}
return false;
}
}
function checkForChildrenNodes(queryAst, toSearchAst) {
if (queryAst.children && queryAst.children.length && toSearchAst.children && toSearchAst.children.length) {
var shortCircuit = false;
var mustMatch = false;
var containsWildcard = false; // only text nodes of substance
var queryChildren = queryAst.children.filter(function (node) {
return node.type !== 'JSXText' || node.value.trim();
});
var toSearchChildren = toSearchAst.children.filter(function (node) {
return node.type !== 'JSXText' || node.value.trim();
});
var all = toSearchChildren.every(function (node, index) {
var queryNode = queryChildren[index] || {};
if (isSingleWildcard(queryNode)) {
return true;
}
if (isSpreadWildcard(queryNode)) {
shortCircuit = true;
containsWildcard = true;
} else if (shortCircuit || mustMatch) {
mustMatch = true;
shortCircuit = false;
if (performTreeEqualityTests(queryNode, node)) {
mustMatch = false;
}
return true;
}
return shortCircuit || performTreeEqualityTests(queryNode, node);
});
if (all && !mustMatch) {
if (queryChildren.length !== toSearchChildren.length) {
return containsWildcard;
}
return true;
}
return false;
}
}
function performTreeEqualityTests(queryAst, toSearchAst) {
if (isSingleWildcard(queryAst)) {
return true;
}
if (!toSearchAst) {
return false;
} // check condition expressions
var testNodeCheck = checkForTestNodes(queryAst, toSearchAst);
if (testNodeCheck) {
return true;
} else if (testNodeCheck === false) {
return false;
} // check for JSX attributes
var attributeNodesCheck = checkForAttributeNodes(queryAst, toSearchAst);
if (attributeNodesCheck) {
return true;
} else if (attributeNodesCheck === false) {
return false;
} // check for JSX children
var childrenNodesCheck = checkForChildrenNodes(queryAst, toSearchAst);
if (childrenNodesCheck) {
return true;
} else if (childrenNodesCheck === false) {
return false;
} // consult the entire object graph
return Object.keys(queryAst).reduce(function (truth, property) {
if (!truth) {
return false;
}
if (Array.isArray(queryAst[property])) {
var shortCircuit = false;
return !queryAst[property].length || queryAst[property].every(function (node, index) {
if (isSingleWildcard(node)) {
return true;
}
if (isSpreadWildcard(node)) {
shortCircuit = true;
}
return shortCircuit || performTreeEqualityTests(node, toSearchAst[property][index]);
});
} else if (_lodash.default.isObject(queryAst[property])) {
if (isSingleWildcard(queryAst[property])) {
toSearchAst[property] = queryAst[property];
return true;
}
return performTreeEqualityTests(queryAst[property], toSearchAst[property]);
}
return property in toSearchAst && queryAst[property] == toSearchAst[property];
}, true);
}
function _default(queryAstNode, esToSearchAst) {
var results = [];
var queryClone = (0, _utils.reducer)(queryAstNode);
if (queryClone.type === 'ExpressionStatement' && queryClone.name !== '_esSearch_') {
queryClone = queryClone.expression;
}
(0, _traverse.default)(esToSearchAst, {
enter: function enter(path) {
if (queryClone.type === path.node.type) {
var nodeClone = (0, _utils.reducer)(path.node);
if (performTreeEqualityTests(queryClone, nodeClone)) {
results.push(path.node);
}
}
}
});
return results;
}
//# sourceMappingURL=loose.js.map