What is ast-types?
The ast-types npm package is designed to define and manipulate ASTs (Abstract Syntax Trees) efficiently. It provides a flexible way to inspect, transform, and generate code from ASTs, which is particularly useful in the context of building compilers, code analysis tools, and code transformers.
What are ast-types's main functionalities?
Defining AST node types
This feature allows users to define various types of AST nodes. The code sample shows how to define an 'Identifier' and a 'BinaryExpression' node, specifying their structure and inheritance.
const def = require('ast-types').Type.def;
def('Identifier')
.bases('Node')
.build('name');
def('BinaryExpression')
.bases('Expression')
.build('operator', 'left', 'right');
Building AST nodes
This feature enables the construction of AST nodes using predefined builders. The code sample demonstrates creating a binary expression that adds two literals.
const builders = require('ast-types').builders;
const b = builders;
const ast = b.binaryExpression('+', b.literal(1), b.literal(2));
Visiting AST nodes
This feature provides a mechanism to traverse and manipulate nodes in an AST. The code sample illustrates how to visit all identifier nodes in an AST and log their names.
const visit = require('ast-types').visit;
const ast = require('./some-ast');
visit(ast, {
visitIdentifier(path) {
console.log('Found an identifier:', path.node.name);
this.traverse(path);
}
});
Other packages similar to ast-types
babel-types
Similar to ast-types, babel-types is part of the Babel compiler ecosystem. It provides builders, validators, and converters for Babel's AST nodes. While ast-types is more generic and flexible, babel-types is specifically optimized for use with Babel's AST format.
recast
Recast is built on top of ast-types and provides additional utilities for parsing, printing, and source map support. It leverages ast-types for node type definitions and manipulation, but extends its functionality with a focus on maintaining exact original formatting.
AST Types
This module provides an efficient, modular,
Esprima-compatible implementation of
the abstract syntax
tree type hierarchy
pioneered by the Mozilla Parser
API.
Installation
From NPM:
npm install ast-types
From GitHub:
cd path/to/node_modules
git clone git://github.com/benjamn/ast-types.git
cd ast-types
npm install .
Basic Usage
var assert = require("assert");
var n = require("ast-types").namedTypes;
var b = require("ast-types").builders;
var fooId = b.identifier("foo");
var ifFoo = b.ifStatement(fooId, b.blockStatement([
b.expressionStatement(b.callExpression(fooId, []))
]));
assert.ok(n.IfStatement.check(ifFoo));
assert.ok(n.Statement.check(ifFoo));
assert.ok(n.Node.check(ifFoo));
assert.ok(n.BlockStatement.check(ifFoo.consequent));
assert.strictEqual(
ifFoo.consequent.body[0].expression.arguments.length,
0);
assert.strictEqual(ifFoo.test, fooId);
assert.ok(n.Expression.check(ifFoo.test));
assert.ok(n.Identifier.check(ifFoo.test));
assert.ok(!n.Statement.check(ifFoo.test));
Custom AST Node Types
var types = require("ast-types");
var def = types.Type.def;
var string = types.builtInTypes.string;
var b = types.builders;
// Suppose you need a named File type to wrap your Programs.
def("File")
.bases("Node")
.build("name", "program")
.field("name", string)
.field("program", def("Program"));
// Prevent further modifications to the File type (and any other
// types newly introduced by def(...)).
types.finalize();
// The b.file builder function is now available. It expects two
// arguments, as named by .build("name", "program") above.
var main = b.file("main.js", b.program([
// Pointless program contents included for extra color.
b.functionDeclaration(b.identifier("succ"), [
b.identifier("x")
], b.blockStatement([
b.returnStatement(
b.binaryExpression(
"+", b.identifier("x"), b.literal(1)
)
)
]))
]));
assert.strictEqual(main.name, "main.js");
assert.strictEqual(main.program.body[0].params[0].name, "x");
// etc.
// If you pass the wrong type of arguments, or fail to pass enough
// arguments, an AssertionError will be thrown.
b.file(b.blockStatement([])); // AssertionError: {"body":[],"type":"BlockStatement","loc":null} does not match type string
b.file("lib/types.js", b.thisExpression()); // AssertionError: {"type":"ThisExpression","loc":null} does not match type Program