UglifyJS provides a comprehensive Abstract Syntax Tree (AST) representation of JavaScript code with classes for every language construct, plus utilities for traversing and transforming syntax trees.
AST traversal utility for visiting nodes in a syntax tree.
/**
* Creates a TreeWalker for AST traversal
* @param callback - Function called for each visited node
* @constructor
*/
function TreeWalker(callback);
interface TreeWalker {
/** Function called for each visited node */
callback: (node: AST_Node, descend?: Function) => boolean | undefined;
/** Current directive state */
directives: object;
/** Stack of nodes being traversed */
stack: AST_Node[];
/** Visit a node and optionally descend to children */
visit(node: AST_Node, descend?: Function): void;
/** Get parent node (n levels up) */
parent(n?: number): AST_Node;
/** Push node to traversal stack */
push(node: AST_Node): void;
/** Pop node from traversal stack */
pop(): void;
/** Find nearest parent of specified type */
find_parent(type: string): AST_Node | null;
/** Get current node being processed */
self(): AST_Node;
/** Check if directive is present in current scope */
has_directive(type: string): boolean;
}Usage Examples:
const UglifyJS = require("uglify-js");
// Parse code into AST
const ast = UglifyJS.parse("function test() { return 42; }");
// Walk through all nodes
const walker = new UglifyJS.TreeWalker(function(node) {
console.log(node.TYPE); // Print node type
return false; // Continue traversal
});
ast.walk(walker);AST transformation utility extending TreeWalker for modifying syntax trees.
/**
* Creates a TreeTransformer for AST modification
* @param before - Transformation function called before processing children
* @param after - Transformation function called after processing children
* @constructor
*/
function TreeTransformer(before, after);
interface TreeTransformer extends TreeWalker {
/** Transformation applied before processing child nodes */
before?: (node: AST_Node, descend: Function) => AST_Node;
/** Transformation applied after processing child nodes */
after?: (node: AST_Node) => AST_Node;
}Usage Examples:
const UglifyJS = require("uglify-js");
// Transform all function names to uppercase
const transformer = new UglifyJS.TreeTransformer(function(node) {
if (node instanceof UglifyJS.AST_Function && node.name) {
node.name.name = node.name.name.toUpperCase();
}
return node;
});
const ast = UglifyJS.parse("function hello() { return 'world'; }");
const transformed = ast.transform(transformer);Array transformation utility with special operation handling.
/**
* Transform array with support for special operations
* @param array - Input array to transform
* @param fn - Transformation function
* @returns Transformed array
*/
function List(array, fn);
interface ListStatic {
/** Check if value is a special List operation */
is_op(value: any): boolean;
}Base class for all AST nodes.
class AST_Node {
/** Start token position in source code */
start: AST_Token;
/** End token position in source code */
end: AST_Token;
/** Node type identifier */
TYPE: string;
/** Constructor reference */
CTOR: Function;
/** Internal bit flags for boolean properties */
_bits: number;
/** Create a copy of the node */
clone(deep?: boolean): AST_Node;
/** Transform node using TreeTransformer */
transform(transformer: TreeTransformer): AST_Node;
/** Walk through node tree using TreeWalker */
walk(walker: TreeWalker): void;
/** Check structural equality with another node */
equals(node: AST_Node): boolean;
/** Validate node structure (when validation enabled) */
validate(): void;
}Represents a token in the source code.
class AST_Token extends AST_Node {
/** Token type */
type: string;
/** Token value */
value: string;
/** Line number */
line: number;
/** Column number */
col: number;
/** Character position */
pos: number;
/** End line number */
endline: number;
/** End column number */
endcol: number;
/** End character position */
endpos: number;
/** Comments before token */
comments_before: AST_Token[];
/** Comments after token */
comments_after: AST_Token[];
/** Source file */
file: string;
/** Raw token text */
raw: string;
}Base class for all statements.
class AST_Statement extends AST_Node {
}Top-level program node containing the entire script.
class AST_Toplevel extends AST_BlockScope {
/** Global variables */
globals: object;
}Expression statement (expression followed by semicolon).
class AST_SimpleStatement extends AST_Statement {
/** Expression being executed */
body: AST_Node;
}Block statement containing multiple statements.
class AST_Block extends AST_Statement {
/** Array of statements in block */
body: AST_Statement[];
}Empty statement (just a semicolon).
class AST_EmptyStatement extends AST_Statement {
}Labeled statement.
class AST_LabeledStatement extends AST_Statement {
/** Statement label */
label: AST_Label;
/** Labeled statement body */
body: AST_Statement;
}Base class for loop statements.
class AST_IterationStatement extends AST_Statement {
}Do-while loop.
class AST_Do extends AST_IterationStatement {
/** Loop condition */
condition: AST_Node;
/** Loop body */
body: AST_Statement;
}While loop.
class AST_While extends AST_IterationStatement {
/** Loop condition */
condition: AST_Node;
/** Loop body */
body: AST_Statement;
}Traditional for loop.
class AST_For extends AST_IterationStatement {
/** Loop initialization */
init: AST_Node;
/** Loop condition */
condition: AST_Node;
/** Loop increment */
step: AST_Node;
/** Loop body */
body: AST_Statement;
}For-in loop.
class AST_ForIn extends AST_IterationStatement {
/** Loop variable */
init: AST_Node;
/** Object being iterated */
object: AST_Node;
/** Loop body */
body: AST_Statement;
}For-of loop.
class AST_ForOf extends AST_IterationStatement {
/** Loop variable */
init: AST_Node;
/** Iterable being processed */
object: AST_Node;
/** Loop body */
body: AST_Statement;
}For-await-of loop (async iteration).
class AST_ForAwaitOf extends AST_ForOf {
}Block with scope (let/const declarations).
class AST_BlockScope extends AST_Block {
/** Variable names in scope */
_var_names: object;
/** Variables from outer scopes */
enclosed: AST_SymbolDef[];
/** Function definitions */
functions: object;
/** Function to create symbol definitions */
make_def: Function;
/** Parent scope */
parent_scope: AST_Scope;
/** Variables defined in this scope */
variables: object;
}Function scope.
class AST_Scope extends AST_BlockScope {
/** Function definitions in scope */
fn_defs: AST_Defun[];
/** Whether 'this' might be called */
may_call_this: boolean;
/** Whether eval() is used */
uses_eval: boolean;
/** Whether 'with' statement is used */
uses_with: boolean;
}Base class for function-like nodes.
class AST_Lambda extends AST_Scope {
/** Function argument names */
argnames: AST_Symbol[];
/** Number of arguments read */
length_read: boolean;
/** Rest parameter */
rest: AST_Symbol;
/** Safe identifiers for optimization */
safe_ids: object;
/** Whether 'arguments' object is used */
uses_arguments: boolean;
}Property getter or setter.
class AST_Accessor extends AST_Lambda {
}Function expression.
class AST_LambdaExpression extends AST_Lambda {
/** Whether function was inlined */
inlined: boolean;
}Arrow function expression.
class AST_Arrow extends AST_LambdaExpression {
/** Function body (expression or block) */
value: AST_Node;
}Async arrow function expression.
class AST_AsyncArrow extends AST_Arrow {
}If statement.
class AST_If extends AST_Statement {
/** If condition */
condition: AST_Node;
/** Then branch */
body: AST_Statement;
/** Else branch (optional) */
alternative?: AST_Statement;
}Switch statement.
class AST_Switch extends AST_Block {
/** Switch expression */
expression: AST_Node;
/** Array of case/default branches */
body: AST_SwitchBranch[];
}Try-catch-finally statement.
class AST_Try extends AST_Statement {
/** Try block */
body: AST_Block;
/** Catch handler (optional) */
bcatch?: AST_Catch;
/** Finally block (optional) */
bfinally?: AST_Block;
}Function call expression.
class AST_Call extends AST_Node {
/** Function being called */
expression: AST_Node;
/** Call arguments */
args: AST_Node[];
}Binary expression (e.g., +, -, *, etc.).
class AST_Binary extends AST_Node {
/** Binary operator */
operator: string;
/** Left operand */
left: AST_Node;
/** Right operand */
right: AST_Node;
}Unary expression (e.g., !, -, typeof, etc.).
class AST_Unary extends AST_Node {
/** Unary operator */
operator: string;
/** Operand expression */
expression: AST_Node;
}String literal.
class AST_String extends AST_Node {
/** String value */
value: string;
/** Quote character used */
quote: string;
}Numeric literal.
class AST_Number extends AST_Node {
/** Numeric value */
value: number;
}Boolean literal.
class AST_Boolean extends AST_Node {
/** Boolean value */
value: boolean;
}Null literal.
class AST_Null extends AST_Node {
}Undefined literal.
class AST_Undefined extends AST_Node {
}Each AST node has a TYPE property identifying its class name.
// Check node type
if (node.TYPE === "Call") {
// Handle function call
}
// Or use instanceof
if (node instanceof UglifyJS.AST_Call) {
// Handle function call
}const calls = [];
const walker = new UglifyJS.TreeWalker(function(node) {
if (node instanceof UglifyJS.AST_Call) {
calls.push(node);
}
});
ast.walk(walker);const transformer = new UglifyJS.TreeTransformer(function(node) {
if (node instanceof UglifyJS.AST_Symbol && node.name === "oldName") {
node.name = "newName";
}
return node;
});
const newAst = ast.transform(transformer);