shift-query

A query library for Shift AST using a CSS selector like query language.

Usage no npm install needed!

<script type="module">
  import shiftQuery from 'https://cdn.skypack.dev/shift-query';
</script>

README

Shift Query

Shift-query is a library for querying a Shift AST for patterns of syntax using a CSS style selector system.

This is a fork and update of esquery to be used with the Shift suite of parsers and tools. No significant functionality has been changed.

Demo

Check out the demo here

Install

$ npm install shift-query

Usage

const query = require('shift-query');
const { parseScript } = require('shift-parser');

const ast = parseScript(`
function add(a, b) { return a + b };
function noop() { };

const sum = add(1,2);
`);

const binding = query(ast, '[name="sum"]');
console.log(binding);
/*
[ BindingIdentifier { type: 'BindingIdentifier', name: 'sum' } ]
*/

const functionsWithParams = query(ast, '[params.items.length>0]');
console.log(functionsWithParams);

/*
[ FunctionDeclaration {
  type: 'FunctionDeclaration',
  isAsync: false,
  isGenerator: false,
  name: BindingIdentifier { type: 'BindingIdentifier', name: 'add' },
  params: FormalParameters { type: 'FormalParameters', items: [Array], rest: null },
  body: FunctionBody { type: 'FunctionBody', directives: [], statements: [Array] } } ]
*/

The following selectors are supported:

  • AST node type: FunctionDeclaration
  • wildcard: *
  • attribute existence: [attr]
  • attribute value: [attr="foo"] or [attr=123]
  • attribute regex: [attr=/foo.*/]
  • attribute conditons: [attr!="foo"], [attr>2], [attr<3], [attr>=2], or [attr<=3]
  • nested attribute: [attr.level2="foo"]
  • field: FunctionDeclaration > IdentifierExpression.name
  • First or last child: :first-child or :last-child
  • nth-child (no ax+b support): :nth-child(2)
  • nth-last-child (no ax+b support): :nth-last-child(1)
  • descendant: ancestor descendant
  • child: parent > child
  • following sibling: node ~ sibling
  • adjacent sibling: node + adjacent
  • negation: :not(ExpressionStatement)
  • matches-any: :matches([attr] > :first-child, :last-child)
  • subject indicator: !IfStatement > [name="foo"]
  • class of AST node: :statement, :expression, :declaration, :function, or :target