# Variable declaration var a = b , c = d; const [x] = y = 3; ==> Script( VariableDeclaration(var,VariableDefinition,Equals,VariableName,VariableDefinition,Equals,VariableName), VariableDeclaration(const,ArrayPattern(VariableDefinition),Equals,AssignmentExpression(VariableName,Equals,Number))) # Function declaration function a(a, b) { return 3; } function b({b}, c = d, e = f) {} ==> Script( FunctionDeclaration(function,VariableDefinition,ParamList(VariableDefinition,VariableDefinition),Block(ReturnStatement(return,Number))), FunctionDeclaration(function,VariableDefinition,ParamList( ObjectPattern(PatternProperty(PropertyName)),VariableDefinition,Equals,VariableName,VariableDefinition,Equals,VariableName),Block)) # Async functions async function foo() {} class Foo { async bar() {} } async (a) => { return foo; }; ==> Script( FunctionDeclaration(async,function,VariableDefinition,ParamList,Block), ClassDeclaration(class,VariableDefinition,ClassBody(MethodDeclaration(async,PropertyDefinition,ParamList,Block))), ExpressionStatement(ArrowFunction(async,ParamList(VariableDefinition),Arrow,Block(ReturnStatement(return,VariableName))))) # If statements if (x) log(y); if (a.b) { d; } if (a) { c; d; } else { e; } if (1) if (2) b; else c; ==> Script( IfStatement(if,ParenthesizedExpression(VariableName),ExpressionStatement(CallExpression(VariableName,ArgList(VariableName)))), IfStatement(if,ParenthesizedExpression(MemberExpression(VariableName,PropertyName)),Block(ExpressionStatement(VariableName))), IfStatement(if,ParenthesizedExpression(VariableName),Block(ExpressionStatement(VariableName),ExpressionStatement(VariableName)), else,Block(ExpressionStatement(VariableName))), IfStatement(if,ParenthesizedExpression(Number),IfStatement(if,ParenthesizedExpression(Number),ExpressionStatement(VariableName), else,ExpressionStatement(VariableName)))) # While loop while (1) debugger; while (2) { a; b; } ==> Script( WhileStatement(while,ParenthesizedExpression(Number),DebuggerStatement(debugger)), WhileStatement(while,ParenthesizedExpression(Number),Block(ExpressionStatement(VariableName),ExpressionStatement(VariableName)))) # Labels foo: 1; foo: while(2) break foo; ==> Script( LabeledStatement(Label,ExpressionStatement(Number)), LabeledStatement(Label,WhileStatement(while,ParenthesizedExpression(Number),BreakStatement(break,Label)))) # Try try { throw new Error; } catch {} try { 1; } catch (x) { 2; } finally { 3; } ==> Script( TryStatement(try,Block(ThrowStatement(throw,NewExpression(new,VariableName))),CatchClause(catch,Block)), TryStatement(try,Block(ExpressionStatement(Number)), CatchClause(catch,VariableDefinition,Block(ExpressionStatement(Number))), FinallyClause(finally,Block(ExpressionStatement(Number))))) # Switch switch (x) { case 1: return true; case 2: case 50 * 3: console.log("ok"); default: return false; } ==> Script(SwitchStatement(switch,ParenthesizedExpression(VariableName),SwitchBody( CaseLabel(case,Number), ReturnStatement(return,BooleanLiteral), CaseLabel(case,Number), CaseLabel(case,BinaryExpression(Number,ArithOp,Number)), ExpressionStatement(CallExpression(MemberExpression(VariableName,PropertyName),ArgList(String))), DefaultLabel(default), ReturnStatement(return,BooleanLiteral)))) # For for (let x = 1; x < 10; x++) {} for (const y of z) {} for (var m in n) {} for (q in r) {} for (var a, b; c; d) continue; for (i = 0, init(); i < 10; i++) {} for (;;) {} for (const {thing} in things) thing; for await (let x of stream) {} ==> Script( ForStatement(for,ForSpec(VariableDeclaration(let,VariableDefinition,Equals,Number), BinaryExpression(VariableName,CompareOp,Number),PostfixExpression(VariableName,ArithOp)),Block), ForStatement(for,ForOfSpec(const,VariableDefinition,of,VariableName),Block), ForStatement(for,ForInSpec(var,VariableDefinition,in,VariableName),Block), ForStatement(for,ForInSpec(VariableName,in,VariableName),Block), ForStatement(for,ForSpec(VariableDeclaration(var,VariableDefinition,VariableDefinition),VariableName,VariableName),ContinueStatement(continue)), ForStatement(for,ForSpec(SequenceExpression(AssignmentExpression(VariableName,Equals,Number), CallExpression(VariableName,ArgList)),BinaryExpression(VariableName,CompareOp,Number),PostfixExpression(VariableName,ArithOp)),Block), ForStatement(for,ForSpec,Block), ForStatement(for,ForInSpec(const,ObjectPattern(PatternProperty(PropertyName)),in,VariableName),ExpressionStatement(VariableName)), ForStatement(for,await,ForOfSpec(let,VariableDefinition,of,VariableName),Block)) # Labeled statements theLoop: for (;;) { if (a) { break theLoop; } } ==> Script(LabeledStatement(Label,ForStatement(for,ForSpec,Block( IfStatement(if,ParenthesizedExpression(VariableName),Block(BreakStatement(break,Label))))))) # Classes class Foo { static one(a) { return a; }; two(b) { return b; } finally() {} } class Foo extends require('another-class') { constructor() { super(); } bar() { super.a(); } prop; etc = 20; static { f() } } ==> Script( ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(static,PropertyDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), MethodDeclaration(PropertyDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), MethodDeclaration(PropertyDefinition,ParamList,Block))), ClassDeclaration(class,VariableDefinition,extends,CallExpression(VariableName,ArgList(String)),ClassBody( MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), PropertyDeclaration(PropertyDefinition), PropertyDeclaration(PropertyDefinition,Equals,Number), StaticBlock(static, Block(ExpressionStatement(CallExpression(VariableName,ArgList))))))) # Private properties class Foo { #bar() { this.#a() + this?.#prop == #prop in this; } #prop; #etc = 20; } ==> Script(ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(PrivatePropertyDefinition,ParamList,Block( ExpressionStatement(BinaryExpression( BinaryExpression( CallExpression(MemberExpression(this,PrivatePropertyName),ArgList), ArithOp, MemberExpression(this,PrivatePropertyName)), CompareOp, BinaryExpression(PrivatePropertyName, in, this))))), PropertyDeclaration(PrivatePropertyDefinition), PropertyDeclaration(PrivatePropertyDefinition,Equals,Number)))) # Computed properties class Foo { [x] = 44; [Symbol.iterator]() {} } ==> Script(ClassDeclaration(class,VariableDefinition,ClassBody( PropertyDeclaration(VariableName,Equals,Number), MethodDeclaration(MemberExpression(VariableName,PropertyName),ParamList,Block)))) # Imports import defaultMember from "module-name"; import * as name from "module-name"; import { member } from "module-name"; import { member1, member2 as alias2 } from "module-name"; import defaultMember, { member1, member2 as alias2, } from "module-name"; import "module-name"; ==> Script( ImportDeclaration(import,VariableDefinition,from,String), ImportDeclaration(import,Star,as,VariableDefinition,from,String), ImportDeclaration(import,ImportGroup(VariableDefinition),from,String), ImportDeclaration(import,ImportGroup(VariableDefinition,VariableName,as,VariableDefinition),from,String), ImportDeclaration(import,VariableDefinition,ImportGroup(VariableDefinition,VariableName,as,VariableDefinition),from,String), ImportDeclaration(import,String)) # Exports export { name1, name2, name3 as x, nameN }; export let a, b = 2; export default 2 + 2; export default function() { } export default async function name1() { } export { name1 as default, } from "foo"; export * from 'foo'; ==> Script( ExportDeclaration(export,ExportGroup(VariableName,VariableName,VariableName,as,VariableName,VariableName)), ExportDeclaration(export,VariableDeclaration(let,VariableDefinition,VariableDefinition,Equals,Number)), ExportDeclaration(export,default,BinaryExpression(Number,ArithOp,Number)), ExportDeclaration(export,default,FunctionDeclaration(function,ParamList,Block)), ExportDeclaration(export,default,FunctionDeclaration(async,function,VariableDefinition,ParamList,Block)), ExportDeclaration(export,ExportGroup(VariableName,as,VariableName),from,String), ExportDeclaration(export,Star,from,String)) # Empty statements if (true) { ; };;; ==> Script(IfStatement(if,ParenthesizedExpression(BooleanLiteral),Block)) # Comments /* a */ one; /* b **/ two; /* c ***/ three; /* d ***/ four; y // comment * z; ==> Script( BlockComment, ExpressionStatement(VariableName), BlockComment, ExpressionStatement(VariableName), BlockComment, ExpressionStatement(VariableName), BlockComment, ExpressionStatement(VariableName), ExpressionStatement(BinaryExpression(VariableName,LineComment,ArithOp,VariableName))) # Recover from invalid char const {foobar} = {}; ==> Script(VariableDeclaration( const, ObjectPattern("{",PatternProperty(PropertyName,⚠),"}"), Equals, ObjectExpression)) # Sync back to statement function f() { log(a b --c) } function g() {} ==> Script( FunctionDeclaration(function,VariableDefinition,ParamList,Block(ExpressionStatement(CallExpression(VariableName,ArgList(...))))), FunctionDeclaration(function,VariableDefinition,ParamList,Block)) # Destructuring ({x} = y); [u, v] = w; let [a,, b = 0] = c; let {x, y: z = 1} = d; let {[f]: m} = e; ==> Script( ExpressionStatement(ParenthesizedExpression(AssignmentExpression( ObjectPattern(PatternProperty(PropertyName)),Equals,VariableName))), ExpressionStatement(AssignmentExpression(ArrayPattern(VariableDefinition,VariableDefinition),Equals,VariableName)), VariableDeclaration(let,ArrayPattern(VariableDefinition,VariableDefinition,Equals,Number),Equals,VariableName), VariableDeclaration(let,ObjectPattern( PatternProperty(PropertyName), PatternProperty(PropertyName,VariableDefinition,Equals,Number) ),Equals,VariableName), VariableDeclaration(let,ObjectPattern(PatternProperty(VariableName,VariableDefinition)),Equals,VariableName)) # Generators function* foo() { yield 1 } class B { *method() {} } ({*x() {}}) ==> Script( FunctionDeclaration(function,Star,VariableDefinition,ParamList,Block( ExpressionStatement(YieldExpression(yield,Number)))), ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(Star,PropertyDefinition,ParamList,Block))), ExpressionStatement(ParenthesizedExpression(ObjectExpression(Property(Star,PropertyDefinition,ParamList,Block))))) # Hashbang #!/bin/env node foo() ==> Script(Hashbang,ExpressionStatement(CallExpression(VariableName,ArgList))) # new.target function MyObj() { if (!new.target) { throw new Error('Must construct MyObj with new'); } } ==> Script( FunctionDeclaration(function,VariableDefinition,ParamList,Block( IfStatement(if,ParenthesizedExpression(UnaryExpression(LogicOp,NewTarget(new,PropertyName))), Block( ThrowStatement(throw,NewExpression(new,VariableName,ArgList(String))))))))