// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ast.js 1`] = ` ====================================options===================================== parsers: ["flow"] printWidth: 80 | printWidth =====================================input====================================== /** * @flow */ export type InferredType = | 'unknown' | 'gender' | 'enum' | 'number-or-string' | 'number' | 'string' | 'error' ; export type Pos = { firstLine: number, firstColumn: number, lastLine: number, lastColumn: number, }; export type TypedBinaryOpNode = { exprNodeType: 'binary_op', binaryOp: 'plus' | 'multiply' | 'divide' | 'minus', lhs: TypedNode, rhs: TypedNode, pos: Pos, exprType: InferredType, typed: true, } export type TypedUnaryMinusNode = { exprNodeType: 'unary_minus', op: TypedNode, pos: Pos, exprType: InferredType, typed: true, } export type TypedNumberNode = { exprNodeType: 'number', value: number, pos: Pos, exprType: 'number', typed: true, } export type TypedStringLiteralNode = { exprNodeType: 'string_literal', value: string, pos: Pos, exprType: 'string', typed: true, } export type TypedVariableNode = { exprNodeType: 'variable', name: string, pos: Pos, exprType: InferredType, typed: true, }; export type TypedFunctionInvocationNode = { exprNodeType: 'function_invocation', name: string, parameters: TypedNode[], pos: Pos, exprType: 'error' | 'string', typed: true, } export type TypedNode = | TypedBinaryOpNode | TypedUnaryMinusNode | TypedNumberNode | TypedStringLiteralNode | TypedVariableNode | TypedFunctionInvocationNode ; =====================================output===================================== /** * @flow */ export type InferredType = | "unknown" | "gender" | "enum" | "number-or-string" | "number" | "string" | "error"; export type Pos = { firstLine: number, firstColumn: number, lastLine: number, lastColumn: number }; export type TypedBinaryOpNode = { exprNodeType: "binary_op", binaryOp: "plus" | "multiply" | "divide" | "minus", lhs: TypedNode, rhs: TypedNode, pos: Pos, exprType: InferredType, typed: true }; export type TypedUnaryMinusNode = { exprNodeType: "unary_minus", op: TypedNode, pos: Pos, exprType: InferredType, typed: true }; export type TypedNumberNode = { exprNodeType: "number", value: number, pos: Pos, exprType: "number", typed: true }; export type TypedStringLiteralNode = { exprNodeType: "string_literal", value: string, pos: Pos, exprType: "string", typed: true }; export type TypedVariableNode = { exprNodeType: "variable", name: string, pos: Pos, exprType: InferredType, typed: true }; export type TypedFunctionInvocationNode = { exprNodeType: "function_invocation", name: string, parameters: TypedNode[], pos: Pos, exprType: "error" | "string", typed: true }; export type TypedNode = | TypedBinaryOpNode | TypedUnaryMinusNode | TypedNumberNode | TypedStringLiteralNode | TypedVariableNode | TypedFunctionInvocationNode; ================================================================================ `; exports[`emit.js 1`] = ` ====================================options===================================== parsers: ["flow"] printWidth: 80 | printWidth =====================================input====================================== /** * @flow */ import * as t from './jsAst'; const b = t.builders; import type { TypedNode } from './ast'; function getBinaryOp(op: 'plus' | 'minus' | 'divide' | 'multiply') : '+' | '-' | '*' | '/' { switch (op) { case 'plus': return '+'; case 'minus': return '-'; case 'divide': return '/'; case 'multiply': return '*'; default: throw new Error('Invalid binary operator: ' + op); } } export function emitExpression(node: TypedNode) : t.Expression { switch (node.exprNodeType) { case 'string_literal': // FALLTHROUGH case 'number': return b.literal(node.value); case 'variable': return b.memberExpression( b.identifier('vars'), b.identifier(node.name), false ); case 'binary_op': { const lhs = emitExpression(node.lhs); const rhs = emitExpression(node.rhs); const op = getBinaryOp(node.binaryOp); return b.binaryExpression(op, lhs, rhs); } case 'unary_minus': { const operand = emitExpression(node.op); return b.unaryExpression('-', operand, true); } case 'function_invocation': { const callee = b.memberExpression( b.identifier('fns'), b.identifier(node.name), false ); const args = node.parameters.map( (n) => emitExpression(n) ); return b.callExpression(callee, args); } default: throw new Error('Unknown expression type: ' + node.type); } } =====================================output===================================== /** * @flow */ import * as t from "./jsAst"; const b = t.builders; import type { TypedNode } from "./ast"; function getBinaryOp( op: "plus" | "minus" | "divide" | "multiply" ): "+" | "-" | "*" | "/" { switch (op) { case "plus": return "+"; case "minus": return "-"; case "divide": return "/"; case "multiply": return "*"; default: throw new Error("Invalid binary operator: " + op); } } export function emitExpression(node: TypedNode): t.Expression { switch (node.exprNodeType) { case "string_literal": // FALLTHROUGH case "number": return b.literal(node.value); case "variable": return b.memberExpression( b.identifier("vars"), b.identifier(node.name), false ); case "binary_op": { const lhs = emitExpression(node.lhs); const rhs = emitExpression(node.rhs); const op = getBinaryOp(node.binaryOp); return b.binaryExpression(op, lhs, rhs); } case "unary_minus": { const operand = emitExpression(node.op); return b.unaryExpression("-", operand, true); } case "function_invocation": { const callee = b.memberExpression( b.identifier("fns"), b.identifier(node.name), false ); const args = node.parameters.map(n => emitExpression(n)); return b.callExpression(callee, args); } default: throw new Error("Unknown expression type: " + node.type); } } ================================================================================ `; exports[`jsAst.js 1`] = ` ====================================options===================================== parsers: ["flow"] printWidth: 80 | printWidth =====================================input====================================== /** * @flow */ export type Comment = { loc: ?SourceLocation, value: string, leading: boolean, trailing: boolean, }; export type SourceLocation = { start: SourcePosition, end: SourcePosition, source: ?string, }; export type SourcePosition = { line: number, column: number, }; export type File = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'File', program: Program, } export type Program = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'Program', body: Statement[], } export type BinaryOperator = |'==' | '!=' | '===' | '!==' | '<' | '<=' | '>' | '>=' | '<<' | '>>' | '>>>' | '+' | '-' | '*' | '/' | '%' | '&' // TODO Missing from the Parser API. | '|' | '^' | 'in' | 'instanceof' | '..' ; export type UnaryOperator = | '-' | '+' | '!' | '~' | 'typeof' | 'void' | 'delete' ; export type AssignmentOperator = | '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&=' ; export type UpdateOperator = | '++' | '--' ; export type LogicalOperator = | '&&' | '||' ; export type Node = | EmptyStatement | BlockStatement | ExpressionStatement | IfStatement | BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement | WhileStatement | ForStatement | ForInStatement | TryStatement | CatchClause | Identifier | Literal | ThisExpression | ArrayExpression | ObjectExpreession | Property | FunctionExpression | BinaryExpression | UnaryExpression | AssignmentExpression | UpdateExpression | LogicalExpression | ConditionalExpression | NewExpression | CallExpression | MemberExpression | VariableDeclaration | FunctionDeclaration | VariableDeclarator ; export type Statement = | BlockStatement | EmptyStatement | ExpressionStatement | IfStatement | BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement | WhileStatement | ForStatement | ForInStatement | TryStatement | Declaration ; export type EmptyStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'EmptyStatement', } export type BlockStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'BlockStatement', body: Statement[], } export type ExpressionStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ExpressionStatement', expression: Expression, } export type IfStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'IfStatement', test: Expression, consequent: Statement, alternate: ?Statement, } export type BreakStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'BreakStatement', label: ?Identifier, } export type ContinueStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ContinueStatement', label: ?Identifier, } export type ReturnStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ReturnStatement', argument: ?Expression, } export type ThrowStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ThrowStatement', argument: ?Expression, } export type WhileStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'WhileStatement', test: Expression, body: Statement, } export type ForStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ForStatement', init: ?(VariableDeclaration | Expression), test: ?Expression, update: ?Expression, body: Statement, } export type ForInStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ForInStatement', left: VariableDeclaration | Expression, right: Expression, body: Statement, } export type TryStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'TryStatement', block: BlockStatement, handler: ?CatchClause, handlers: CatchClause[], finalizer: ?BlockStatement, }; export type CatchClause = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'CatchClause', param: Pattern, guard: ?Expression, body: BlockStatement, }; export type Expression = | Identifier | ThisExpression | Literal | FunctionExpression | BinaryExpression | UnaryExpression | AssignmentExpression | UpdateExpression | LogicalExpression | ConditionalExpression | NewExpression | CallExpression | MemberExpression | ArrayExpression | ObjectExpreession ; export type Identifier = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'Identifier', name: string, } export type Literal = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'Literal', value: ?(string | boolean | number | RegExp), regex: ?{ pattern: string, flags: string }, } export type ThisExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ThisExpression', } export type ArrayExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ArrayExpression', elements: Expression[], } export type ObjectExpreession = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ObjectExpression', properties: Property[], } export type Property = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'Property', kind: 'init' | 'get' | 'set', key: Literal | Identifier, value: Expression, }; export type FunctionExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'FunctionExpression', id: ?Identifier, params: Pattern[], body: BlockStatement, } export type BinaryExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'BinaryExpression', operator: BinaryOperator, left: Expression, right: Expression, } export type UnaryExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'UnaryExpression', operator: UnaryOperator, argument: Expression, prefix: boolean, }; export type AssignmentExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'AssignmentExpression', operator: AssignmentOperator, left: Pattern, right: Expression, }; export type UpdateExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'UpdateExpression', operator: UpdateOperator, argument: Expression, prefix: boolean, }; export type LogicalExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'LogicalExpression', operator: LogicalOperator, left: Expression, right: Expression, }; export type ConditionalExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'ConditionalExpression', test: Expression, consequent: Expression, alternate: Expression, }; export type NewExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'NewExpression', callee: Expression, arguments: Expression[], }; export type CallExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'CallExpression', callee: Expression, arguments: Expression[], }; export type MemberExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'MemberExpression', object: Expression, property: Identifier | Expression, computed: bool, } // ast-types exports all expressions as patterns. // That seems not like it was intended. export type Pattern = | Identifier ; export type Declaration = | VariableDeclaration | FunctionDeclaration ; export type VariableDeclaration = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'VariableDeclaration', kind: 'var' | 'let' | 'const', declarations: VariableDeclarator[], } export type FunctionDeclaration = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'FunctionDeclaration', id: Identifier, body: BlockStatement, params: Pattern[], } export type VariableDeclarator = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: 'VariableDeclarator', id: Pattern, init: ?Expression, } const a : any = null; export const builders : { emptyStatement() : EmptyStatement, blockStatement( body: Statement[] ) : BlockStatement, expressionStatement( expression: Expression ) : ExpressionStatement, ifStatement( test: Expression, consequent: Statement, alternate?: Statement ) : IfStatement, breakStatement( label?: Identifier ) : BreakStatement, continueStatement( label?: Identifier ) : ContinueStatement, returnStatement( argument: ?Expression ) : ReturnStatement, throwStatement( argument: ?Expression ) : ThrowStatement, whileStatement( test: Expression, body: Statement ) : WhileStatement, forStatement( init: ?(VariableDeclaration | Expression), test: ?Expression, update: ?Expression, body: Statement ) : ForStatement, forInStatement( left: VariableDeclaration | Expression, right: Expression, body: Statement ) : ForInStatement, tryStatement( block: BlockStatement, handler: ?CatchClause, handlers: CatchClause[], finalizer?: BlockStatement ) : TryStatement, catchClause( param: Pattern, guard: ?Expression, body: BlockStatement ) : CatchClause, identifier( name: string ) : Identifier, literal( value: ?(string | boolean | number | RegExp), regex?: { pattern: string, flags: string } ) : Literal, thisExpression() : ThisExpression, arrayExpression( elements: Expression[] ) : ArrayExpression, objectExpreession( properties: Property[] ) : ObjectExpreession, property( kind: 'init' | 'get' | 'set', key: Literal | Identifier, value: Expression ) : Property, functionExpression( id: ?Identifier, params: Pattern[], body: BlockStatement ) : FunctionExpression, binaryExpression( operator: BinaryOperator, left: Expression, right: Expression ) : BinaryExpression, unaryExpression( operator: UnaryOperator, argument: Expression, prefix: boolean ) : UnaryExpression, assignmentExpression( operator: AssignmentOperator, left: Pattern, right: Expression ) : AssignmentExpression, updateExpression( operator: UpdateOperator, argument: Expression, prefix: boolean ) : UpdateExpression, logicalExpression( operator: LogicalOperator, left: Expression, right: Expression ) : LogicalExpression, conditionalExpression( test: Expression, consequent: Expression, alternate: Expression ) : ConditionalExpression, newExpression( callee: Expression, arguments: Expression[] ) : NewExpression, callExpression( callee: Expression, arguments: Expression[] ) : CallExpression, memberExpression( object: Expression, property: Identifier | Expression, computed: bool ) : MemberExpression, variableDeclaration( kind: 'var' | 'let' | 'const', declarations: VariableDeclarator[] ) : VariableDeclaration, functionDeclaration( id: Identifier, body: BlockStatement, params: Pattern[] ) : FunctionDeclaration, variableDeclarator( id: Pattern, init?: Expression ) : VariableDeclarator, } = a; =====================================output===================================== /** * @flow */ export type Comment = { loc: ?SourceLocation, value: string, leading: boolean, trailing: boolean }; export type SourceLocation = { start: SourcePosition, end: SourcePosition, source: ?string }; export type SourcePosition = { line: number, column: number }; export type File = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "File", program: Program }; export type Program = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "Program", body: Statement[] }; export type BinaryOperator = | "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "&" // TODO Missing from the Parser API. | "|" | "^" | "in" | "instanceof" | ".."; export type UnaryOperator = | "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; export type AssignmentOperator = | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&="; export type UpdateOperator = "++" | "--"; export type LogicalOperator = "&&" | "||"; export type Node = | EmptyStatement | BlockStatement | ExpressionStatement | IfStatement | BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement | WhileStatement | ForStatement | ForInStatement | TryStatement | CatchClause | Identifier | Literal | ThisExpression | ArrayExpression | ObjectExpreession | Property | FunctionExpression | BinaryExpression | UnaryExpression | AssignmentExpression | UpdateExpression | LogicalExpression | ConditionalExpression | NewExpression | CallExpression | MemberExpression | VariableDeclaration | FunctionDeclaration | VariableDeclarator; export type Statement = | BlockStatement | EmptyStatement | ExpressionStatement | IfStatement | BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement | WhileStatement | ForStatement | ForInStatement | TryStatement | Declaration; export type EmptyStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "EmptyStatement" }; export type BlockStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "BlockStatement", body: Statement[] }; export type ExpressionStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ExpressionStatement", expression: Expression }; export type IfStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "IfStatement", test: Expression, consequent: Statement, alternate: ?Statement }; export type BreakStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "BreakStatement", label: ?Identifier }; export type ContinueStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ContinueStatement", label: ?Identifier }; export type ReturnStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ReturnStatement", argument: ?Expression }; export type ThrowStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ThrowStatement", argument: ?Expression }; export type WhileStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "WhileStatement", test: Expression, body: Statement }; export type ForStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ForStatement", init: ?(VariableDeclaration | Expression), test: ?Expression, update: ?Expression, body: Statement }; export type ForInStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ForInStatement", left: VariableDeclaration | Expression, right: Expression, body: Statement }; export type TryStatement = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "TryStatement", block: BlockStatement, handler: ?CatchClause, handlers: CatchClause[], finalizer: ?BlockStatement }; export type CatchClause = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "CatchClause", param: Pattern, guard: ?Expression, body: BlockStatement }; export type Expression = | Identifier | ThisExpression | Literal | FunctionExpression | BinaryExpression | UnaryExpression | AssignmentExpression | UpdateExpression | LogicalExpression | ConditionalExpression | NewExpression | CallExpression | MemberExpression | ArrayExpression | ObjectExpreession; export type Identifier = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "Identifier", name: string }; export type Literal = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "Literal", value: ?(string | boolean | number | RegExp), regex: ?{ pattern: string, flags: string } }; export type ThisExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ThisExpression" }; export type ArrayExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ArrayExpression", elements: Expression[] }; export type ObjectExpreession = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ObjectExpression", properties: Property[] }; export type Property = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "Property", kind: "init" | "get" | "set", key: Literal | Identifier, value: Expression }; export type FunctionExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "FunctionExpression", id: ?Identifier, params: Pattern[], body: BlockStatement }; export type BinaryExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "BinaryExpression", operator: BinaryOperator, left: Expression, right: Expression }; export type UnaryExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "UnaryExpression", operator: UnaryOperator, argument: Expression, prefix: boolean }; export type AssignmentExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "AssignmentExpression", operator: AssignmentOperator, left: Pattern, right: Expression }; export type UpdateExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "UpdateExpression", operator: UpdateOperator, argument: Expression, prefix: boolean }; export type LogicalExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "LogicalExpression", operator: LogicalOperator, left: Expression, right: Expression }; export type ConditionalExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "ConditionalExpression", test: Expression, consequent: Expression, alternate: Expression }; export type NewExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "NewExpression", callee: Expression, arguments: Expression[] }; export type CallExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "CallExpression", callee: Expression, arguments: Expression[] }; export type MemberExpression = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "MemberExpression", object: Expression, property: Identifier | Expression, computed: boolean }; // ast-types exports all expressions as patterns. // That seems not like it was intended. export type Pattern = Identifier; export type Declaration = VariableDeclaration | FunctionDeclaration; export type VariableDeclaration = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "VariableDeclaration", kind: "var" | "let" | "const", declarations: VariableDeclarator[] }; export type FunctionDeclaration = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "FunctionDeclaration", id: Identifier, body: BlockStatement, params: Pattern[] }; export type VariableDeclarator = { source: ?string, start: SourcePosition, end: SourcePosition, comments: ?Array, type: "VariableDeclarator", id: Pattern, init: ?Expression }; const a: any = null; export const builders: { emptyStatement(): EmptyStatement, blockStatement(body: Statement[]): BlockStatement, expressionStatement(expression: Expression): ExpressionStatement, ifStatement( test: Expression, consequent: Statement, alternate?: Statement ): IfStatement, breakStatement(label?: Identifier): BreakStatement, continueStatement(label?: Identifier): ContinueStatement, returnStatement(argument: ?Expression): ReturnStatement, throwStatement(argument: ?Expression): ThrowStatement, whileStatement(test: Expression, body: Statement): WhileStatement, forStatement( init: ?(VariableDeclaration | Expression), test: ?Expression, update: ?Expression, body: Statement ): ForStatement, forInStatement( left: VariableDeclaration | Expression, right: Expression, body: Statement ): ForInStatement, tryStatement( block: BlockStatement, handler: ?CatchClause, handlers: CatchClause[], finalizer?: BlockStatement ): TryStatement, catchClause( param: Pattern, guard: ?Expression, body: BlockStatement ): CatchClause, identifier(name: string): Identifier, literal( value: ?(string | boolean | number | RegExp), regex?: { pattern: string, flags: string } ): Literal, thisExpression(): ThisExpression, arrayExpression(elements: Expression[]): ArrayExpression, objectExpreession(properties: Property[]): ObjectExpreession, property( kind: "init" | "get" | "set", key: Literal | Identifier, value: Expression ): Property, functionExpression( id: ?Identifier, params: Pattern[], body: BlockStatement ): FunctionExpression, binaryExpression( operator: BinaryOperator, left: Expression, right: Expression ): BinaryExpression, unaryExpression( operator: UnaryOperator, argument: Expression, prefix: boolean ): UnaryExpression, assignmentExpression( operator: AssignmentOperator, left: Pattern, right: Expression ): AssignmentExpression, updateExpression( operator: UpdateOperator, argument: Expression, prefix: boolean ): UpdateExpression, logicalExpression( operator: LogicalOperator, left: Expression, right: Expression ): LogicalExpression, conditionalExpression( test: Expression, consequent: Expression, alternate: Expression ): ConditionalExpression, newExpression(callee: Expression, arguments: Expression[]): NewExpression, callExpression(callee: Expression, arguments: Expression[]): CallExpression, memberExpression( object: Expression, property: Identifier | Expression, computed: boolean ): MemberExpression, variableDeclaration( kind: "var" | "let" | "const", declarations: VariableDeclarator[] ): VariableDeclaration, functionDeclaration( id: Identifier, body: BlockStatement, params: Pattern[] ): FunctionDeclaration, variableDeclarator(id: Pattern, init?: Expression): VariableDeclarator } = a; ================================================================================ `;