These are basic utilities that you can use as helper functions
const { utils: u } = require('estree-toolkit');evaluate(path)path: <NodePath> The path that you want to evaluate{ value: any } | undefined The evaluation resultEvaluates the given path and returns the evaluated result. If it's sure
about the evaluation it would return an object with the evaluated value stored
in value property. If it's not sure about the evaluation it would return undefined.
These AST Nodes are supported for now
Identifier - with undefined as valueLiteralBinaryExpression - except instanceof operatorUnaryExpression - except delete operatorLogicalExpressionObjectExpressionArrayExpressionconst { utils: u, traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');
traverse(parseModule(`undefined`), {
Identifier(path) {
u.evaluate(path) // => { value: undefined }
}
});
traverse(parseModule(`'some string'`), {
Literal(path) {
u.evaluate(path) // => { value: 'some string' }
}
});
traverse(parseModule(`1 + 2`), {
BinaryExpression(path) {
u.evaluate(path) // => { value: 3 }
}
});
traverse(parseModule(`!(1 === 2)`), {
UnaryExpression(path) {
u.evaluate(path) // => { value: true }
}
});
traverse(parseModule(`false && unknown`), {
LogicalExpression(path) {
u.evaluate(path) // => { value: false }
}
});
traverse(parseModule(`
({ a: 1, b: 2, m: { c: 1 } })
`), {
ObjectExpression(path) {
if (path.parent.type !== 'ExpressionStatement') return;
u.evaluate(path) // => { value: { a: 1, b: 2, m: { c: 1 } } }
}
});
traverse(parseModule(`[1, 2, '3']`), {
ArrayExpression(path) {
u.evaluate(path) // => { value: [1, 2, '3'] }
}
});
// Whenever unknown binding is involved, it returns `undefined`
traverse(parseModule(`unknownVariable`), {
Identifier(path) {
u.evaluate(path) // => undefined
}
});
traverse(parseModule(`unknownVariable === 55`), {
BinaryExpression(path) {
u.evaluate(path) // => undefined
}
});evaluateTruthy(path)path: <NodePath> The path that you want to evaluatetrue | false | undefined The evaluation resultIt's just like evaluate(path) but it evaluates for truthiness. It returns true or false
depending on the evaluation result, if it's sure. If it's not sure, it would return undefined.
const { utils: u, traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');
traverse(parseModule(`false && unknown`), {
LogicalExpression(path) {
u.evaluateTruthy(path) // => false
}
});
traverse(parseModule(`true || unknown`), {
LogicalExpression(path) {
u.evaluateTruthy(path) // => true
}
});
traverse(parseModule(`!0`), {
UnaryExpression(path) {
u.evaluateTruthy(path) // => true
}
});hasBinding(path, name)path: <NodePath> The path from where the searching should startname: <string> The name of the bindingboolean If the binding is available in the current positionYou can easily track scopes by enabling Scope when traversing.
But if you need to check if a binding is available only one or two times, using Scope can be
overkill, because scope builds all the graphs that you may not need. So using hasBinding in this
case would be more preferable.
This function starts walking up the tree from the path and finds if there is any binding
with the provided name. If there is any binding it returns true, if not then it returns false.
const { utils: u, traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');
const ast = parseModule(`
{
let a;
{
id1;
}
}
id2;
`);
traverse(ast, {
Identifier(path) {
if (path.node.name === 'id1') {
u.hasBinding(path, 'a') // => true
} else if (path.node.name === 'id2') {
u.hasBinding(path, 'a') // => false
}
}
});getCommonAncestor(paths)paths: <NodePath[]> The paths for which the ancestor should be commonNodePath> The NodePath of the ancestorFinds the closest common parent (or ancestor) for all the provided paths
isReference(path, includeGlobals)path: <NodePath<Identifier | JSXIdentifier>> The path which should be checkedincludeGlobals: <boolean> Whether global bindings should be included while checking for referencesboolean> Whether the path is a referencePort of is-reference. Functionality of this function is identical to the npm package.