pub const Loc = struct { start: usize, end: usize, }; pub const Node = union(enum) { program: Program, stmt: Stmt, expr: Expr, pat: Pat, decl: Decl, literal: Lit, property: Prop, template: Template, spread: Spread, decorator: Decorator, import_specifier: ImportSpecifier, export_specifier: ExportSpecifier, import_attr: ImportAttribute, catch_clause: CatchClause, switch_case: SwitchCase, }; pub const Program = struct { body: []const Node, loc: Loc, }; pub const StmtType = union(enum) { block: BlockStmt, empty: void, debugger: void, expr: ExprStmt, @"if": IfStmt, @"while": WhileStmt, do_while: DoWhileStmt, @"for": ForStmt, for_in: ForInStmt, for_of: ForOfStmt, @"continue": ContinueStmt, @"break": BreakStmt, @"return": ReturnStmt, @"switch": SwitchStmt, throw: ThrowStmt, @"try": TryStmt, labelled: LabelledStmt, with: WithStmt, variable: VarStmt, using: UsingStmt, import: ImportDecl, @"export": ExportDecl, }; pub const Stmt = struct { loc: Loc, data: StmtType, }; pub const ExprType = union(enum) { identifier: []const u8, this: void, super: void, null: void, bool: bool, number: f64, string: []const u8, regex: Regex, array: ArrayExpr, object: ObjectExpr, func: FnExpr, arrow: ArrowFn, class: ClassExpr, template: TemplateLit, tagged_template: TaggedTemplate, member: MemberExpr, computed_member: ComputedMember, call: CallExpr, new: NewExpr, chain: ChainExpr, unary: UnaryExpr, binary: BinaryExpr, update: UpdateExpr, conditional: IfExpr, assign: AssignExpr, sequence: SeqExpr, spread: SpreadElem, yield: YieldExpr, await: AwaitExpr, meta_prop: MetaProp, parenthesized: *const Expr, private_ident: []const u8, }; pub const Expr = struct { loc: Loc, data: ExprType, }; pub const PatType = union(enum) { ident: []const u8, object: ObjectPat, array: ArrayPat, assign: AssignPat, rest: RestPat, }; pub const Pat = struct { loc: Loc, data: PatType, }; pub const DeclType = union(enum) { @"fn": FnDecl, class: ClassDecl, @"var": VarDecl, lexical: LexicalDecl, using: UsingDecl, import: ImportDecl, @"export": ExportDecl, export_default: ExportDefault, }; pub const Decl = struct { loc: Loc, data: DeclType, }; pub const LitType = union(enum) { null: void, bool: bool, number: f64, string: []const u8, regex: Regex, bigint: []const u8, }; pub const Lit = struct { loc: Loc, data: LitType, }; pub const Regex = struct { pattern: []const u8, flags: []const u8, }; pub const PropType = union(enum) { init: PropInit, get: PropGet, set: PropSet, shorthand: []const u8, spread: SpreadElem, method: FnExpr, }; pub const Prop = struct { loc: Loc, key: PropKey, data: PropType, }; pub const PropKey = union(enum) { ident: []const u8, string: []const u8, number: f64, computed: *const Expr, private: []const u8, }; pub const PropInit = struct { key: PropKey, value: *const Expr, }; pub const PropGet = struct { key: PropKey, body: BlockStmt, }; pub const PropSet = struct { key: PropKey, param: Pat, body: BlockStmt, }; pub const SpreadElem = struct { loc: Loc, arg: *const Expr, }; pub const BlockStmt = struct { loc: Loc, body: []const Stmt, }; pub const ExprStmt = struct { loc: Loc, expr: *const Expr, }; pub const IfStmt = struct { loc: Loc, condition: *const Expr, consequent: *const Stmt, alternate: ?*const Stmt, }; pub const WhileStmt = struct { loc: Loc, condition: *const Expr, body: *const Stmt, }; pub const DoWhileStmt = struct { loc: Loc, body: *const Stmt, condition: *const Expr, }; pub const ForStmt = struct { loc: Loc, init: ?union(enum) { expr: *const Expr, decl: *const Decl, }, condition: ?*const Expr, update: ?*const Expr, body: *const Stmt, }; pub const ForInStmt = struct { loc: Loc, left: union(enum) { expr: *const Expr, decl: *const Decl, }, right: *const Expr, body: *const Stmt, }; pub const ForOfStmt = struct { loc: Loc, await_token: bool, left: union(enum) { expr: *const Expr, decl: *const Decl, }, right: *const Expr, body: *const Stmt, }; pub const ContinueStmt = struct { loc: Loc, label: ?[]const u8, }; pub const BreakStmt = struct { loc: Loc, label: ?[]const u8, }; pub const ReturnStmt = struct { loc: Loc, arg: ?*const Expr, }; pub const SwitchStmt = struct { loc: Loc, discriminant: *const Expr, cases: []const SwitchCase, }; pub const SwitchCase = struct { loc: Loc, condition: ?*const Expr, consequent: []const Stmt, }; pub const ThrowStmt = struct { loc: Loc, arg: *const Expr, }; pub const TryStmt = struct { loc: Loc, block: BlockStmt, handler: ?CatchClause, finalizer: ?BlockStmt, }; pub const CatchClause = struct { loc: Loc, param: ?Pat, body: BlockStmt, }; pub const LabelledStmt = struct { loc: Loc, label: []const u8, body: *const Stmt, }; pub const WithStmt = struct { loc: Loc, obj: *const Expr, body: *const Stmt, }; pub const VarStmt = struct { loc: Loc, kind: VarKind, decls: []const VarDeclarator, }; pub const UsingStmt = struct { loc: Loc, decls: []const VarDeclarator, }; pub const VarKind = enum { @"var", let, @"const", }; pub const VarDecl = struct { loc: Loc, kind: VarKind, decls: []const VarDeclarator, }; pub const LexicalDecl = struct { loc: Loc, kind: VarKind, decls: []const VarDeclarator, }; pub const UsingDecl = struct { loc: Loc, is_await: bool, decls: []const VarDeclarator, }; pub const VarDeclarator = struct { loc: Loc, id: Pat, init: ?*const Expr, }; pub const ObjectPat = struct { loc: Loc, props: []const PatProp, rest: ?*const Pat, }; pub const PatProp = union(enum) { key_value: struct { key: PropKey, value: *const Pat, }, shorthand: []const u8, rest: *const Pat, }; pub const ArrayPat = struct { loc: Loc, elems: []const ?Pat, rest: ?*const Pat, }; pub const AssignPat = struct { loc: Loc, left: *const Pat, right: *const Expr, }; pub const RestPat = struct { loc: Loc, arg: *const Pat, }; pub const FnType = union(enum) { normal: void, generator: void, async: void, async_generator: void, }; pub const FnDecl = struct { loc: Loc, fn_type: FnType, id: ?[]const u8, params: []const Pat, body: BlockStmt, }; pub const FnExpr = struct { loc: Loc, fn_type: FnType, id: ?[]const u8, params: []const Pat, body: BlockStmt, }; pub const ArrowFn = struct { loc: Loc, async_token: bool, params: []const Pat, body: union(enum) { block: BlockStmt, expr: *const Expr, }, }; pub const ClassDecl = struct { loc: Loc, id: ?[]const u8, super_class: ?*const Expr, body: []const ClassElem, }; pub const ClassExpr = struct { loc: Loc, id: ?[]const u8, super_class: ?*const Expr, body: []const ClassElem, }; pub const ClassElem = union(enum) { method: FnExpr, get: PropGet, set: PropSet, field: FieldDef, static_block: BlockStmt, static_method: FnExpr, static_get: PropGet, static_set: PropSet, static_field: FieldDef, }; pub const FieldDef = struct { loc: Loc, key: PropKey, value: ?*const Expr, }; pub const ImportDecl = struct { loc: Loc, specifiers: []const ImportSpecifier, source: []const u8, attributes: []const ImportAttribute, }; pub const ImportSpecifier = union(enum) { default: []const u8, namespace: []const u8, named: struct { imported: []const u8, local: []const u8 }, }; pub const ImportAttribute = struct { key: []const u8, value: []const u8, }; pub const ExportDecl = struct { loc: Loc, declaration: ?*const Decl, specifiers: ?[]const ExportSpecifier, source: ?[]const u8, }; pub const ExportSpecifier = struct { loc: Loc, exported: []const u8, local: []const u8, }; pub const ExportDefault = struct { loc: Loc, declaration: *const Decl, }; pub const ArrayExpr = struct { loc: Loc, elems: []const ?Expr, }; pub const ObjectExpr = struct { loc: Loc, props: []const Prop, }; pub const MemberExpr = struct { loc: Loc, obj: *const Expr, prop: union(enum) { ident: []const u8, private: []const u8, }, }; pub const ComputedMember = struct { loc: Loc, obj: *const Expr, expr: *const Expr, }; pub const CallExpr = struct { loc: Loc, callee: *const Expr, args: []const Expr, optional: bool, }; pub const NewExpr = struct { loc: Loc, callee: *const Expr, args: []const Expr, }; pub const ChainExpr = struct { loc: Loc, expr: *const Expr, }; pub const UnaryOp = enum { @"-", @"+", @"!", @"~", typeof, void, delete, }; pub const UnaryExpr = struct { loc: Loc, op: UnaryOp, arg: *const Expr, prefix: bool, }; pub const BinaryOp = enum { @"==", @"!=", @"===", @"!==", @"<", @"<=", @">", @">=", @"<<", @">>", @">>>", @"+", @"-", @"*", @"/", @"%", @"**", @"|", @"^", @"&", in, instanceof, @"||", @"&&", @"??", }; pub const BinaryExpr = struct { loc: Loc, op: BinaryOp, left: *const Expr, right: *const Expr, }; pub const UpdateOp = enum { @"++", @"--", }; pub const UpdateExpr = struct { loc: Loc, op: UpdateOp, arg: *const Expr, prefix: bool, }; pub const IfExpr = struct { loc: Loc, condition: *const Expr, consequent: *const Expr, alternate: *const Expr, }; pub const AssignOp = enum { @"=", @"+=", @"-=", @"*=", @"/=", @"%=", @"**=", @"<<=", @">>=", @">>>=", @"|=", @"^=", @"&=", @"||=", @"&&=", @"??=", }; pub const AssignExpr = struct { loc: Loc, op: AssignOp, left: *const Expr, right: *const Expr, }; pub const SeqExpr = struct { loc: Loc, exprs: []const Expr, }; pub const SpreadElem = struct { loc: Loc, arg: *const Expr, }; pub const YieldExpr = struct { loc: Loc, arg: ?*const Expr, delegate: bool, }; pub const AwaitExpr = struct { loc: Loc, arg: *const Expr, }; pub const MetaProp = struct { loc: Loc, meta: []const u8, prop: []const u8, }; pub const TemplateLit = struct { loc: Loc, quasis: []const TemplateElem, exprs: []const Expr, }; pub const TemplateElem = struct { loc: Loc, value: []const u8, tail: bool, }; pub const TaggedTemplate = struct { loc: Loc, tag: *const Expr, quasi: TemplateLit, }; pub const Decorator = struct { loc: Loc, expr: *const Expr, };