we (web engine): Experimental web browser project to understand the limits of Claude
at js-parser 504 lines 12 kB view raw
1//! Abstract Syntax Tree node types for ECMAScript 2024. 2 3use crate::lexer::Span; 4 5/// A complete JavaScript program. 6#[derive(Debug, Clone, PartialEq)] 7pub struct Program { 8 pub body: Vec<Stmt>, 9 pub source_type: SourceType, 10 pub span: Span, 11} 12 13/// Whether the program is a script or module. 14#[derive(Debug, Clone, Copy, PartialEq, Eq)] 15pub enum SourceType { 16 Script, 17 Module, 18} 19 20// ── Statements ────────────────────────────────────────────── 21 22/// A statement or declaration. 23#[derive(Debug, Clone, PartialEq)] 24pub struct Stmt { 25 pub kind: StmtKind, 26 pub span: Span, 27} 28 29#[derive(Debug, Clone, PartialEq)] 30pub enum StmtKind { 31 /// Expression followed by semicolon. 32 Expr(Expr), 33 /// `{ ... }` 34 Block(Vec<Stmt>), 35 /// `var`/`let`/`const` declaration. 36 VarDecl { 37 kind: VarKind, 38 declarators: Vec<VarDeclarator>, 39 }, 40 /// `function name(...) { ... }` 41 FunctionDecl(FunctionDef), 42 /// `class Name { ... }` 43 ClassDecl(ClassDef), 44 /// `if (test) consequent else alternate` 45 If { 46 test: Expr, 47 consequent: Box<Stmt>, 48 alternate: Option<Box<Stmt>>, 49 }, 50 /// `for (init; test; update) body` 51 For { 52 init: Option<ForInit>, 53 test: Option<Expr>, 54 update: Option<Expr>, 55 body: Box<Stmt>, 56 }, 57 /// `for (left in right) body` 58 ForIn { 59 left: ForInOfLeft, 60 right: Expr, 61 body: Box<Stmt>, 62 }, 63 /// `for (left of right) body` 64 ForOf { 65 left: ForInOfLeft, 66 right: Expr, 67 body: Box<Stmt>, 68 is_await: bool, 69 }, 70 /// `while (test) body` 71 While { test: Expr, body: Box<Stmt> }, 72 /// `do body while (test)` 73 DoWhile { body: Box<Stmt>, test: Expr }, 74 /// `switch (discriminant) { cases }` 75 Switch { 76 discriminant: Expr, 77 cases: Vec<SwitchCase>, 78 }, 79 /// `try { block } catch (param) { handler } finally { finalizer }` 80 Try { 81 block: Vec<Stmt>, 82 handler: Option<CatchClause>, 83 finalizer: Option<Vec<Stmt>>, 84 }, 85 /// `return expr;` 86 Return(Option<Expr>), 87 /// `throw expr;` 88 Throw(Expr), 89 /// `break label;` 90 Break(Option<String>), 91 /// `continue label;` 92 Continue(Option<String>), 93 /// `label: stmt` 94 Labeled { label: String, body: Box<Stmt> }, 95 /// `with (object) body` 96 With { object: Expr, body: Box<Stmt> }, 97 /// `debugger;` 98 Debugger, 99 /// `;` 100 Empty, 101 /// `import` declaration. 102 Import { 103 specifiers: Vec<ImportSpecifier>, 104 source: String, 105 }, 106 /// `export` declaration. 107 Export(ExportDecl), 108} 109 110// ── Variable declarations ─────────────────────────────────── 111 112#[derive(Debug, Clone, Copy, PartialEq, Eq)] 113pub enum VarKind { 114 Var, 115 Let, 116 Const, 117} 118 119#[derive(Debug, Clone, PartialEq)] 120pub struct VarDeclarator { 121 pub pattern: Pattern, 122 pub init: Option<Expr>, 123 pub span: Span, 124} 125 126// ── For-statement helpers ─────────────────────────────────── 127 128#[derive(Debug, Clone, PartialEq)] 129pub enum ForInit { 130 VarDecl { 131 kind: VarKind, 132 declarators: Vec<VarDeclarator>, 133 }, 134 Expr(Expr), 135} 136 137#[derive(Debug, Clone, PartialEq)] 138pub enum ForInOfLeft { 139 VarDecl { kind: VarKind, pattern: Pattern }, 140 Pattern(Pattern), 141} 142 143// ── Switch / Try helpers ──────────────────────────────────── 144 145#[derive(Debug, Clone, PartialEq)] 146pub struct SwitchCase { 147 /// `None` for `default:`. 148 pub test: Option<Expr>, 149 pub consequent: Vec<Stmt>, 150 pub span: Span, 151} 152 153#[derive(Debug, Clone, PartialEq)] 154pub struct CatchClause { 155 pub param: Option<Pattern>, 156 pub body: Vec<Stmt>, 157 pub span: Span, 158} 159 160// ── Import / Export ───────────────────────────────────────── 161 162#[derive(Debug, Clone, PartialEq)] 163pub enum ImportSpecifier { 164 /// `import defaultExport from "mod"` 165 Default(String), 166 /// `import { foo } from "mod"` or `import { foo as bar } from "mod"` 167 Named { imported: String, local: String }, 168 /// `import * as ns from "mod"` 169 Namespace(String), 170} 171 172#[derive(Debug, Clone, PartialEq)] 173pub enum ExportDecl { 174 /// `export default expr` 175 Default(Expr), 176 /// `export function/class/var ...` 177 Declaration(Box<Stmt>), 178 /// `export { a, b as c }` 179 Named { 180 specifiers: Vec<ExportSpecifier>, 181 source: Option<String>, 182 }, 183 /// `export * from "mod"` 184 AllFrom(String), 185} 186 187#[derive(Debug, Clone, PartialEq)] 188pub struct ExportSpecifier { 189 pub local: String, 190 pub exported: String, 191} 192 193// ── Expressions ───────────────────────────────────────────── 194 195#[derive(Debug, Clone, PartialEq)] 196pub struct Expr { 197 pub kind: ExprKind, 198 pub span: Span, 199} 200 201#[derive(Debug, Clone, PartialEq)] 202pub enum ExprKind { 203 /// Numeric literal. 204 Number(f64), 205 /// String literal. 206 String(String), 207 /// `true` / `false`. 208 Bool(bool), 209 /// `null`. 210 Null, 211 /// An identifier reference. 212 Identifier(String), 213 /// `this`. 214 This, 215 /// `[a, b, c]` 216 Array(Vec<Option<ArrayElement>>), 217 /// `{ key: value, ... }` 218 Object(Vec<Property>), 219 /// `function name(...) { ... }` expression. 220 Function(FunctionDef), 221 /// `(...) => body` 222 Arrow { 223 params: Vec<Pattern>, 224 body: ArrowBody, 225 is_async: bool, 226 }, 227 /// `class Name { ... }` expression. 228 Class(ClassDef), 229 /// Prefix unary (`!x`, `-x`, `~x`, `typeof x`, `void x`, `delete x`). 230 Unary { op: UnaryOp, argument: Box<Expr> }, 231 /// `++x`, `--x`, `x++`, `x--`. 232 Update { 233 op: UpdateOp, 234 argument: Box<Expr>, 235 prefix: bool, 236 }, 237 /// `a + b`, `a * b`, etc. 238 Binary { 239 op: BinaryOp, 240 left: Box<Expr>, 241 right: Box<Expr>, 242 }, 243 /// `a && b`, `a || b`, `a ?? b`. 244 Logical { 245 op: LogicalOp, 246 left: Box<Expr>, 247 right: Box<Expr>, 248 }, 249 /// `a = b`, `a += b`, etc. 250 Assignment { 251 op: AssignOp, 252 left: Box<Expr>, 253 right: Box<Expr>, 254 }, 255 /// `test ? consequent : alternate` 256 Conditional { 257 test: Box<Expr>, 258 consequent: Box<Expr>, 259 alternate: Box<Expr>, 260 }, 261 /// `callee(arguments)` 262 Call { 263 callee: Box<Expr>, 264 arguments: Vec<Expr>, 265 }, 266 /// `new callee(arguments)` 267 New { 268 callee: Box<Expr>, 269 arguments: Vec<Expr>, 270 }, 271 /// `object.property` or `object[property]` 272 Member { 273 object: Box<Expr>, 274 property: Box<Expr>, 275 computed: bool, 276 }, 277 /// `obj?.prop`, `obj?.[expr]`, `fn?.(args)` 278 OptionalChain { base: Box<Expr> }, 279 /// Template literal: `` `hello ${name}` `` 280 TemplateLiteral { 281 quasis: Vec<String>, 282 expressions: Vec<Expr>, 283 }, 284 /// Tagged template: `` tag`string` `` 285 TaggedTemplate { tag: Box<Expr>, quasi: Box<Expr> }, 286 /// `a, b, c` 287 Sequence(Vec<Expr>), 288 /// `...expr` 289 Spread(Box<Expr>), 290 /// `yield expr` / `yield* expr` 291 Yield { 292 argument: Option<Box<Expr>>, 293 delegate: bool, 294 }, 295 /// `await expr` 296 Await(Box<Expr>), 297 /// `/pattern/flags` 298 RegExp { pattern: String, flags: String }, 299} 300 301// ── Array element ─────────────────────────────────────────── 302 303#[derive(Debug, Clone, PartialEq)] 304pub enum ArrayElement { 305 Expr(Expr), 306 Spread(Expr), 307} 308 309// ── Object literal ────────────────────────────────────────── 310 311#[derive(Debug, Clone, PartialEq)] 312pub struct Property { 313 pub key: PropertyKey, 314 pub value: Option<Expr>, 315 pub kind: PropertyKind, 316 pub computed: bool, 317 pub shorthand: bool, 318 pub method: bool, 319 pub span: Span, 320} 321 322#[derive(Debug, Clone, PartialEq)] 323pub enum PropertyKey { 324 Identifier(String), 325 String(String), 326 Number(f64), 327 Computed(Expr), 328} 329 330#[derive(Debug, Clone, Copy, PartialEq, Eq)] 331pub enum PropertyKind { 332 Init, 333 Get, 334 Set, 335} 336 337// ── Arrow function body ───────────────────────────────────── 338 339#[derive(Debug, Clone, PartialEq)] 340pub enum ArrowBody { 341 Expr(Box<Expr>), 342 Block(Vec<Stmt>), 343} 344 345// ── Function definition ───────────────────────────────────── 346 347#[derive(Debug, Clone, PartialEq)] 348pub struct FunctionDef { 349 pub id: Option<String>, 350 pub params: Vec<Pattern>, 351 pub body: Vec<Stmt>, 352 pub is_async: bool, 353 pub is_generator: bool, 354} 355 356// ── Class definition ──────────────────────────────────────── 357 358#[derive(Debug, Clone, PartialEq)] 359pub struct ClassDef { 360 pub id: Option<String>, 361 pub super_class: Option<Box<Expr>>, 362 pub body: Vec<ClassMember>, 363} 364 365#[derive(Debug, Clone, PartialEq)] 366pub struct ClassMember { 367 pub kind: ClassMemberKind, 368 pub span: Span, 369} 370 371#[derive(Debug, Clone, PartialEq)] 372pub enum ClassMemberKind { 373 Method { 374 key: PropertyKey, 375 value: FunctionDef, 376 kind: MethodKind, 377 is_static: bool, 378 computed: bool, 379 }, 380 Property { 381 key: PropertyKey, 382 value: Option<Expr>, 383 is_static: bool, 384 computed: bool, 385 }, 386} 387 388#[derive(Debug, Clone, Copy, PartialEq, Eq)] 389pub enum MethodKind { 390 Method, 391 Get, 392 Set, 393 Constructor, 394} 395 396// ── Patterns (destructuring) ──────────────────────────────── 397 398#[derive(Debug, Clone, PartialEq)] 399pub struct Pattern { 400 pub kind: PatternKind, 401 pub span: Span, 402} 403 404#[derive(Debug, Clone, PartialEq)] 405pub enum PatternKind { 406 /// Simple binding: `x` 407 Identifier(String), 408 /// Array destructuring: `[a, b, ...rest]` 409 Array { 410 elements: Vec<Option<Pattern>>, 411 rest: Option<Box<Pattern>>, 412 }, 413 /// Object destructuring: `{ a, b: c, ...rest }` 414 Object { 415 properties: Vec<ObjectPatternProp>, 416 rest: Option<Box<Pattern>>, 417 }, 418 /// Default value: `x = defaultValue` 419 Assign { 420 left: Box<Pattern>, 421 right: Box<Expr>, 422 }, 423} 424 425#[derive(Debug, Clone, PartialEq)] 426pub struct ObjectPatternProp { 427 pub key: PropertyKey, 428 pub value: Pattern, 429 pub computed: bool, 430 pub shorthand: bool, 431 pub span: Span, 432} 433 434// ── Operators ─────────────────────────────────────────────── 435 436#[derive(Debug, Clone, Copy, PartialEq, Eq)] 437pub enum UnaryOp { 438 Minus, 439 Plus, 440 Not, 441 BitwiseNot, 442 Typeof, 443 Void, 444 Delete, 445} 446 447#[derive(Debug, Clone, Copy, PartialEq, Eq)] 448pub enum UpdateOp { 449 Increment, 450 Decrement, 451} 452 453#[derive(Debug, Clone, Copy, PartialEq, Eq)] 454pub enum BinaryOp { 455 Add, 456 Sub, 457 Mul, 458 Div, 459 Rem, 460 Exp, 461 Eq, 462 Ne, 463 StrictEq, 464 StrictNe, 465 Lt, 466 Le, 467 Gt, 468 Ge, 469 Shl, 470 Shr, 471 Ushr, 472 BitAnd, 473 BitOr, 474 BitXor, 475 In, 476 Instanceof, 477} 478 479#[derive(Debug, Clone, Copy, PartialEq, Eq)] 480pub enum LogicalOp { 481 And, 482 Or, 483 Nullish, 484} 485 486#[derive(Debug, Clone, Copy, PartialEq, Eq)] 487pub enum AssignOp { 488 Assign, 489 AddAssign, 490 SubAssign, 491 MulAssign, 492 DivAssign, 493 RemAssign, 494 ExpAssign, 495 ShlAssign, 496 ShrAssign, 497 UshrAssign, 498 BitAndAssign, 499 BitOrAssign, 500 BitXorAssign, 501 AndAssign, 502 OrAssign, 503 NullishAssign, 504}