UNPKG

grasp-equery

Version:

grasp query using example code with wildcards

247 lines (246 loc) 6.87 kB
// Generated by LiveScript 1.5.0 (function(){ var parser, ref$, aliasMap, matchesMap, matchesAliasMap, literalMap, getNodeAtPath, toString$ = {}.toString; parser = require('flow-parser'); ref$ = require('grasp-syntax-javascript'), aliasMap = ref$.aliasMap, matchesMap = ref$.matchesMap, matchesAliasMap = ref$.matchesAliasMap, literalMap = ref$.literalMap; getNodeAtPath = require('./common').getNodeAtPath; function parse(selector){ var attempts, i$, len$, attempt, code, parserOptions, parsedSelector, path, e, selectorBody, extractedSelector, finalSelector, root; attempts = [ { code: selector, path: [] }, { code: "function f(){ " + selector + "; }", path: ['body', 'body', 0] }, { code: "function* f(){ " + selector + "; }", path: ['body', 'body', 0] }, { code: "(" + selector + ")", path: [] }, { code: "while (true) { " + selector + "; }", path: ['body', 'body', 0] }, { code: "switch (x) { " + selector + " }", path: ['cases', 0] }, { code: "try { } " + selector, path: ['handlers', 0] } ]; for (i$ = 0, len$ = attempts.length; i$ < len$; ++i$) { attempt = attempts[i$], code = attempt.code; try { parserOptions = { sourceType: 'module' }; parsedSelector = parser.parse(code, parserOptions); path = attempt.path; break; } catch (e$) { e = e$; continue; } } if (!parsedSelector) { throw new Error("Error processing selector '" + selector + "'."); } selectorBody = parsedSelector.body; if (selectorBody.length > 1) { throw new Error("Selector body can't be more than one statement"); } extractedSelector = getNodeAtPath(selectorBody[0], path); finalSelector = extractedSelector.type === 'ExpressionStatement' && !/;\s*$/.test(selector) ? extractedSelector.expression : extractedSelector; root = { type: 'Root', value: finalSelector }; processSelector(root); return root.value; } function processSelector(ast){ var key, node, nodeType, i$, len$, i, n, that; delete ast.loc; delete ast.range; for (key in ast) { node = ast[key]; if (key !== 'type') { nodeType = toString$.call(node).slice(8, -1); if (nodeType === 'Array') { for (i$ = 0, len$ = node.length; i$ < len$; ++i$) { i = i$; n = node[i$]; if (that = processNode(n)) { node[i] = that; } else { processSelector(n); } } } else if (nodeType === 'Object') { if (that = processNode(node)) { ast[key] = that; } else { processSelector(node); } } } } } function processNode(node){ var name, that, ident, attrs, n, processedAttrs, i$, len$, attr; switch (node.type) { case 'Identifier': name = node.name; if (name === '_') { return null; } else if (name === '__') { return { type: 'Grasp', graspType: 'wildcard' }; } else if (that = /^_\$(\w*)$/.exec(name)) { return { type: 'Grasp', graspType: 'array-wildcard', name: that[1] }; } else if (that = /^\$(\w+)$/.exec(name)) { return { type: 'Grasp', graspType: 'named-wildcard', name: that[1] }; } else if (that = /^_([_a-zA-Z]+)/.exec(name)) { ident = that[1].replace(/_/, '-'); if (ident in matchesMap || ident in matchesAliasMap) { return { type: 'Grasp', graspType: 'matches', value: matchesMap[matchesAliasMap[ident] || ident] }; } else if (ident in literalMap) { return { type: 'Grasp', graspType: 'literal', value: literalMap[ident] }; } else { return { type: 'Grasp', graspType: 'node-type', value: aliasMap[ident] || ident }; } } break; case 'MemberExpression': if (!node.computed) { return; } attrs = []; n = node; while (n.type === 'MemberExpression') { if (!n.computed) { return; } attrs.unshift(n.property); n = n.object; } if (n.type !== 'Identifier') { return; } ident = processNode(n); if (!ident) { return; } processedAttrs = []; for (i$ = 0, len$ = attrs.length; i$ < len$; ++i$) { attr = attrs[i$]; if (that = processAttr(attr)) { processedAttrs.push(that); } else { return; } } return { type: 'Grasp', graspType: 'compound', ident: ident, attrs: processedAttrs }; case 'ExpressionStatement': return processNode(node.expression); case 'Property': if (!(node.key.type === 'Identifier' && node.value.type === 'Identifier')) { return; } if (node.key.name === '_') { if (node.value.name === '_') { return { type: 'Grasp', graspType: 'wildcard' }; } else if (/^\$/.test(node.value.name)) { return { type: 'Grasp', graspType: 'array-wildcard', name: /^\$(\w*)$/.exec(node.value.name)[1] }; } } else if (node.key.name === '$') { return { type: 'Grasp', graspType: 'named-wildcard', name: node.value.name }; } } } function processAttr(attr){ var attrType, path, ref$; attrType = attr.type; if (attrType === 'Identifier') { if (processNode(attr)) {} else { return { path: [attr.name] }; } } else if (attrType === 'MemberExpression') { path = getMemberPath(attr); if (!path) { return; } return { path: path }; } else if ((attrType === 'AssignmentExpression' || attrType === 'BinaryExpression') && ((ref$ = attr.operator) === '=' || ref$ === '!=')) { path = getMemberPath(attr.left); if (!path) { return; } return { path: path, op: attr.operator, value: attr.right }; } } function getMemberPath(node){ var path; path = []; while (node.type === 'MemberExpression') { if (node.computed) { return; } path.unshift(node.property.name); node = node.object; } path.unshift(node.name); return path; } module.exports = { parse: parse }; }).call(this);