Something went wrong. Try again.
we (web engine): Experimental web browser project to understand the limits of Claude
Something went wrong. Try again.
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505//! Abstract Syntax Tree node types for ECMAScript 2024.
use crate::lexer::Span;
/// A complete JavaScript program.#[derive(Debug, Clone, PartialEq)]pub struct Program { pub body: Vec<Stmt>, pub source_type: SourceType, pub span: Span,}
/// Whether the program is a script or module.#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum SourceType { Script, Module,}
// ── Statements ──────────────────────────────────────────────
/// A statement or declaration.#[derive(Debug, Clone, PartialEq)]pub struct Stmt { pub kind: StmtKind, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub enum StmtKind { /// Expression followed by semicolon. Expr(Expr), /// `{ ... }` Block(Vec<Stmt>), /// `var`/`let`/`const` declaration. VarDecl { kind: VarKind, declarators: Vec<VarDeclarator>, }, /// `function name(...) { ... }` FunctionDecl(FunctionDef), /// `class Name { ... }` ClassDecl(ClassDef), /// `if (test) consequent else alternate` If { test: Expr, consequent: Box<Stmt>, alternate: Option<Box<Stmt>>, }, /// `for (init; test; update) body` For { init: Option<ForInit>, test: Option<Expr>, update: Option<Expr>, body: Box<Stmt>, }, /// `for (left in right) body` ForIn { left: ForInOfLeft, right: Expr, body: Box<Stmt>, }, /// `for (left of right) body` ForOf { left: ForInOfLeft, right: Expr, body: Box<Stmt>, is_await: bool, }, /// `while (test) body` While { test: Expr, body: Box<Stmt> }, /// `do body while (test)` DoWhile { body: Box<Stmt>, test: Expr }, /// `switch (discriminant) { cases }` Switch { discriminant: Expr, cases: Vec<SwitchCase>, }, /// `try { block } catch (param) { handler } finally { finalizer }` Try { block: Vec<Stmt>, handler: Option<CatchClause>, finalizer: Option<Vec<Stmt>>, }, /// `return expr;` Return(Option<Expr>), /// `throw expr;` Throw(Expr), /// `break label;` Break(Option<String>), /// `continue label;` Continue(Option<String>), /// `label: stmt` Labeled { label: String, body: Box<Stmt> }, /// `with (object) body` With { object: Expr, body: Box<Stmt> }, /// `debugger;` Debugger, /// `;` Empty, /// `import` declaration. Import { specifiers: Vec<ImportSpecifier>, source: String, }, /// `export` declaration. Export(ExportDecl),}
// ── Variable declarations ───────────────────────────────────
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum VarKind { Var, Let, Const,}
#[derive(Debug, Clone, PartialEq)]pub struct VarDeclarator { pub pattern: Pattern, pub init: Option<Expr>, pub span: Span,}
// ── For-statement helpers ───────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub enum ForInit { VarDecl { kind: VarKind, declarators: Vec<VarDeclarator>, }, Expr(Expr),}
#[derive(Debug, Clone, PartialEq)]pub enum ForInOfLeft { VarDecl { kind: VarKind, pattern: Pattern }, Pattern(Pattern),}
// ── Switch / Try helpers ────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct SwitchCase { /// `None` for `default:`. pub test: Option<Expr>, pub consequent: Vec<Stmt>, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub struct CatchClause { pub param: Option<Pattern>, pub body: Vec<Stmt>, pub span: Span,}
// ── Import / Export ─────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub enum ImportSpecifier { /// `import defaultExport from "mod"` Default(String), /// `import { foo } from "mod"` or `import { foo as bar } from "mod"` Named { imported: String, local: String }, /// `import * as ns from "mod"` Namespace(String),}
#[derive(Debug, Clone, PartialEq)]pub enum ExportDecl { /// `export default expr` Default(Expr), /// `export function/class/var ...` Declaration(Box<Stmt>), /// `export { a, b as c }` Named { specifiers: Vec<ExportSpecifier>, source: Option<String>, }, /// `export * from "mod"` AllFrom(String),}
#[derive(Debug, Clone, PartialEq)]pub struct ExportSpecifier { pub local: String, pub exported: String,}
// ── Expressions ─────────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct Expr { pub kind: ExprKind, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub enum ExprKind { /// Numeric literal. Number(f64), /// String literal. String(String), /// `true` / `false`. Bool(bool), /// `null`. Null, /// An identifier reference. Identifier(String), /// `this`. This, /// `[a, b, c]` Array(Vec<Option<ArrayElement>>), /// `{ key: value, ... }` Object(Vec<Property>), /// `function name(...) { ... }` expression. Function(FunctionDef), /// `(...) => body` Arrow { params: Vec<Pattern>, body: ArrowBody, is_async: bool, }, /// `class Name { ... }` expression. Class(ClassDef), /// Prefix unary (`!x`, `-x`, `~x`, `typeof x`, `void x`, `delete x`). Unary { op: UnaryOp, argument: Box<Expr> }, /// `++x`, `--x`, `x++`, `x--`. Update { op: UpdateOp, argument: Box<Expr>, prefix: bool, }, /// `a + b`, `a * b`, etc. Binary { op: BinaryOp, left: Box<Expr>, right: Box<Expr>, }, /// `a && b`, `a || b`, `a ?? b`. Logical { op: LogicalOp, left: Box<Expr>, right: Box<Expr>, }, /// `a = b`, `a += b`, etc. Assignment { op: AssignOp, left: Box<Expr>, right: Box<Expr>, }, /// `test ? consequent : alternate` Conditional { test: Box<Expr>, consequent: Box<Expr>, alternate: Box<Expr>, }, /// `callee(arguments)` Call { callee: Box<Expr>, arguments: Vec<Expr>, }, /// `new callee(arguments)` New { callee: Box<Expr>, arguments: Vec<Expr>, }, /// `object.property` or `object[property]` Member { object: Box<Expr>, property: Box<Expr>, computed: bool, }, /// `obj?.prop`, `obj?.[expr]`, `fn?.(args)` OptionalChain { base: Box<Expr> }, /// Template literal: `` `hello ${name}` `` TemplateLiteral { quasis: Vec<String>, expressions: Vec<Expr>, }, /// Tagged template: `` tag`string` `` TaggedTemplate { tag: Box<Expr>, quasi: Box<Expr> }, /// `a, b, c` Sequence(Vec<Expr>), /// `...expr` Spread(Box<Expr>), /// `yield expr` / `yield* expr` Yield { argument: Option<Box<Expr>>, delegate: bool, }, /// `await expr` Await(Box<Expr>), /// `/pattern/flags` RegExp { pattern: String, flags: String },}
// ── Array element ───────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub enum ArrayElement { Expr(Expr), Spread(Expr),}
// ── Object literal ──────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct Property { pub key: PropertyKey, pub value: Option<Expr>, pub kind: PropertyKind, pub computed: bool, pub shorthand: bool, pub method: bool, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub enum PropertyKey { Identifier(String), String(String), Number(f64), Computed(Expr),}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum PropertyKind { Init, Get, Set,}
// ── Arrow function body ─────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub enum ArrowBody { Expr(Box<Expr>), Block(Vec<Stmt>),}
// ── Function definition ─────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct FunctionDef { pub id: Option<String>, pub params: Vec<Pattern>, pub body: Vec<Stmt>, pub is_async: bool, pub is_generator: bool,}
// ── Class definition ────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct ClassDef { pub id: Option<String>, pub super_class: Option<Box<Expr>>, pub body: Vec<ClassMember>,}
#[derive(Debug, Clone, PartialEq)]pub struct ClassMember { pub kind: ClassMemberKind, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub enum ClassMemberKind { Method { key: PropertyKey, value: FunctionDef, kind: MethodKind, is_static: bool, computed: bool, }, Property { key: PropertyKey, value: Option<Expr>, is_static: bool, computed: bool, },}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum MethodKind { Method, Get, Set, Constructor,}
// ── Patterns (destructuring) ────────────────────────────────
#[derive(Debug, Clone, PartialEq)]pub struct Pattern { pub kind: PatternKind, pub span: Span,}
#[derive(Debug, Clone, PartialEq)]pub enum PatternKind { /// Simple binding: `x` Identifier(String), /// Array destructuring: `[a, b, ...rest]` Array { elements: Vec<Option<Pattern>>, rest: Option<Box<Pattern>>, }, /// Object destructuring: `{ a, b: c, ...rest }` Object { properties: Vec<ObjectPatternProp>, rest: Option<Box<Pattern>>, }, /// Default value: `x = defaultValue` Assign { left: Box<Pattern>, right: Box<Expr>, },}
#[derive(Debug, Clone, PartialEq)]pub struct ObjectPatternProp { pub key: PropertyKey, pub value: Pattern, pub computed: bool, pub shorthand: bool, pub span: Span,}
// ── Operators ───────────────────────────────────────────────
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum UnaryOp { Minus, Plus, Not, BitwiseNot, Typeof, Void, Delete,}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum UpdateOp { Increment, Decrement,}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum BinaryOp { Add, Sub, Mul, Div, Rem, Exp, Eq, Ne, StrictEq, StrictNe, Lt, Le, Gt, Ge, Shl, Shr, Ushr, BitAnd, BitOr, BitXor, In, Instanceof,}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum LogicalOp { And, Or, Nullish,}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum AssignOp { Assign, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, ExpAssign, ShlAssign, ShrAssign, UshrAssign, BitAndAssign, BitOrAssign, BitXorAssign, AndAssign, OrAssign, NullishAssign,}