offers a way to query a Javascript AST to find specific patterns using a syntax somewhat similar to XPath.
npm install astronomicalastronomical offers a way to query a JavaScript AST to find specific patterns using a syntax somewhat similar to XPath. astronomical was inspired by astq, but offers some features that did not seem possible in astq and also has some limits compared to astq.
Goals:
* Should try to traverse the AST only once when resolving the Query
* Should allow filtering of nodes
* Allow running multiple queries at the same time _without traversing the AST multiple times_
The following pattern:
```
//AssignmentExpression[
/MemberExpression[
/:property/:name == "migrateVersion" &&
/$:object == ../../../../:params
]
]/:right/:valuemigrateVersion
tries to find the following code snippet and returns the string value assigned to the property:``
...
function( jQuery, window ) {
...
jQuery.migrateVersion = "3.4.1";
...
}
...
Find an AssignmentExpression at arbitrary depth, which directly contains a MemberExpression where the property name is "migrateVersion" and
the object is bound to a parameter of the surrounding function, an return the assigned value.
* / - find a child node of the given type//
* - find a descendant of the given type/:
* - find an attribute of the current node with the given name//:
* - find an attribute of the current node with the given name regardless of whether it's on the current node or on a descendant/$:
* - find the binding of an Identifier/$$:
* - return the binding or the attribute if binding cannot be resolved (helpful if a variable is sometimes directly assigned and sometimes not)[]
* - apply a filter to the node&&
* , || - logical conditions of a filter==
* - comparison in filter../
* - go to parent in filter (use with care, as this causes extra traversal)/
- wildcard type child//
- wildcard type descendant'
* ," - a string literal /fn:first(selector)
* - returns the first result from all matches/fn:concat(...selectors...)
* - concatenates results. If an argument has more than one value, those will be concatenated first./fn:join(selector, ",")
* - concatenates the results of a selector with the given separator
* query(code: string, query: string) : Result[] - Runs the given query on the given code in the form of an already parsed AST or a string (which is parsed as sourceType: "unambiguous"), and returns the result.multiQuery
* - Runs the given set of named queries on the given code in the form of an already parsed AST or a string (which is parsed as sourceType: "unambiguous"), and returns a map of named results (one result array per named query).
where Result is Babel.Node | string | number | boolean;
`
import { query } from "astronomical";
import * as fs from "fs";
const contents = fs.readFileSync("some-file.js");
const result = query(
contents,
//FunctionDeclaration/:id/:name
);
console.log("Function names", result);
``