Mozilla Specification JavaScript/ES AST Traversal and Modification Unit, as god intended.
Just run this command inside your project directory:
npm i crucifix
// Importing the library
const crucifix = require( 'crucifix' );
// Importing our AST data from somewhere
const data = require( './ast.json' );
// Use the library
crucifix.traverse( data, {
// We are going to list all the
// identifiers
Identifier ( node, manager ) {
console.log( node.name );
}
} );
// Importing the library
import crucifix from 'crucifix';
// Importing our AST data from somewhere
const data = await import( './ast.json', { assert: { type: 'json' } } );
// Use the library
crucifix.traverse( data, {
// We are going to list all the
// identifiers
Identifier ( node, manager ) {
console.log( node.name );
}
} );
After importing the library and doing necessary things, you can modify the AST using manager methods like so:
// Assuming you've imported your data
// and the crucifix library
const output = crucifix.traverse( data, {
VariableDeclaration ( node, manager ) {
// Clone the node
const newNode = manager.clone();
// After cloning the node, we can
// safely replace the data and
// even append new nodes to parent
// object's own property
manager.replace( [
newNode,
newNode.declarations.map( decl => (
{
type: 'ExpressionStatement',
expression: {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: 'print'
},
arguments: [ decl.id ]
}
}
) )
] )
}
} );
// Input data below is converted to AST
// and saved inside "ast.json" ->
// const hey = 10;
// const test = 20, test2 = 30;
// Output AST will be converted to code
// and the output would be:
// const hey = 10;
// print( hey );
// const test = 20, test2 = 30;
// print( test );
// print( test2 );
manager.clone()
Clones the node for user to do changes that does not affect the original node.
manager.remove()
Removes the node from the list or the property itself.
manager.modify( source: object, surfaceLevel: boolean )
Modifies the current property. When surfaceLevel
is true, it copies the properties of source directly to the current property, otherwise it recursively scans through the objects to deeply modify without directly modifying the property itself.
manager.replace( source: object|object[] )
Replaces the current property. When an array is given, it flats out the array to append nodes to the parent object's property.
manager.item
Returns the current node.
manager.ancestors
Returns the list of ancestors of the current node.