pax_global_header00006660000000000000000000000064136210400510014502gustar00rootroot0000000000000052 comment=cf004f240a26bb0b2de673b558889de5723444be esquery-1.1.0/000077500000000000000000000000001362104005100131765ustar00rootroot00000000000000esquery-1.1.0/.gitignore000066400000000000000000000000331362104005100151620ustar00rootroot00000000000000node_modules coverage dist esquery-1.1.0/.npmignore000066400000000000000000000000551362104005100151750ustar00rootroot00000000000000Makefile grammar.pegjs tests testRunner.html esquery-1.1.0/.travis.yml000066400000000000000000000001231362104005100153030ustar00rootroot00000000000000sudo: false language: node_js node_js: - "iojs" - "0.12" - "0.11" - "0.10" esquery-1.1.0/Makefile000066400000000000000000000010651362104005100146400ustar00rootroot00000000000000default: parser PEGJS = node_modules/.bin/pegjs --cache --export-var 'var result' CJSIFY = node_modules/.bin/cjsify parser: parser.js browser: dist/esquery.min.js parser.js: grammar.pegjs $(PEGJS) <"$<" >"$@" @echo 'if (typeof define === "function" && define.amd) { define(function(){ return result; }); } else if (typeof module !== "undefined" && module.exports) { module.exports = result; } else { this.esquery = result; }' >> "$@" dist/esquery.min.js: esquery.js parser.js @mkdir -p "$(@D)" $(CJSIFY) esquery.js -mvx esquery --source-map "$@.map" > "$@" esquery-1.1.0/README.md000066400000000000000000000041211362104005100144530ustar00rootroot00000000000000ESQuery is a library for querying the AST output by Esprima for patterns of syntax using a CSS style selector system. Check out the demo: [demo](https://estools.github.io/esquery/) The following selectors are supported: * AST node type: `ForStatement` * [wildcard](http://dev.w3.org/csswg/selectors4/#universal-selector): `*` * [attribute existence](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr]` * [attribute value](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr="foo"]` or `[attr=123]` * attribute regex: `[attr=/foo.*/]` * attribute conditions: `[attr!="foo"]`, `[attr>2]`, `[attr<3]`, `[attr>=2]`, or `[attr<=3]` * nested attribute: `[attr.level2="foo"]` * field: `FunctionDeclaration > Identifier.id` * [First](http://dev.w3.org/csswg/selectors4/#the-first-child-pseudo) or [last](http://dev.w3.org/csswg/selectors4/#the-last-child-pseudo) child: `:first-child` or `:last-child` * [nth-child](http://dev.w3.org/csswg/selectors4/#the-nth-child-pseudo) (no ax+b support): `:nth-child(2)` * [nth-last-child](http://dev.w3.org/csswg/selectors4/#the-nth-last-child-pseudo) (no ax+b support): `:nth-last-child(1)` * [descendant](http://dev.w3.org/csswg/selectors4/#descendant-combinators): `ancestor descendant` * [child](http://dev.w3.org/csswg/selectors4/#child-combinators): `parent > child` * [following sibling](http://dev.w3.org/csswg/selectors4/#general-sibling-combinators): `node ~ sibling` * [adjacent sibling](http://dev.w3.org/csswg/selectors4/#adjacent-sibling-combinators): `node + adjacent` * [negation](http://dev.w3.org/csswg/selectors4/#negation-pseudo): `:not(ForStatement)` * [has](https://drafts.csswg.org/selectors-4/#has-pseudo): `:has(ForStatement)` * [matches-any](http://dev.w3.org/csswg/selectors4/#matches): `:matches([attr] > :first-child, :last-child)` * [subject indicator](http://dev.w3.org/csswg/selectors4/#subject): `!IfStatement > [name="foo"]` * class of AST node: `:statement`, `:expression`, `:declaration`, `:function`, or `:pattern` [![Build Status](https://travis-ci.org/estools/esquery.png?branch=master)](https://travis-ci.org/estools/esquery) esquery-1.1.0/esquery.js000066400000000000000000000337641362104005100152460ustar00rootroot00000000000000/* vim: set sw=4 sts=4 : */ (function () { var estraverse = require('estraverse'); var parser = require('./parser'); var isArray = Array.isArray || function isArray(array) { return {}.toString.call(array) === '[object Array]'; }; var LEFT_SIDE = {}; var RIGHT_SIDE = {}; function esqueryModule() { /** * Get the value of a property which may be multiple levels down in the object. */ function getPath(obj, key) { var i, keys = key.split("."); for (i = 0; i < keys.length; i++) { if (obj == null) { return obj; } obj = obj[keys[i]]; } return obj; } /** * Determine whether `node` can be reached by following `path`, starting at `ancestor`. */ function inPath(node, ancestor, path) { var field, remainingPath, i; if (path.length === 0) { return node === ancestor; } if (ancestor == null) { return false; } field = ancestor[path[0]]; remainingPath = path.slice(1); if (isArray(field)) { for (i = 0, l = field.length; i < l; ++i) { if (inPath(node, field[i], remainingPath)) { return true; } } return false; } else { return inPath(node, field, remainingPath); } } /** * Given a `node` and its ancestors, determine if `node` is matched by `selector`. */ function matches(node, selector, ancestry) { var path, ancestor, i, l, p; if (!selector) { return true; } if (!node) { return false; } if (!ancestry) { ancestry = []; } switch(selector.type) { case 'wildcard': return true; case 'identifier': return selector.value.toLowerCase() === node.type.toLowerCase(); case 'field': path = selector.name.split('.'); ancestor = ancestry[path.length - 1]; return inPath(node, ancestor, path); case 'matches': for (i = 0, l = selector.selectors.length; i < l; ++i) { if (matches(node, selector.selectors[i], ancestry)) { return true; } } return false; case 'compound': for (i = 0, l = selector.selectors.length; i < l; ++i) { if (!matches(node, selector.selectors[i], ancestry)) { return false; } } return true; case 'not': for (i = 0, l = selector.selectors.length; i < l; ++i) { if (matches(node, selector.selectors[i], ancestry)) { return false; } } return true; case 'has': var a, collector = []; for (i = 0, l = selector.selectors.length; i < l; ++i) { a = []; estraverse.traverse(node, { enter: function (node, parent) { if (parent != null) { a.unshift(parent); } if (matches(node, selector.selectors[i], a)) { collector.push(node); } }, leave: function () { a.shift(); }, fallback: 'iteration' }); } return collector.length !== 0; case 'child': if (matches(node, selector.right, ancestry)) { return matches(ancestry[0], selector.left, ancestry.slice(1)); } return false; case 'descendant': if (matches(node, selector.right, ancestry)) { for (i = 0, l = ancestry.length; i < l; ++i) { if (matches(ancestry[i], selector.left, ancestry.slice(i + 1))) { return true; } } } return false; case 'attribute': p = getPath(node, selector.name); switch (selector.operator) { case null: case void 0: return p != null; case '=': switch (selector.value.type) { case 'regexp': return typeof p === 'string' && selector.value.value.test(p); case 'literal': return '' + selector.value.value === '' + p; case 'type': return selector.value.value === typeof p; } case '!=': switch (selector.value.type) { case 'regexp': return !selector.value.value.test(p); case 'literal': return '' + selector.value.value !== '' + p; case 'type': return selector.value.value !== typeof p; } case '<=': return p <= selector.value.value; case '<': return p < selector.value.value; case '>': return p > selector.value.value; case '>=': return p >= selector.value.value; } case 'sibling': return matches(node, selector.right, ancestry) && sibling(node, selector.left, ancestry, LEFT_SIDE) || selector.left.subject && matches(node, selector.left, ancestry) && sibling(node, selector.right, ancestry, RIGHT_SIDE); case 'adjacent': return matches(node, selector.right, ancestry) && adjacent(node, selector.left, ancestry, LEFT_SIDE) || selector.right.subject && matches(node, selector.left, ancestry) && adjacent(node, selector.right, ancestry, RIGHT_SIDE); case 'nth-child': return matches(node, selector.right, ancestry) && nthChild(node, ancestry, function (length) { return selector.index.value - 1; }); case 'nth-last-child': return matches(node, selector.right, ancestry) && nthChild(node, ancestry, function (length) { return length - selector.index.value; }); case 'class': if(!node.type) return false; switch(selector.name.toLowerCase()){ case 'statement': if(node.type.slice(-9) === 'Statement') return true; // fallthrough: interface Declaration <: Statement { } case 'declaration': return node.type.slice(-11) === 'Declaration'; case 'pattern': if(node.type.slice(-7) === 'Pattern') return true; // fallthrough: interface Expression <: Node, Pattern { } case 'expression': return node.type.slice(-10) === 'Expression' || node.type.slice(-7) === 'Literal' || ( node.type === 'Identifier' && (ancestry.length === 0 || ancestry[0].type !== 'MetaProperty') ) || node.type === 'MetaProperty'; case 'function': return node.type.slice(0, 8) === 'Function' || node.type === 'ArrowFunctionExpression'; } throw new Error('Unknown class name: ' + selector.name); } throw new Error('Unknown selector type: ' + selector.type); } /* * Determines if the given node has a sibling that matches the given selector. */ function sibling(node, selector, ancestry, side) { var parent = ancestry[0], listProp, startIndex, keys, i, l, k, lowerBound, upperBound; if (!parent) { return false; } keys = estraverse.VisitorKeys[parent.type]; for (i = 0, l = keys.length; i < l; ++i) { listProp = parent[keys[i]]; if (isArray(listProp)) { startIndex = listProp.indexOf(node); if (startIndex < 0) { continue; } if (side === LEFT_SIDE) { lowerBound = 0; upperBound = startIndex; } else { lowerBound = startIndex + 1; upperBound = listProp.length; } for (k = lowerBound; k < upperBound; ++k) { if (matches(listProp[k], selector, ancestry)) { return true; } } } } return false; } /* * Determines if the given node has an adjacent sibling that matches the given selector. */ function adjacent(node, selector, ancestry, side) { var parent = ancestry[0], listProp, keys, i, l, idx; if (!parent) { return false; } keys = estraverse.VisitorKeys[parent.type]; for (i = 0, l = keys.length; i < l; ++i) { listProp = parent[keys[i]]; if (isArray(listProp)) { idx = listProp.indexOf(node); if (idx < 0) { continue; } if (side === LEFT_SIDE && idx > 0 && matches(listProp[idx - 1], selector, ancestry)) { return true; } if (side === RIGHT_SIDE && idx < listProp.length - 1 && matches(listProp[idx + 1], selector, ancestry)) { return true; } } } return false; } /* * Determines if the given node is the nth child, determined by idxFn, which is given the containing list's length. */ function nthChild(node, ancestry, idxFn) { var parent = ancestry[0], listProp, keys, i, l, idx; if (!parent) { return false; } keys = estraverse.VisitorKeys[parent.type]; for (i = 0, l = keys.length; i < l; ++i) { listProp = parent[keys[i]]; if (isArray(listProp)) { idx = listProp.indexOf(node); if (idx >= 0 && idx === idxFn(listProp.length)) { return true; } } } return false; } /* * For each selector node marked as a subject, find the portion of the selector that the subject must match. */ function subjects(selector, ancestor) { var results, p; if (selector == null || typeof selector != 'object') { return []; } if (ancestor == null) { ancestor = selector; } results = selector.subject ? [ancestor] : []; for(p in selector) { if(!{}.hasOwnProperty.call(selector, p)) { continue; } [].push.apply(results, subjects(selector[p], p === 'left' ? selector[p] : ancestor)); } return results; } /** * From a JS AST and a selector AST, collect all JS AST nodes that match the selector. */ function match(ast, selector) { var ancestry = [], results = [], altSubjects, i, l, k, m; if (!selector) { return results; } altSubjects = subjects(selector); estraverse.traverse(ast, { enter: function (node, parent) { if (parent != null) { ancestry.unshift(parent); } if (matches(node, selector, ancestry)) { if (altSubjects.length) { for (i = 0, l = altSubjects.length; i < l; ++i) { if (matches(node, altSubjects[i], ancestry)) { results.push(node); } for (k = 0, m = ancestry.length; k < m; ++k) { if (matches(ancestry[k], altSubjects[i], ancestry.slice(k + 1))) { results.push(ancestry[k]); } } } } else { results.push(node); } } }, leave: function () { ancestry.shift(); }, fallback: 'iteration' }); return results; } /** * Parse a selector string and return its AST. */ function parse(selector) { return parser.parse(selector); } /** * Query the code AST using the selector string. */ function query(ast, selector) { return match(ast, parse(selector)); } query.parse = parse; query.match = match; query.matches = matches; return query.query = query; } if (typeof define === "function" && define.amd) { define(esqueryModule); } else if (typeof module !== 'undefined' && module.exports) { module.exports = esqueryModule(); } else { this.esquery = esqueryModule(); } })(); esquery-1.1.0/grammar.pegjs000066400000000000000000000071571362104005100156700ustar00rootroot00000000000000{ function nth(n) { return { type: 'nth-child', index: { type: 'literal', value: n } }; } function nthLast(n) { return { type: 'nth-last-child', index: { type: 'literal', value: n } }; } function strUnescape(s) { return s.replace(/\\(.)/g, function(match, ch) { switch(ch) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; default: return ch; } }); } } start = _ ss:selectors _ { return ss.length === 1 ? ss[0] : { type: 'matches', selectors: ss }; } / _ { return void 0; } _ = " "* identifierName = i:[^ [\],():#!=><~+.]+ { return i.join(''); } binaryOp = _ ">" _ { return 'child'; } / _ "~" _ { return 'sibling'; } / _ "+" _ { return 'adjacent'; } / " " _ { return 'descendant'; } selectors = s:selector ss:(_ "," _ selector)* { return [s].concat(ss.map(function (s) { return s[3]; })); } selector = a:sequence ops:(binaryOp sequence)* { return ops.reduce(function (memo, rhs) { return { type: rhs[0], left: memo, right: rhs[1] }; }, a); } sequence = subject:"!"? as:atom+ { var b = as.length === 1 ? as[0] : { type: 'compound', selectors: as }; if(subject) b.subject = true; return b; } atom = wildcard / identifier / attr / field / negation / matches / has / firstChild / lastChild / nthChild / nthLastChild / class wildcard = a:"*" { return { type: 'wildcard', value: a }; } identifier = "#"? i:identifierName { return { type: 'identifier', value: i }; } attr = "[" _ v:attrValue _ "]" { return v; } attrOps = a:[><] attrEqOps = a:"!"? "=" { return a + '='; } attrName = i:(identifierName / ".")+ { return i.join(''); } attrValue = name:attrName _ op:attrEqOps _ value:(type / regex) { return { type: 'attribute', name: name, operator: op, value: value }; } / name:attrName _ op:attrOps _ value:(string / number / path) { return { type: 'attribute', name: name, operator: op, value: value }; } / name:attrName { return { type: 'attribute', name: name }; } string = "\"" d:([^\\"] / a:"\\" b:. { return a + b; })* "\"" { return { type: 'literal', value: strUnescape(d.join('')) }; } / "'" d:([^\\'] / a:"\\" b:. { return a + b; })* "'" { return { type: 'literal', value: strUnescape(d.join('')) }; } number = a:([0-9]* ".")? b:[0-9]+ { return { type: 'literal', value: parseFloat((a ? a.join('') : '') + b.join('')) }; } path = i:identifierName { return { type: 'literal', value: i }; } type = "type(" _ t:[^ )]+ _ ")" { return { type: 'type', value: t.join('') }; } regex = "/" d:[^/]+ "/" { return { type: 'regexp', value: new RegExp(d.join('')) }; } field = "." i:identifierName is:("." identifierName)* { return { type: 'field', name: is.reduce(function(memo, p){ return memo + p[0] + p[1]; }, i)}; } negation = ":not(" _ ss:selectors _ ")" { return { type: 'not', selectors: ss }; } matches = ":matches(" _ ss:selectors _ ")" { return { type: 'matches', selectors: ss }; } has = ":has(" _ ss:selectors _ ")" { return { type: 'has', selectors: ss }; } firstChild = ":first-child" { return nth(1); } lastChild = ":last-child" { return nthLast(1); } nthChild = ":nth-child(" _ n:[0-9]+ _ ")" { return nth(parseInt(n.join(''), 10)); } nthLastChild = ":nth-last-child(" _ n:[0-9]+ _ ")" { return nthLast(parseInt(n.join(''), 10)); } class = ":" c:("statement"i / "expression"i / "declaration"i / "function"i / "pattern"i) { return { type: 'class', name: c }; } esquery-1.1.0/license.txt000066400000000000000000000027201362104005100153620ustar00rootroot00000000000000Copyright (c) 2013, Joel Feenstra All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the ESQuery nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOEL FEENSTRA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. esquery-1.1.0/package.json000066400000000000000000000015301362104005100154630ustar00rootroot00000000000000{ "name": "esquery", "preferGlobal": false, "version": "1.1.0", "author": "Joel Feenstra ", "description": "A query library for ECMAScript AST using a CSS selector like query language.", "main": "esquery.js", "files": [ "esquery.js", "parser.js", "license.txt", "README.md" ], "scripts": { "test": "node node_modules/jstestr/bin/jstestr.js path=tests" }, "repository": { "type": "git", "url": "https://github.com/jrfeenst/esquery.git" }, "keywords": [ "ast", "ecmascript", "javascript", "query" ], "devDependencies": { "jstestr": ">=0.4", "pegjs": "~0.7.0", "commonjs-everywhere": "~0.9.4", "esprima": "~1.1.1" }, "license": "BSD-3-Clause", "engines": { "node": ">=0.6" }, "dependencies": { "estraverse": "^4.0.0" } } esquery-1.1.0/parser.js000066400000000000000000002250451362104005100150400ustar00rootroot00000000000000var result = (function(){ /* * Generated by PEG.js 0.7.0. * * http://pegjs.majda.cz/ */ function quote(s) { /* * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a * string literal except for the closing quote character, backslash, * carriage return, line separator, paragraph separator, and line feed. * Any character may appear in the form of an escape sequence. * * For portability, we also escape escape all control and non-ASCII * characters. Note that "\0" and "\v" escape sequences are not used * because JSHint does not like the first and IE the second. */ return '"' + s .replace(/\\/g, '\\\\') // backslash .replace(/"/g, '\\"') // closing quote character .replace(/\x08/g, '\\b') // backspace .replace(/\t/g, '\\t') // horizontal tab .replace(/\n/g, '\\n') // line feed .replace(/\f/g, '\\f') // form feed .replace(/\r/g, '\\r') // carriage return .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) + '"'; } var result = { /* * Parses the input with a generated parser. If the parsing is successful, * returns a value explicitly or implicitly specified by the grammar from * which the parser was generated (see |PEG.buildParser|). If the parsing is * unsuccessful, throws |PEG.parser.SyntaxError| describing the error. */ parse: function(input, startRule) { var parseFunctions = { "start": parse_start, "_": parse__, "identifierName": parse_identifierName, "binaryOp": parse_binaryOp, "selectors": parse_selectors, "selector": parse_selector, "sequence": parse_sequence, "atom": parse_atom, "wildcard": parse_wildcard, "identifier": parse_identifier, "attr": parse_attr, "attrOps": parse_attrOps, "attrEqOps": parse_attrEqOps, "attrName": parse_attrName, "attrValue": parse_attrValue, "string": parse_string, "number": parse_number, "path": parse_path, "type": parse_type, "regex": parse_regex, "field": parse_field, "negation": parse_negation, "matches": parse_matches, "has": parse_has, "firstChild": parse_firstChild, "lastChild": parse_lastChild, "nthChild": parse_nthChild, "nthLastChild": parse_nthLastChild, "class": parse_class }; if (startRule !== undefined) { if (parseFunctions[startRule] === undefined) { throw new Error("Invalid rule name: " + quote(startRule) + "."); } } else { startRule = "start"; } var pos = 0; var reportFailures = 0; var rightmostFailuresPos = 0; var rightmostFailuresExpected = []; var cache = {}; function padLeft(input, padding, length) { var result = input; var padLength = length - input.length; for (var i = 0; i < padLength; i++) { result = padding + result; } return result; } function escape(ch) { var charCode = ch.charCodeAt(0); var escapeChar; var length; if (charCode <= 0xFF) { escapeChar = 'x'; length = 2; } else { escapeChar = 'u'; length = 4; } return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); } function matchFailed(failure) { if (pos < rightmostFailuresPos) { return; } if (pos > rightmostFailuresPos) { rightmostFailuresPos = pos; rightmostFailuresExpected = []; } rightmostFailuresExpected.push(failure); } function parse_start() { var cacheKey = "start@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse__(); if (result0 !== null) { result1 = parse_selectors(); if (result1 !== null) { result2 = parse__(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, ss) { return ss.length === 1 ? ss[0] : { type: 'matches', selectors: ss }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; result0 = parse__(); if (result0 !== null) { result0 = (function(offset) { return void 0; })(pos0); } if (result0 === null) { pos = pos0; } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse__() { var cacheKey = "_@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; result0 = []; if (input.charCodeAt(pos) === 32) { result1 = " "; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\" \""); } } while (result1 !== null) { result0.push(result1); if (input.charCodeAt(pos) === 32) { result1 = " "; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\" \""); } } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_identifierName() { var cacheKey = "identifierName@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0; pos0 = pos; if (/^[^ [\],():#!=><~+.]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[^ [\\],():#!=><~+.]"); } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); if (/^[^ [\],():#!=><~+.]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[^ [\\],():#!=><~+.]"); } } } } else { result0 = null; } if (result0 !== null) { result0 = (function(offset, i) { return i.join(''); })(pos0, result0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_binaryOp() { var cacheKey = "binaryOp@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse__(); if (result0 !== null) { if (input.charCodeAt(pos) === 62) { result1 = ">"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\">\""); } } if (result1 !== null) { result2 = parse__(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset) { return 'child'; })(pos0); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; result0 = parse__(); if (result0 !== null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } if (result1 !== null) { result2 = parse__(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset) { return 'sibling'; })(pos0); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; result0 = parse__(); if (result0 !== null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 !== null) { result2 = parse__(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset) { return 'adjacent'; })(pos0); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 32) { result0 = " "; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\" \""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset) { return 'descendant'; })(pos0); } if (result0 === null) { pos = pos0; } } } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_selectors() { var cacheKey = "selectors@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4, result5; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_selector(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse__(); if (result2 !== null) { if (input.charCodeAt(pos) === 44) { result3 = ","; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result3 !== null) { result4 = parse__(); if (result4 !== null) { result5 = parse_selector(); if (result5 !== null) { result2 = [result2, result3, result4, result5]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse__(); if (result2 !== null) { if (input.charCodeAt(pos) === 44) { result3 = ","; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result3 !== null) { result4 = parse__(); if (result4 !== null) { result5 = parse_selector(); if (result5 !== null) { result2 = [result2, result3, result4, result5]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, s, ss) { return [s].concat(ss.map(function (s) { return s[3]; })); })(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_selector() { var cacheKey = "selector@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_sequence(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_binaryOp(); if (result2 !== null) { result3 = parse_sequence(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_binaryOp(); if (result2 !== null) { result3 = parse_sequence(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, a, ops) { return ops.reduce(function (memo, rhs) { return { type: rhs[0], left: memo, right: rhs[1] }; }, a); })(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_sequence() { var cacheKey = "sequence@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 33) { result0 = "!"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result2 = parse_atom(); if (result2 !== null) { result1 = []; while (result2 !== null) { result1.push(result2); result2 = parse_atom(); } } else { result1 = null; } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, subject, as) { var b = as.length === 1 ? as[0] : { type: 'compound', selectors: as }; if(subject) b.subject = true; return b; })(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_atom() { var cacheKey = "atom@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0; result0 = parse_wildcard(); if (result0 === null) { result0 = parse_identifier(); if (result0 === null) { result0 = parse_attr(); if (result0 === null) { result0 = parse_field(); if (result0 === null) { result0 = parse_negation(); if (result0 === null) { result0 = parse_matches(); if (result0 === null) { result0 = parse_has(); if (result0 === null) { result0 = parse_firstChild(); if (result0 === null) { result0 = parse_lastChild(); if (result0 === null) { result0 = parse_nthChild(); if (result0 === null) { result0 = parse_nthLastChild(); if (result0 === null) { result0 = parse_class(); } } } } } } } } } } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_wildcard() { var cacheKey = "wildcard@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0; var pos0; pos0 = pos; if (input.charCodeAt(pos) === 42) { result0 = "*"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result0 !== null) { result0 = (function(offset, a) { return { type: 'wildcard', value: a }; })(pos0, result0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_identifier() { var cacheKey = "identifier@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 35) { result0 = "#"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"#\""); } } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result1 = parse_identifierName(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, i) { return { type: 'identifier', value: i }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_attr() { var cacheKey = "attr@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 91) { result0 = "["; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_attrValue(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 93) { result4 = "]"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, v) { return v; })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_attrOps() { var cacheKey = "attrOps@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (/^[><]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[><]"); } } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_attrEqOps() { var cacheKey = "attrEqOps@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 33) { result0 = "!"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, a) { return a + '='; })(pos0, result0[0]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_attrName() { var cacheKey = "attrName@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0; pos0 = pos; result1 = parse_identifierName(); if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_identifierName(); if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } } } } else { result0 = null; } if (result0 !== null) { result0 = (function(offset, i) { return i.join(''); })(pos0, result0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_attrValue() { var cacheKey = "attrValue@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_attrName(); if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_attrEqOps(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { result4 = parse_type(); if (result4 === null) { result4 = parse_regex(); } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, name, op, value) { return { type: 'attribute', name: name, operator: op, value: value }; })(pos0, result0[0], result0[2], result0[4]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; result0 = parse_attrName(); if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_attrOps(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { result4 = parse_string(); if (result4 === null) { result4 = parse_number(); if (result4 === null) { result4 = parse_path(); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, name, op, value) { return { type: 'attribute', name: name, operator: op, value: value }; })(pos0, result0[0], result0[2], result0[4]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; result0 = parse_attrName(); if (result0 !== null) { result0 = (function(offset, name) { return { type: 'attribute', name: name }; })(pos0, result0); } if (result0 === null) { pos = pos0; } } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_string() { var cacheKey = "string@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3; var pos0, pos1, pos2, pos3; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 34) { result0 = "\""; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"\\\"\""); } } if (result0 !== null) { result1 = []; if (/^[^\\"]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\\\\"]"); } } if (result2 === null) { pos2 = pos; pos3 = pos; if (input.charCodeAt(pos) === 92) { result2 = "\\"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result2 !== null) { if (input.length > pos) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("any character"); } } if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos3; } } else { result2 = null; pos = pos3; } if (result2 !== null) { result2 = (function(offset, a, b) { return a + b; })(pos2, result2[0], result2[1]); } if (result2 === null) { pos = pos2; } } while (result2 !== null) { result1.push(result2); if (/^[^\\"]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\\\\"]"); } } if (result2 === null) { pos2 = pos; pos3 = pos; if (input.charCodeAt(pos) === 92) { result2 = "\\"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result2 !== null) { if (input.length > pos) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("any character"); } } if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos3; } } else { result2 = null; pos = pos3; } if (result2 !== null) { result2 = (function(offset, a, b) { return a + b; })(pos2, result2[0], result2[1]); } if (result2 === null) { pos = pos2; } } } if (result1 !== null) { if (input.charCodeAt(pos) === 34) { result2 = "\""; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"\\\"\""); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, d) { return { type: 'literal', value: strUnescape(d.join('')) }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 39) { result0 = "'"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result0 !== null) { result1 = []; if (/^[^\\']/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\\\']"); } } if (result2 === null) { pos2 = pos; pos3 = pos; if (input.charCodeAt(pos) === 92) { result2 = "\\"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result2 !== null) { if (input.length > pos) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("any character"); } } if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos3; } } else { result2 = null; pos = pos3; } if (result2 !== null) { result2 = (function(offset, a, b) { return a + b; })(pos2, result2[0], result2[1]); } if (result2 === null) { pos = pos2; } } while (result2 !== null) { result1.push(result2); if (/^[^\\']/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\\\']"); } } if (result2 === null) { pos2 = pos; pos3 = pos; if (input.charCodeAt(pos) === 92) { result2 = "\\"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result2 !== null) { if (input.length > pos) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("any character"); } } if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos3; } } else { result2 = null; pos = pos3; } if (result2 !== null) { result2 = (function(offset, a, b) { return a + b; })(pos2, result2[0], result2[1]); } if (result2 === null) { pos = pos2; } } } if (result1 !== null) { if (input.charCodeAt(pos) === 39) { result2 = "'"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, d) { return { type: 'literal', value: strUnescape(d.join('')) }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_number() { var cacheKey = "number@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; pos2 = pos; result0 = []; if (/^[0-9]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } while (result1 !== null) { result0.push(result1); if (/^[0-9]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } } if (result0 !== null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos2; } } else { result0 = null; pos = pos2; } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { if (/^[0-9]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } if (result2 !== null) { result1 = []; while (result2 !== null) { result1.push(result2); if (/^[0-9]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } } } else { result1 = null; } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, a, b) { return { type: 'literal', value: parseFloat((a ? a.join('') : '') + b.join('')) }; })(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_path() { var cacheKey = "path@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0; var pos0; pos0 = pos; result0 = parse_identifierName(); if (result0 !== null) { result0 = (function(offset, i) { return { type: 'literal', value: i }; })(pos0, result0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_type() { var cacheKey = "type@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5) === "type(") { result0 = "type("; pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"type(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { if (/^[^ )]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[^ )]"); } } if (result3 !== null) { result2 = []; while (result3 !== null) { result2.push(result3); if (/^[^ )]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[^ )]"); } } } } else { result2 = null; } if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, t) { return { type: 'type', value: t.join('') }; })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_regex() { var cacheKey = "regex@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 !== null) { if (/^[^\/]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\/]"); } } if (result2 !== null) { result1 = []; while (result2 !== null) { result1.push(result2); if (/^[^\/]/.test(input.charAt(pos))) { result2 = input.charAt(pos); pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("[^\\/]"); } } } } else { result1 = null; } if (result1 !== null) { if (input.charCodeAt(pos) === 47) { result2 = "/"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, d) { return { type: 'regexp', value: new RegExp(d.join('')) }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_field() { var cacheKey = "field@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 46) { result0 = "."; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result0 !== null) { result1 = parse_identifierName(); if (result1 !== null) { result2 = []; pos2 = pos; if (input.charCodeAt(pos) === 46) { result3 = "."; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result3 !== null) { result4 = parse_identifierName(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } while (result3 !== null) { result2.push(result3); pos2 = pos; if (input.charCodeAt(pos) === 46) { result3 = "."; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result3 !== null) { result4 = parse_identifierName(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, i, is) { return { type: 'field', name: is.reduce(function(memo, p){ return memo + p[0] + p[1]; }, i)}; })(pos0, result0[1], result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_negation() { var cacheKey = "negation@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5) === ":not(") { result0 = ":not("; pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":not(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_selectors(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, ss) { return { type: 'not', selectors: ss }; })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_matches() { var cacheKey = "matches@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 9) === ":matches(") { result0 = ":matches("; pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":matches(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_selectors(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, ss) { return { type: 'matches', selectors: ss }; })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_has() { var cacheKey = "has@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5) === ":has(") { result0 = ":has("; pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":has(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { result2 = parse_selectors(); if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, ss) { return { type: 'has', selectors: ss }; })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_firstChild() { var cacheKey = "firstChild@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0; var pos0; pos0 = pos; if (input.substr(pos, 12) === ":first-child") { result0 = ":first-child"; pos += 12; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":first-child\""); } } if (result0 !== null) { result0 = (function(offset) { return nth(1); })(pos0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_lastChild() { var cacheKey = "lastChild@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0; var pos0; pos0 = pos; if (input.substr(pos, 11) === ":last-child") { result0 = ":last-child"; pos += 11; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":last-child\""); } } if (result0 !== null) { result0 = (function(offset) { return nthLast(1); })(pos0); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_nthChild() { var cacheKey = "nthChild@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 11) === ":nth-child(") { result0 = ":nth-child("; pos += 11; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":nth-child(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { if (/^[0-9]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } if (result3 !== null) { result2 = []; while (result3 !== null) { result2.push(result3); if (/^[0-9]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } } } else { result2 = null; } if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, n) { return nth(parseInt(n.join(''), 10)); })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_nthLastChild() { var cacheKey = "nthLastChild@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 16) === ":nth-last-child(") { result0 = ":nth-last-child("; pos += 16; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":nth-last-child(\""); } } if (result0 !== null) { result1 = parse__(); if (result1 !== null) { if (/^[0-9]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } if (result3 !== null) { result2 = []; while (result3 !== null) { result2.push(result3); if (/^[0-9]/.test(input.charAt(pos))) { result3 = input.charAt(pos); pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } } } else { result2 = null; } if (result2 !== null) { result3 = parse__(); if (result3 !== null) { if (input.charCodeAt(pos) === 41) { result4 = ")"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, n) { return nthLast(parseInt(n.join(''), 10)); })(pos0, result0[2]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function parse_class() { var cacheKey = "class@" + pos; var cachedResult = cache[cacheKey]; if (cachedResult) { pos = cachedResult.nextPos; return cachedResult.result; } var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 !== null) { if (input.substr(pos, 9).toLowerCase() === "statement") { result1 = input.substr(pos, 9); pos += 9; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"statement\""); } } if (result1 === null) { if (input.substr(pos, 10).toLowerCase() === "expression") { result1 = input.substr(pos, 10); pos += 10; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"expression\""); } } if (result1 === null) { if (input.substr(pos, 11).toLowerCase() === "declaration") { result1 = input.substr(pos, 11); pos += 11; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"declaration\""); } } if (result1 === null) { if (input.substr(pos, 8).toLowerCase() === "function") { result1 = input.substr(pos, 8); pos += 8; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"function\""); } } if (result1 === null) { if (input.substr(pos, 7).toLowerCase() === "pattern") { result1 = input.substr(pos, 7); pos += 7; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"pattern\""); } } } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = (function(offset, c) { return { type: 'class', name: c }; })(pos0, result0[1]); } if (result0 === null) { pos = pos0; } cache[cacheKey] = { nextPos: pos, result: result0 }; return result0; } function cleanupExpected(expected) { expected.sort(); var lastExpected = null; var cleanExpected = []; for (var i = 0; i < expected.length; i++) { if (expected[i] !== lastExpected) { cleanExpected.push(expected[i]); lastExpected = expected[i]; } } return cleanExpected; } function computeErrorPosition() { /* * The first idea was to use |String.split| to break the input up to the * error position along newlines and derive the line and column from * there. However IE's |split| implementation is so broken that it was * enough to prevent it. */ var line = 1; var column = 1; var seenCR = false; for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) { var ch = input.charAt(i); if (ch === "\n") { if (!seenCR) { line++; } column = 1; seenCR = false; } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { line++; column = 1; seenCR = true; } else { column++; seenCR = false; } } return { line: line, column: column }; } function nth(n) { return { type: 'nth-child', index: { type: 'literal', value: n } }; } function nthLast(n) { return { type: 'nth-last-child', index: { type: 'literal', value: n } }; } function strUnescape(s) { return s.replace(/\\(.)/g, function(match, ch) { switch(ch) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; default: return ch; } }); } var result = parseFunctions[startRule](); /* * The parser is now in one of the following three states: * * 1. The parser successfully parsed the whole input. * * - |result !== null| * - |pos === input.length| * - |rightmostFailuresExpected| may or may not contain something * * 2. The parser successfully parsed only a part of the input. * * - |result !== null| * - |pos < input.length| * - |rightmostFailuresExpected| may or may not contain something * * 3. The parser did not successfully parse any part of the input. * * - |result === null| * - |pos === 0| * - |rightmostFailuresExpected| contains at least one failure * * All code following this comment (including called functions) must * handle these states. */ if (result === null || pos !== input.length) { var offset = Math.max(pos, rightmostFailuresPos); var found = offset < input.length ? input.charAt(offset) : null; var errorPosition = computeErrorPosition(); throw new this.SyntaxError( cleanupExpected(rightmostFailuresExpected), found, offset, errorPosition.line, errorPosition.column ); } return result; }, /* Returns the parser source code. */ toSource: function() { return this._source; } }; /* Thrown when a parser encounters a syntax error. */ result.SyntaxError = function(expected, found, offset, line, column) { function buildMessage(expected, found) { var expectedHumanized, foundHumanized; switch (expected.length) { case 0: expectedHumanized = "end of input"; break; case 1: expectedHumanized = expected[0]; break; default: expectedHumanized = expected.slice(0, expected.length - 1).join(", ") + " or " + expected[expected.length - 1]; } foundHumanized = found ? quote(found) : "end of input"; return "Expected " + expectedHumanized + " but " + foundHumanized + " found."; } this.name = "SyntaxError"; this.expected = expected; this.found = found; this.message = buildMessage(expected, found); this.offset = offset; this.line = line; this.column = column; }; result.SyntaxError.prototype = Error.prototype; return result; })(); if (typeof define === "function" && define.amd) { define(function(){ return result; }); } else if (typeof module !== "undefined" && module.exports) { module.exports = result; } else { this.esquery = result; } esquery-1.1.0/testRunner.html000066400000000000000000000023121362104005100162330ustar00rootroot00000000000000 Test Runner
esquery-1.1.0/tests/000077500000000000000000000000001362104005100143405ustar00rootroot00000000000000esquery-1.1.0/tests/fixtures/000077500000000000000000000000001362104005100162115ustar00rootroot00000000000000esquery-1.1.0/tests/fixtures/allClasses.js000066400000000000000000000113061362104005100206360ustar00rootroot00000000000000define(["esprima"], function (esprima) { // return esprima.parse("function a(){ [a] = () => 0; new.target; `test`; `hello,${name}`; }"); return { "type": "Program", "body": [ { "type": "FunctionDeclaration", "id": { "type": "Identifier", "name": "a" }, "params": [], "defaults": [], "body": { "type": "BlockStatement", "body": [ { "type": "ExpressionStatement", "expression": { "type": "AssignmentExpression", "operator": "=", "left": { "type": "ArrayPattern", "elements": [ { "type": "Identifier", "name": "a" } ] }, "right": { "type": "ArrowFunctionExpression", "params": [], "defaults": [], "rest": null, "body": { "type": "Literal", "value": 0, "raw": "0" }, "generator": false, "expression": false } } }, { "type": "ExpressionStatement", "expression": { "type": "MetaProperty", "meta": { "type": "Identifier", "name": "new", }, "property": { "type": "Identifier", "name": "target", }, }, }, { "type": "ExpressionStatement", "expression": { "type": "TemplateLiteral", "quasis": [ { "type": "TemplateElement", "value": { "raw": "test", "cooked": "test" }, "tail": true, } ], "expressions": [], }, }, { "type": "ExpressionStatement", "expression": { "type": "TemplateLiteral", "quasis": [ { "type": "TemplateElement", "value": { "raw": "hello,", "cooked": "hello," }, "tail": false, }, { "type": "TemplateElement", "value": { "raw": "", "cooked": "" }, "tail": true, } ], "expressions": [ { "type": "Identifier", "name": "name", } ], }, } ] }, "rest": null, "generator": false, "expression": false } ] }; }); esquery-1.1.0/tests/fixtures/bigArray.js000066400000000000000000000002011362104005100203000ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( '[1, 2, 3, foo, bar, 4, 5, baz, qux, 6]' ); }); esquery-1.1.0/tests/fixtures/conditional.js000066400000000000000000000003251362104005100210520ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "if (x === 1) { foo(); } else { x = 2; }\n" + "if (x == 'test' && true || x) { y = -1; } else if (false) { y = 1; }" ); }); esquery-1.1.0/tests/fixtures/forLoop.js000066400000000000000000000001731362104005100201700ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse("for (i = 0; i < foo.length; i++) { foo[i](); }"); }); esquery-1.1.0/tests/fixtures/nestedFunctions.js000066400000000000000000000003441362104005100217230ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "function foo() {\n" + " var x = 1;\n" + " function bar() {\n" + " x = 2;\n" + " }\n" + "}\n" ); }); esquery-1.1.0/tests/fixtures/simpleFunction.js000066400000000000000000000003171362104005100215470ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "function foo(x, y) {\n" + " var z = x + y;\n" + " z++;\n" + " return z;\n" + "}\n" ); }); esquery-1.1.0/tests/fixtures/simpleProgram.js000066400000000000000000000002761362104005100213750ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "var x = 1;\n" + "var y = 'y';\n" + "x = x * 2;\n" + "if (y) { y += 'z'; }\n" ); }); esquery-1.1.0/tests/fixtures/switchStatement.js000066400000000000000000000004071362104005100217360ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "var x = 1;\n" + "switch (x) {\n" + " case 0: foo1(); break;\n" + " case 1: foo2(); break;\n" + " default: x = 1; break;\n" + "}\n" ); }); esquery-1.1.0/tests/fixtures/unknownNodeTypeAST.js000066400000000000000000000004631362104005100222710ustar00rootroot00000000000000/* * This pretends (badly) to be a TypeAlias type node, which would normally be generated by flow-parser from the following code: * * type aType = {}; * */ define(["esprima"], function(esprima) { var program = esprima.parse("var x = 's'"); program.body[0].type = 'TypeAlias'; return program; }); esquery-1.1.0/tests/fixtures/whileLoop.js000066400000000000000000000002071362104005100205100ustar00rootroot00000000000000define(["esprima"], function (esprima) { return esprima.parse( "x = 10;\n" + "while (x > 0) { x--; }" ); }); esquery-1.1.0/tests/parser.js000066400000000000000000000014031362104005100161700ustar00rootroot00000000000000define([ "esquery", "jstestr/assert", "jstestr/test", ], function (esquery, assert, test) { test.defineSuite("basic query parsing", { "empty query": function () { assert.isEqual(void 0, esquery.parse("")); assert.isEqual(void 0, esquery.parse(" ")); }, "leading/trailing whitespace": function () { assert.isNotEqual(void 0, esquery.parse(" A")); assert.isNotEqual(void 0, esquery.parse(" A")); assert.isNotEqual(void 0, esquery.parse("A ")); assert.isNotEqual(void 0, esquery.parse("A ")); assert.isNotEqual(void 0, esquery.parse(" A ")); assert.isNotEqual(void 0, esquery.parse(" A ")); } }); }); esquery-1.1.0/tests/queryAttribute.js000066400000000000000000000175651362104005100177450ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Attribute query", { "conditional": function () { var matches = esquery(conditional, "[name=\"x\"]"); assert.contains([ conditional.body[0].test.left, conditional.body[0].alternate.body[0].expression.left, conditional.body[1].test.left.left.left, conditional.body[1].test.right ], matches); matches = esquery(conditional, "[callee.name=\"foo\"]"); assert.contains([ conditional.body[0].consequent.body[0].expression ], matches); matches = esquery(conditional, "[operator]"); assert.contains([ conditional.body[0].test, conditional.body[0].alternate.body[0].expression, conditional.body[1].test, conditional.body[1].test.left, conditional.body[1].test.left.left ], matches); matches = esquery(conditional, "[prefix=true]"); assert.contains([ conditional.body[1].consequent.body[0].expression.right ], matches); }, "for loop": function () { var matches = esquery(forLoop, "[operator=\"=\"]"); assert.contains([ forLoop.body[0].init ], matches); matches = esquery(forLoop, "[object.name=\"foo\"]"); assert.contains([ forLoop.body[0].test.right ], matches); matches = esquery(forLoop, "[operator]"); assert.contains([ forLoop.body[0].init, forLoop.body[0].test, forLoop.body[0].update ], matches); }, "simple function": function () { var matches = esquery(simpleFunction, "[kind=\"var\"]"); assert.contains([ simpleFunction.body[0].body.body[0] ], matches); matches = esquery(simpleFunction, "[id.name=\"foo\"]"); assert.contains([ simpleFunction.body[0] ], matches); matches = esquery(simpleFunction, "[left]"); assert.contains([ simpleFunction.body[0].body.body[0].declarations[0].init ], matches); }, "simple program": function () { var matches = esquery(simpleProgram, "[kind=\"var\"]"); assert.contains([ simpleProgram.body[0], simpleProgram.body[1] ], matches); matches = esquery(simpleProgram, "[id.name=\"y\"]"); assert.contains([ simpleProgram.body[1].declarations[0] ], matches); matches = esquery(simpleProgram, "[body]"); assert.contains([ simpleProgram, simpleProgram.body[3].consequent ], matches); }, "conditional regexp": function () { var matches = esquery(conditional, "[name=/x|foo/]"); assert.contains([ conditional.body[0].test.left, conditional.body[0].consequent.body[0].expression.callee, conditional.body[0].alternate.body[0].expression.left ], matches); }, "simple function regexp": function () { var matches = esquery(simpleFunction, "[name=/x|foo/]"); assert.contains([ simpleFunction.body[0].id, simpleFunction.body[0].params[0], simpleFunction.body[0].body.body[0].declarations[0].init.left ], matches); }, "simple function numeric": function () { var matches = esquery(simpleFunction, "FunctionDeclaration[params.0.name=x]"); assert.contains([ simpleFunction.body[0] ], matches); }, "simple program regexp": function () { var matches = esquery(simpleProgram, "[name=/[asdfy]/]"); assert.contains([ simpleProgram.body[1].declarations[0].id, simpleProgram.body[3].test, simpleProgram.body[3].consequent.body[0].expression.left ], matches); }, "for loop regexp": function () { var matches = esquery(forLoop, "[name=/i|foo/]"); assert.contains([ forLoop.body[0].init.left, forLoop.body[0].test.left, forLoop.body[0].test.right.object, forLoop.body[0].update.argument, forLoop.body[0].body.body[0].expression.callee.object, forLoop.body[0].body.body[0].expression.callee.property ], matches); }, "nonexistent attribute regexp": function () { var matches = esquery(conditional, '[foobar=/./]'); assert.isSame(0, matches.length); }, "not string": function () { var matches = esquery(conditional, '[name!="x"]'); assert.contains([ conditional.body[0].consequent.body[0].expression.callee, conditional.body[1].consequent.body[0].expression.left ], matches); }, "not type": function () { var matches = esquery(conditional, '[value!=type(number)]'); assert.contains([ conditional.body[1].test.left.left.right, conditional.body[1].test.left.right, conditional.body[1].alternate ], matches); }, "not regexp": function () { var matches = esquery(conditional, '[name!=/x|y/]'); assert.contains([ conditional.body[0].consequent.body[0].expression.callee ], matches); }, "less than": function () { var matches = esquery(conditional, "[body.length<2]"); assert.contains([ conditional.body[0].consequent, conditional.body[0].alternate, conditional.body[1].consequent, conditional.body[1].alternate.consequent ], matches); }, "greater than": function () { var matches = esquery(conditional, "[body.length>1]"); assert.contains([ conditional ], matches); }, "less than or equal": function () { var matches = esquery(conditional, "[body.length<=2]"); assert.contains([ conditional, conditional.body[0].consequent, conditional.body[0].alternate, conditional.body[1].consequent, conditional.body[1].alternate.consequent ], matches); }, "greater than or equal": function () { var matches = esquery(conditional, "[body.length>=1]"); assert.contains([ conditional, conditional.body[0].consequent, conditional.body[0].alternate, conditional.body[1].consequent, conditional.body[1].alternate.consequent ], matches); }, "attribute type": function () { var matches = esquery(conditional, "[test=type(object)]"); assert.contains([ conditional.body[0], conditional.body[1], conditional.body[1].alternate ], matches); matches = esquery(conditional, "[value=type(boolean)]"); assert.contains([ conditional.body[1].test.left.right, conditional.body[1].alternate.test ], matches); } }); }); esquery-1.1.0/tests/queryClass.js000066400000000000000000000050001362104005100170240ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/allClasses" ], function (esquery, assert, test, ast) { test.defineSuite("Class query", { ":statement": function () { var matches = esquery(ast, ":statement"); assert.contains([ ast.body[0], ast.body[0].body, ast.body[0].body.body[0], ast.body[0].body.body[1], ast.body[0].body.body[2], ast.body[0].body.body[3] ], matches); assert.isSame(6, matches.length); }, ":expression": function () { var matches = esquery(ast, ":Expression"); assert.contains([ ast.body[0].id, ast.body[0].body.body[0].expression, ast.body[0].body.body[0].expression.left.elements[0], ast.body[0].body.body[0].expression.right, ast.body[0].body.body[0].expression.right.body, ast.body[0].body.body[1].expression, ast.body[0].body.body[2].expression, ast.body[0].body.body[3].expression, ast.body[0].body.body[3].expression.expressions[0] ], matches); assert.isSame(9, matches.length); }, ":function": function () { var matches = esquery(ast, ":FUNCTION"); assert.contains([ ast.body[0], ast.body[0].body.body[0].expression.right ], matches); assert.isSame(2, matches.length); }, ":declaration": function () { var matches = esquery(ast, ":declaratioN"); assert.contains([ ast.body[0] ], matches); assert.isSame(1, matches.length); }, ":pattern": function () { var matches = esquery(ast, ":paTTern"); assert.contains([ ast.body[0].id, ast.body[0].body.body[0].expression, ast.body[0].body.body[0].expression.left, ast.body[0].body.body[0].expression.left.elements[0], ast.body[0].body.body[0].expression.right, ast.body[0].body.body[0].expression.right.body, ast.body[0].body.body[1].expression, ast.body[0].body.body[2].expression, ast.body[0].body.body[3].expression, ast.body[0].body.body[3].expression.expressions[0] ], matches); assert.isSame(10, matches.length); } }); }); esquery-1.1.0/tests/queryComplex.js000066400000000000000000000030611362104005100173730ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram", "./fixtures/nestedFunctions" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram, nestedFunctions) { test.defineSuite("Complex selector query", { "two types child": function () { var matches = esquery(conditional, "IfStatement > BinaryExpression"); assert.contains([ conditional.body[0].test ], matches); }, "three types child": function () { var matches = esquery(conditional, "IfStatement > BinaryExpression > Identifier"); assert.contains([ conditional.body[0].test.left ], matches); }, "two types descendant": function () { var matches = esquery(conditional, "IfStatement BinaryExpression"); assert.contains([ conditional.body[0].test ], matches); }, "two types sibling": function () { var matches = esquery(simpleProgram, "VariableDeclaration ~ IfStatement"); assert.contains([ simpleProgram.body[3] ], matches); }, "two types adjacent": function () { var matches = esquery(simpleProgram, "VariableDeclaration + ExpressionStatement"); assert.contains([ simpleProgram.body[2] ], matches); } }); }); esquery-1.1.0/tests/queryCompound.js000066400000000000000000000014241362104005100175510ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Compound query", { "two attributes": function () { var matches = esquery(conditional, '[left.name="x"][right.value=1]'); assert.contains([ conditional.body[0].test ], matches); }, "type and pseudo": function () { var matches = esquery(conditional, '[left.name="x"]:matches(*)'); assert.contains([ conditional.body[0].test ], matches); } }); }); esquery-1.1.0/tests/queryDescendant.js000066400000000000000000000020551362104005100200360ustar00rootroot00000000000000define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", ], function (esquery, assert, test, conditional) { test.defineSuite("Pseudo matches query", { "conditional matches": function () { var matches = esquery(conditional, "Program IfStatement"); assert.contains([ conditional.body[0], conditional.body[1], conditional.body[1].alternate ], matches); }, "#8: descendant selector includes ancestor in search": function() { var matches = esquery(conditional, "Identifier[name=x]"); assert.isSame(4, matches.length); matches = esquery(conditional, "Identifier [name=x]"); assert.isSame(0, matches.length); matches = esquery(conditional, "BinaryExpression [name=x]"); assert.isSame(2, matches.length); matches = esquery(conditional, "AssignmentExpression [name=x]"); assert.isSame(1, matches.length); } }); }); esquery-1.1.0/tests/queryField.js000066400000000000000000000016331362104005100170120ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Field query", { "single field": function () { var matches = esquery(conditional, ".test"); assert.contains([ conditional.body[0].test, conditional.body[1].test, conditional.body[1].alternate.test ], matches); }, "field sequence": function () { var matches = esquery(simpleProgram, ".declarations.init"); assert.contains([ simpleProgram.body[0].declarations[0].init, simpleProgram.body[1].declarations[0].init ], matches); } }); }); esquery-1.1.0/tests/queryHas.js000066400000000000000000000023241362104005100165000ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional" ], function (esquery, assert, test, conditional) { test.defineSuite("Parent selector query", { "conditional": function () { var matches = esquery(conditional, 'ExpressionStatement:has([name="foo"][type="Identifier"])'); assert.isEqual(1, matches.length); }, "one of": function () { var matches = esquery(conditional, 'IfStatement:has(LogicalExpression [name="foo"], LogicalExpression [name="x"])'); assert.isEqual(1, matches.length); }, "chaining": function () { var matches = esquery(conditional, 'BinaryExpression:has(Identifier[name="x"]):has(Literal[value="test"])'); assert.isEqual(1, matches.length); }, "nesting": function () { var matches = esquery(conditional, 'Program:has(IfStatement:has(Literal[value=true], Literal[value=false]))'); assert.isEqual(1, matches.length); }, "non-matching": function () { var matches = esquery(conditional, ':has([value="impossible"])'); assert.isEqual(0, matches.length); } }); }); esquery-1.1.0/tests/queryMatches.js000066400000000000000000000037071362104005100173570ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Pseudo matches query", { "conditional matches": function () { var matches = esquery(conditional, ":matches(IfStatement)"); assert.contains([ conditional.body[0], conditional.body[1].alternate ], matches); }, "for loop matches": function () { var matches = esquery(forLoop, ":matches(BinaryExpression, MemberExpression)"); assert.contains([ forLoop.body[0].test, forLoop.body[0].body.body[0].expression.callee ], matches); }, "simple function matches": function () { var matches = esquery(simpleFunction, ':matches([name="foo"], ReturnStatement)'); assert.contains([ simpleFunction.body[0].id, simpleFunction.body[0].body.body[2] ], matches); }, "simple program matches": function () { var matches = esquery(simpleProgram, ":matches(AssignmentExpression, BinaryExpression)"); assert.contains([ simpleProgram.body[2].expression, simpleProgram.body[3].consequent.body[0].expression, simpleProgram.body[2].expression.right ], matches); }, "implicit matches": function () { var matches = esquery(simpleProgram, "AssignmentExpression, BinaryExpression, NonExistant"); assert.contains([ simpleProgram.body[2].expression, simpleProgram.body[3].consequent.body[0].expression, simpleProgram.body[2].expression.right ], matches); } }); }); esquery-1.1.0/tests/queryNot.js000066400000000000000000000033511362104005100165260ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Pseudo matches query", { "conditional": function () { var matches = esquery(conditional, ":not(Literal)"); assert.isEqual(28, matches.length); }, "for loop": function () { var matches = esquery(forLoop, ':not([name="x"])'); assert.isEqual(18, matches.length); }, "simple function": function () { var matches = esquery(simpleFunction, ":not(*)"); assert.isEqual(0, matches.length); }, "simple program": function () { var matches = esquery(simpleProgram, ":not(Identifier, IfStatement)"); assert.isEqual(15, matches.length); }, "small program": function () { var program = { type: "Program", body: [{ type: "VariableDeclaration", declarations: [{ type: "VariableDeclarator", id: {type: "Identifier", name: "x"}, init: {type: "Literal", value: 1, raw: "1"} }], kind: "var" }] }; matches = esquery(program, ":not([value=1])"); assert.contains([ program, program.body[0], program.body[0].declarations[0], program.body[0].declarations[0].id ], matches); } }); }); esquery-1.1.0/tests/queryPseudoChild.js000066400000000000000000000120531362104005100201700ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Pseudo *-child query", { "conditional first child": function () { var matches = esquery(conditional, ":first-child"); assert.contains([ conditional.body[0], conditional.body[0].consequent.body[0], conditional.body[0].alternate.body[0], conditional.body[1].consequent.body[0], conditional.body[1].alternate.consequent.body[0] ], matches); }, "conditional last child": function () { var matches = esquery(conditional, ":last-child"); assert.contains([ conditional.body[1], conditional.body[0].consequent.body[0], conditional.body[0].alternate.body[0], conditional.body[1].consequent.body[0], conditional.body[1].alternate.consequent.body[0] ], matches); }, "conditional nth child": function () { var matches = esquery(conditional, ":nth-child(2)"); assert.contains([ conditional.body[1] ], matches); matches = esquery(conditional, ":nth-last-child(2)"); assert.contains([ conditional.body[0] ], matches); }, "for loop first child": function () { var matches = esquery(forLoop, ":first-child"); assert.contains([ forLoop.body[0], forLoop.body[0].body.body[0] ], matches); }, "for loop last child": function () { var matches = esquery(forLoop, ":last-child"); assert.contains([ forLoop.body[0], forLoop.body[0].body.body[0] ], matches); }, "for loop nth child": function () { var matches = esquery(forLoop, ":nth-last-child(1)"); assert.contains([ forLoop.body[0], forLoop.body[0].body.body[0] ], matches); }, "simple function first child": function () { var matches = esquery(simpleFunction, ":first-child"); assert.contains([ simpleFunction.body[0], simpleFunction.body[0].params[0], simpleFunction.body[0].body.body[0], simpleFunction.body[0].body.body[0].declarations[0] ], matches); }, "simple function last child": function () { var matches = esquery(simpleFunction, ":last-child"); assert.contains([ simpleFunction.body[0], simpleFunction.body[0].params[1], simpleFunction.body[0].body.body[2], simpleFunction.body[0].body.body[0].declarations[0] ], matches); }, "simple function nth child": function () { var matches = esquery(simpleFunction, ":nth-child(2)"); assert.contains([ simpleFunction.body[0].params[1], simpleFunction.body[0].body.body[1] ], matches); matches = esquery(simpleFunction, ":nth-child(3)"); assert.contains([ simpleFunction.body[0].body.body[2] ], matches); matches = esquery(simpleFunction, ":nth-last-child(2)"); assert.contains([ simpleFunction.body[0].params[0], simpleFunction.body[0].body.body[1] ], matches); }, "simple program first child": function () { var matches = esquery(simpleProgram, ":first-child"); assert.contains([ simpleProgram.body[0], simpleProgram.body[0].declarations[0], simpleProgram.body[1].declarations[0], simpleProgram.body[3].consequent.body[0] ], matches); }, "simple program last child": function () { var matches = esquery(simpleProgram, ":last-child"); assert.contains([ simpleProgram.body[3], simpleProgram.body[0].declarations[0], simpleProgram.body[1].declarations[0], simpleProgram.body[3].consequent.body[0] ], matches); }, "simple program nth child": function () { var matches = esquery(simpleProgram, ":nth-child(2)"); assert.contains([ simpleProgram.body[1] ], matches); matches = esquery(simpleProgram, ":nth-child(3)"); assert.contains([ simpleProgram.body[2] ], matches); matches = esquery(simpleProgram, ":nth-last-child(2)"); assert.contains([ simpleProgram.body[2] ], matches); } }); }); esquery-1.1.0/tests/querySubject.js000066400000000000000000000130051362104005100173620ustar00rootroot00000000000000define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram", "./fixtures/nestedFunctions", "./fixtures/bigArray" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram, nestedFunctions, bigArray) { test.defineSuite("Query subject", { "type subject": function () { var matches = esquery(conditional, "!IfStatement Identifier"); assert.contains([ conditional.body[0], conditional.body[1], conditional.body[1].alternate ], matches); }, "* subject": function () { var matches = esquery(forLoop, '!* > [name="foo"]'); assert.contains([ forLoop.body[0].test.right, forLoop.body[0].body.body[0].expression.callee ], matches); }, ":nth-child subject": function () { var matches = esquery(simpleFunction, '!:nth-child(1) [name="y"]'); assert.contains([ simpleFunction.body[0], simpleFunction.body[0].body.body[0], simpleFunction.body[0].body.body[0].declarations[0] ], matches); }, ":nth-last-child subject": function () { var matches = esquery(simpleProgram, '!:nth-last-child(1) [name="y"]'); assert.contains([ simpleProgram.body[3], simpleProgram.body[1].declarations[0], simpleProgram.body[3].consequent.body[0] ], matches); }, "attribute literal subject": function () { var matches = esquery(simpleProgram, '![test] [name="y"]'); assert.contains([ simpleProgram.body[3] ], matches); }, "attribute type subject": function () { var matches = esquery(nestedFunctions, '![generator=type(boolean)] > BlockStatement'); assert.contains([ nestedFunctions.body[0], nestedFunctions.body[0].body.body[1] ], matches); }, "attribute regexp subject": function () { var matches = esquery(conditional, '![operator=/=+/] > [name="x"]'); assert.contains([ conditional.body[0].test, conditional.body[0].alternate.body[0].expression, conditional.body[1].test.left.left ], matches); }, "field subject": function () { var matches = esquery(forLoop, '!.test'); assert.contains([ forLoop.body[0].test ], matches); }, ":matches subject": function () { var matches = esquery(forLoop, '!:matches(*) > [name="foo"]'); assert.contains([ forLoop.body[0].test.right, forLoop.body[0].body.body[0].expression.callee ], matches); }, ":not subject": function () { var matches = esquery(nestedFunctions, '!:not(BlockStatement) > [name="foo"]'); assert.contains([ nestedFunctions.body[0] ], matches); }, "compound attributes subject": function () { var matches = esquery(conditional, '![left.name="x"][right.value=1]'); assert.contains([ conditional.body[0].test ], matches); }, "descendant right subject": function () { var matches = esquery(forLoop, '* !AssignmentExpression'); assert.contains([ forLoop.body[0].init ], matches); }, "child right subject": function () { var matches = esquery(forLoop, '* > !AssignmentExpression'); assert.contains([ forLoop.body[0].init ], matches); }, "sibling left subject": function () { var matches = esquery(simpleProgram, "!VariableDeclaration ~ IfStatement"); assert.contains([ simpleProgram.body[0], simpleProgram.body[1] ], matches); }, "sibling right subject": function () { var matches = esquery(simpleProgram, "!VariableDeclaration ~ !IfStatement"); assert.contains([ simpleProgram.body[0], simpleProgram.body[1], simpleProgram.body[3] ], matches); }, "adjacent right subject": function () { var matches = esquery(simpleProgram, "!VariableDeclaration + !ExpressionStatement"); assert.contains([ simpleProgram.body[1], simpleProgram.body[2] ], matches); }, "multiple adjacent siblings": function () { var matches = esquery(bigArray, "Identifier + Identifier"); assert.contains([ bigArray.body[0].expression.elements[4], bigArray.body[0].expression.elements[8] ], matches); assert.isSame(2, matches.length); }, "multiple siblings": function () { var matches = esquery(bigArray, "Identifier ~ Identifier"); assert.contains([ bigArray.body[0].expression.elements[4], bigArray.body[0].expression.elements[7], bigArray.body[0].expression.elements[8] ], matches); assert.isSame(3, matches.length); } }); }); esquery-1.1.0/tests/queryType.js000066400000000000000000000105651362104005100167140ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Type query", { "conditional": function () { var matches = esquery(conditional, "Program"); assert.contains([conditional], matches); matches = esquery(conditional, "IfStatement"); assert.contains([ conditional.body[0], conditional.body[1], conditional.body[1].alternate ], matches); matches = esquery(conditional, "LogicalExpression"); assert.contains([ conditional.body[1].test, conditional.body[1].test.left ], matches); matches = esquery(conditional, "ExpressionStatement"); assert.contains([ conditional.body[0].consequent.body[0], conditional.body[0].alternate.body[0], conditional.body[1].consequent.body[0], conditional.body[1].alternate.consequent.body[0] ], matches); }, "for loop": function () { var matches = esquery(forLoop, "Program"); assert.contains([forLoop], matches); matches = esquery(forLoop, "ForStatement"); assert.contains([ forLoop.body[0] ], matches); matches = esquery(forLoop, "BinaryExpression"); assert.contains([ forLoop.body[0].test ], matches); }, "simple function": function () { var matches = esquery(simpleFunction, "Program"); assert.contains([simpleFunction], matches); matches = esquery(simpleFunction, "VariableDeclaration"); assert.contains([ simpleFunction.body[0].body.body[0] ], matches); matches = esquery(simpleFunction, "FunctionDeclaration"); assert.contains([ simpleFunction.body[0] ], matches); matches = esquery(simpleFunction, "ReturnStatement"); assert.contains([ simpleFunction.body[0].body.body[2] ], matches); }, "simple program": function () { var matches = esquery(simpleProgram, "Program"); assert.contains([simpleProgram], matches); matches = esquery(simpleProgram, "VariableDeclaration"); assert.contains([ simpleProgram.body[0], simpleProgram.body[1] ], matches); matches = esquery(simpleProgram, "AssignmentExpression"); assert.contains([ simpleProgram.body[2].expression, simpleProgram.body[3].consequent.body[0].expression ], matches); matches = esquery(simpleProgram, "Identifier"); assert.contains([ simpleProgram.body[0].declarations[0].id, simpleProgram.body[1].declarations[0].id, simpleProgram.body[2].expression.left, simpleProgram.body[2].expression.right.left, simpleProgram.body[3].test, simpleProgram.body[3].consequent.body[0].expression.left ], matches); }, "# type": function () { var matches = esquery(forLoop, "#Program"); assert.contains([ forLoop ], matches); matches = esquery(forLoop, "#ForStatement"); assert.contains([ forLoop.body[0] ], matches); matches = esquery(forLoop, "#BinaryExpression"); assert.contains([ forLoop.body[0].test ], matches); }, "case insensitive type": function () { var matches = esquery(forLoop, "Program"); assert.contains([ forLoop ], matches); matches = esquery(forLoop, "forStatement"); assert.contains([ forLoop.body[0] ], matches); matches = esquery(forLoop, "binaryexpression"); assert.contains([ forLoop.body[0].test ], matches); } }); }); esquery-1.1.0/tests/queryWildcard.js000066400000000000000000000035351362104005100175230ustar00rootroot00000000000000 define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/conditional", "./fixtures/forLoop", "./fixtures/simpleFunction", "./fixtures/simpleProgram" ], function (esquery, assert, test, conditional, forLoop, simpleFunction, simpleProgram) { test.defineSuite("Wildcard query", { "empty": function () { var matches = esquery(conditional, ""); assert.isEqual(0, matches.length); }, "conditional": function () { var matches = esquery(conditional, "*"); assert.isEqual(35, matches.length); }, "for loop": function () { var matches = esquery(forLoop, "*"); assert.isEqual(18, matches.length); }, "simple function": function () { var matches = esquery(simpleFunction, "*"); assert.isEqual(17, matches.length); }, "simple program": function () { var matches = esquery(simpleProgram, "*"); assert.isEqual(22, matches.length); }, "small program": function () { var program = { type: "Program", body: [{ type: "VariableDeclaration", declarations: [{ type: "VariableDeclarator", id: {type: "Identifier", name: "x"}, init: {type: "Literal", value: 1, raw: "1"} }], kind: "var" }] }; matches = esquery(program, "*"); assert.contains([ program, program.body[0], program.body[0].declarations[0], program.body[0].declarations[0].id, program.body[0].declarations[0].init ], matches); } }); }); esquery-1.1.0/tests/unknownNodeType.js000066400000000000000000000005031362104005100200430ustar00rootroot00000000000000define([ "esquery", "jstestr/assert", "jstestr/test", "./fixtures/unknownNodeTypeAST", ], function (esquery, assert, test, AST) { test.defineSuite("Unknown node type", { "does not throw": function () { try { esquery(AST, '*'); } catch (e) { assert.fail(); } } }); });