UNPKG

grasp-equery

Version:

grasp query using example code with wildcards

191 lines (190 loc) 6.92 kB
// Generated by LiveScript 1.5.0 (function(){ var ref$, primitiveOnlyAttributes, eitherAttributes, syntaxFlat, all, tail, getNodeAtPath, toString$ = {}.toString, slice$ = [].slice; ref$ = require('grasp-syntax-javascript'), primitiveOnlyAttributes = ref$.primitiveOnlyAttributes, eitherAttributes = ref$.eitherAttributes, syntaxFlat = ref$.syntaxFlat; ref$ = require('prelude-ls'), all = ref$.all, tail = ref$.tail; getNodeAtPath = require('./common').getNodeAtPath; function matchNode(results, query, mainNode){ var spec, i$, ref$, len$, key, j$, ref1$, len1$, subNode; if (eq(mainNode, query)) { results.push(mainNode); } spec = syntaxFlat[mainNode.type]; if (spec == null) { return; } for (i$ = 0, len$ = (ref$ = spec.nodes || []).length; i$ < len$; ++i$) { key = ref$[i$]; if (mainNode[key]) { matchNode(results, query, mainNode[key]); } } for (i$ = 0, len$ = (ref$ = spec.nodeArrays || []).length; i$ < len$; ++i$) { key = ref$[i$]; for (j$ = 0, len1$ = (ref1$ = mainNode[key]).length; j$ < len1$; ++j$) { subNode = ref1$[j$]; if (subNode) { matchNode(results, query, subNode); } } } function eq(targetNode, selectorNode){ var type, spec; if (targetNode === selectorNode) { return true; } else if (selectorNode.type === 'Grasp') { return matchSpecial(targetNode, selectorNode); } else if (selectorNode.type === targetNode.type) { type = selectorNode.type; spec = syntaxFlat[type]; if (spec == null) { return; } return all(function(it){ return eq(targetNode[it], selectorNode[it]); }, spec.nodes || []) && all(function(it){ return matchArray(targetNode[it], selectorNode[it]); }, spec.nodeArrays || []) && all(function(it){ return targetNode[it] === selectorNode[it]; }, spec.primitives || []); } else { return false; } } function matchArray(input, pattern){ var that, ref$, patternFirst, patternRest, inputFirst, inputRest, arrayWildcardName, wildcardName; if (toString$.call(pattern).slice(8, -1) === 'Object' && pattern.type === 'Grasp') { return matchSpecial(input, pattern); } if (pattern.length === 0) { return input.length === 0; } else if (pattern.length === 1) { if (that = isArrayWildcard(pattern[0])) { if (that = that.name) { mainNode._named == null && (mainNode._named = {}); (ref$ = mainNode._named)[that] == null && (ref$[that] = []); (ref$ = mainNode._named)[that] = ref$[that].concat(input); } return true; } else { return input.length === 1 && eq(input[0], pattern[0]); } } else if (input.length === 0) { return false; } else { patternFirst = pattern[0], patternRest = slice$.call(pattern, 1); inputFirst = input[0], inputRest = slice$.call(input, 1); if (that = isArrayWildcard(patternFirst)) { if (that = that.name) { arrayWildcardName = that; mainNode._named == null && (mainNode._named = {}); (ref$ = mainNode._named)[arrayWildcardName] == null && (ref$[arrayWildcardName] = []); } if (that = eq(inputFirst, patternRest[0])) { wildcardName = that; if (matchArray(inputRest, tail(patternRest))) { return true; } else { if (toString$.call(wildcardName).slice(8, -1) === 'String') { delete mainNode._named[wildcardName]; } return matchArray(inputRest, pattern); } } else { if (arrayWildcardName) { mainNode._named[arrayWildcardName].push(inputFirst); } return matchArray(inputRest, pattern); } } else { return eq(inputFirst, patternFirst) && matchArray(inputRest, patternRest); } } } function matchSpecial(targetNode, selectorNode){ var named, name, that, identMatch, attrMatch; switch (selectorNode.graspType) { case 'wildcard': return true; case 'named-wildcard': mainNode._named == null && (mainNode._named = {}); named = mainNode._named; name = selectorNode.name; if (that = named[name]) { if (eq(targetNode, that)) { return true; } else { return false; } } else { named[name] = targetNode; return name; } break; case 'node-type': return targetNode.type === selectorNode.value; case 'matches': return in$(targetNode.type, selectorNode.value); case 'literal': return targetNode.type === 'Literal' && toString$.call(targetNode.value).slice(8, -1) === selectorNode.value; case 'compound': identMatch = matchSpecial(targetNode, selectorNode.ident); attrMatch = all(matchAttr(targetNode), selectorNode.attrs); return identMatch && attrMatch; } } function isArrayWildcard(node){ var cleanNode; cleanNode = node.type === 'ExpressionStatement' ? node.expression : node; return cleanNode.type === 'Grasp' && cleanNode.graspType === 'array-wildcard' && cleanNode; } function matchAttr(targetNode){ return function(attr){ var node, attrValue, lastPath, ref$; node = getNodeAtPath(targetNode, attr.path); if (node != null) { attrValue = attr.value; if (attrValue) { lastPath = (ref$ = attr.path)[ref$.length - 1]; if (in$(lastPath, primitiveOnlyAttributes)) { return matchPrimitive(attr.op, node, attrValue); } else if (in$(lastPath, eitherAttributes)) { return matchEither(attr.op, node, attrValue); } else { return matchComplex(attr.op, node, attrValue); } } else { return true; } } else { return false; } }; } function matchPrimitive(op, node, attrValue){ if (op === '=') { return node === attrValue.value; } else { return node !== attrValue.value; } } function matchComplex(op, node, attrValue){ if (op === '=') { return eq(node, attrValue); } else { return !eq(node, attrValue); } } function matchEither(op, node, attrValue){ return matchPrimitive(op, node, attrValue) || matchComplex(op, node, attrValue); } } module.exports = { matchNode: matchNode }; function in$(x, xs){ var i = -1, l = xs.length >>> 0; while (++i < l) if (x === xs[i]) return true; return false; } }).call(this);