Skip to main content

bamts_compiler/
parser.rs

1//! The syntactic parser: a recovered token stream to a recovered [`SourceFile`].
2//!
3//! The parser is *total*: it accepts any scanned token stream, never panics,
4//! and always produces a [`SourceFile`] whose statement list covers the whole
5//! source. Grammar errors are represented with [`Token::missing`] tokens and
6//! `Missing*` node products instead of aborting, and every list loop carries a
7//! forward-progress guard so recovery can never stall.
8//!
9//! # Rescans
10//!
11//! Two lexical forms depend on grammar context, and the scanner deliberately
12//! refuses to guess them. The parser resolves both with an explicit
13//! token-cursor rescan over the already-scanned stream (the design
14//! [`crate::scanner::Scanner`] documents as the alternative to driving the
15//! scanner directly):
16//!
17//! * At an expression start, a [`TokenKind::Slash`]/[`TokenKind::SlashEq`]
18//!   token is re-lexed as a regular-expression literal directly from the
19//!   source text, using the same lexical rules as
20//!   [`crate::scanner::Scanner::rescan_regex`]. The tokens covered by the new
21//!   literal are replaced so the stored token stream still tiles the source.
22//! * When a type-argument, type-parameter, or heritage list closes, a greedily
23//!   formed `>>`/`>>>`/`>=`-family token is split into a single
24//!   [`TokenKind::GreaterThan`] plus its remainder token, mirroring
25//!   [`crate::scanner::Scanner::rescan_greater_than`]. The symmetric split is
26//!   applied to `<<` when a type context opens.
27//!
28//! Template literals never need a parser rescan here: the single-pass scanner
29//! already segments them deterministically with brace tracking.
30//!
31//! # Context sensitivity
32//!
33//! Contextual keywords are produced by the scanner as dedicated tokens; the
34//! parser decides from grammar position whether `type`, `as`, `namespace`,
35//! `let`, and the rest act as keywords or ordinary identifiers.
36//! [`ScriptKind`] drives the remaining decisions: TypeScript-only syntax in a
37//! JavaScript source parses (for recovery) but is diagnosed, `<T>expr` type
38//! assertions exist only in non-React TypeScript, and a `<` opening JSX in a
39//! React source is diagnosed as unsupported because the fixed [`NodeKind`]
40//! space has no JSX productions.
41
42use std::sync::Arc;
43
44use crate::diagnostic::{Diagnostic, DiagnosticCode, Recovered};
45use crate::scanner::ScannedSource;
46use crate::source::{ScriptKind, SourceId, SourceText, TextRange, Utf16Pos};
47use crate::syntax::{
48    Accessibility, ArrayBindingElement, ArrayBindingPattern, ArrayElement, ArrayLiteral,
49    ArrowFunction, AsExpression, AssignmentArrayElement, AssignmentArrayPattern,
50    AssignmentBindingPattern, AssignmentExpression, AssignmentMemberTarget,
51    AssignmentObjectPattern, AssignmentObjectProperty, AssignmentOperator, AssignmentTarget,
52    AssignmentTargetNode, AutoAccessor, AwaitExpression, BigIntLiteral, BinaryExpression,
53    BinaryOperator, BindingPattern, Block, BlockNode, BooleanLiteral, CallArgument, CallExpression,
54    CallSignature, CatchClause, CatchClauseNode, ClassDeclaration, ClassExpression, ClassHeritage,
55    ClassMember, ClassMemberNode, ClassProperty, ConditionalExpression, ConditionalType,
56    ConstructSignature, ConstructorDeclaration, ConstructorType, DeclarationModifiers, Decorator,
57    DecoratorNode, DoWhileStatement, EntityName, EnumDeclaration, EnumMember, EnumMemberNode,
58    ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportDefaultValue,
59    ExportNamedDeclaration, ExportSpecifier, ExportSpecifierMode, ExportSpecifierNode, Expr,
60    Expression, ExpressionStatement, ExternalModuleReference, ForBinding, ForInStatement,
61    ForInitializer, ForOfMode, ForOfStatement, ForStatement, FunctionBody, FunctionDeclaration,
62    FunctionExpression, FunctionLike, FunctionType, FunctionTypeParameter, Identifier,
63    IdentifierNode, IfStatement, ImportAttribute, ImportAttributes, ImportBinding, ImportClause,
64    ImportDeclaration, ImportEqualsDeclaration, ImportExpression, ImportSpecifier,
65    ImportSpecifierMode, ImportSpecifierNode, ImportType, IndexSignature, IndexedAccessType,
66    InferType, InterfaceDeclaration, JumpStatement, KeywordType, LabeledStatement, Literal,
67    LogicalExpression, LogicalOperator, MappedModifier, MappedType, MemberExpression,
68    MemberProperty, MetaProperty, MethodDeclaration, MissingNode, ModuleExportName,
69    NamespaceDeclaration, NewExpression, Node, NodeId, NodeKind, NonNullExpression, NullLiteral,
70    NumericLiteral, ObjectBindingPattern, ObjectBindingProperty, ObjectLiteral, ObjectMember,
71    ObjectMemberNode, ObjectMethod, ObjectProperty, ObjectType, Parameter, ParameterModifiers,
72    ParameterNode, Pattern, PrivateIdentifier, PropertyModifier, PropertyName, RegexLiteral,
73    RestBindingPattern, ReturnStatement, SatisfiesExpression, SequenceExpression, SourceFile,
74    SpreadElement, Statement, Stmt, StringLiteral, StringLiteralNode, SwitchCase, SwitchCaseNode,
75    SwitchStatement, TaggedTemplateExpression, TemplateElement, TemplateLiteral,
76    TemplateLiteralType, ThrowStatement, Token, TokenKind, TryStatement, TupleElement, TupleType,
77    Ty, TypeAliasDeclaration, TypeAnnotation, TypeAnnotationNode, TypeArgumentList,
78    TypeAssertionExpression, TypeIndexSignature, TypeLiteral, TypeMember, TypeMemberNode,
79    TypeMethodSignature, TypeNode, TypeOperator, TypeParameter, TypeParameterList,
80    TypeParameterNode, TypePredicate, TypePropertySignature, TypeQuery, TypeReference,
81    UnaryExpression, UnaryOperator, UpdateExpression, UpdateOperator, VariableDeclaration,
82    VariableDeclarator, VariableDeclaratorNode, VariableKind, Variance, WhileStatement,
83    WithStatement, YieldExpression,
84};
85
86/// A token of one kind was required by the grammar but absent.
87const EXPECTED_TOKEN: DiagnosticCode = DiagnosticCode::new("BAMTS-P001");
88/// An expression was required but the next token cannot begin one.
89const EXPECTED_EXPRESSION: DiagnosticCode = DiagnosticCode::new("BAMTS-P002");
90/// An identifier was required but the next token is not identifier-like.
91const EXPECTED_IDENTIFIER: DiagnosticCode = DiagnosticCode::new("BAMTS-P003");
92/// A type was required but the next token cannot begin one.
93const EXPECTED_TYPE: DiagnosticCode = DiagnosticCode::new("BAMTS-P004");
94/// A token no grammar production could consume was skipped for recovery.
95const UNEXPECTED_TOKEN: DiagnosticCode = DiagnosticCode::new("BAMTS-P005");
96/// The left operand of an assignment or update is not a valid target.
97const INVALID_ASSIGNMENT_TARGET: DiagnosticCode = DiagnosticCode::new("BAMTS-P006");
98/// TypeScript-only syntax appeared in a JavaScript source.
99const TYPESCRIPT_SYNTAX_IN_JAVASCRIPT: DiagnosticCode = DiagnosticCode::new("BAMTS-P007");
100/// A syntax form the fixed node space cannot represent (JSX, `module "name"`).
101const UNSUPPORTED_SYNTAX: DiagnosticCode = DiagnosticCode::new("BAMTS-P008");
102/// A property name was required but the next token cannot begin one.
103const EXPECTED_PROPERTY_NAME: DiagnosticCode = DiagnosticCode::new("BAMTS-P009");
104/// Nesting exceeded the recovery depth bound; the construct was abandoned.
105const NESTING_TOO_DEEP: DiagnosticCode = DiagnosticCode::new("BAMTS-P010");
106/// Unterminated regular-expression literal (shared with the scanner code).
107const UNTERMINATED_REGEX: DiagnosticCode = DiagnosticCode::new("BAMTS-L004");
108
109/// The maximum expression/type nesting depth before recovery abandons a
110/// construct.
111///
112/// A single depth budget is shared by every recursive grammar edge an attacker
113/// can nest without a bracketed list in between: prefix unary operators, the
114/// right-recursive `**` operator, conditional, assignment, and parenthesized
115/// expressions, plus types. Flat lists (statements, members, arguments,
116/// elements) are parsed iteratively, so this bound is reached only through
117/// genuinely nested syntax such as `- - - …` or `((((…))))`, keeping
118/// attacker-controlled inputs from exhausting the native stack without any
119/// process-wide stack workaround.
120const MAX_DEPTH: u32 = 256;
121
122/// Parses a scanned source into a recovered [`SourceFile`].
123///
124/// The scanner's diagnostics are consumed, unioned with the parse diagnostics,
125/// canonically ordered, and deduplicated; the identical vector is stored in the
126/// [`SourceFile`] and returned in the [`Recovered`] wrapper. The stored token
127/// stream is the parser-observed stream: identical to the scanner's except
128/// where a grammar-driven rescan merged a regular-expression literal or split
129/// a `>`-family operator, so it still tiles the source and retains all trivia
130/// and the end-of-file token.
131#[must_use]
132pub fn parse(scanned: Recovered<ScannedSource>) -> Recovered<SourceFile> {
133    let (scanned, lexical) = scanned.into_parts();
134    let source_id = scanned.source_id();
135    let script_kind = scanned.script_kind();
136    let source = Arc::clone(scanned.source());
137    let eof = *scanned.eof();
138    let tokens = scanned.tokens().to_vec();
139
140    let mut parser = Parser::new(source_id, script_kind, source, tokens, eof);
141    let statements = parser.parse_statements_until(&[]);
142
143    // The default scanner pass emits only `Slash`/`SlashEq`, never a
144    // `RegularExpressionLiteral`; every such token in the final stream is a
145    // committed parser regex rescan. The lexical diagnostics the default pass
146    // recorded inside those spans reflect the wrong (division) interpretation,
147    // so they are dropped and superseded by the rescan's own diagnostics.
148    let regex_spans: Vec<TextRange> = parser
149        .tokens
150        .iter()
151        .filter(|t| t.kind() == TokenKind::RegularExpressionLiteral)
152        .map(|t| t.range())
153        .collect();
154    let mut diagnostics = lexical;
155    diagnostics.retain(|diagnostic| {
156        let start = diagnostic.range().start().get();
157        !regex_spans
158            .iter()
159            .any(|span| start >= span.start().get() && start < span.end().get())
160    });
161    diagnostics.extend(parser.diagnostics.iter().cloned());
162    diagnostics.sort();
163    diagnostics.dedup();
164
165    let full_range = TextRange::new(Utf16Pos::ZERO, parser.source.len_utf16())
166        .expect("a source range starts at zero");
167    let file_id = parser.fresh_id();
168    let file = SourceFile::new(
169        file_id,
170        source_id,
171        script_kind,
172        full_range,
173        parser.source,
174        parser.tokens,
175        statements,
176        eof,
177        diagnostics.clone(),
178    );
179    Recovered::new(file, diagnostics)
180}
181
182/// One reversible token-stream rescan, journaled so speculative parses can
183/// undo their lexical reinterpretations on rollback.
184struct RescanEdit {
185    index: usize,
186    removed: Vec<Token>,
187    inserted: usize,
188}
189
190/// A restorable parser position for speculative parsing.
191#[derive(Clone, Copy)]
192struct ParserCheckpoint {
193    cursor: usize,
194    prev_end: usize,
195    diagnostics: usize,
196    next_node_id: u32,
197    journal: usize,
198}
199
200struct Parser {
201    source_id: SourceId,
202    script_kind: ScriptKind,
203    source: Arc<SourceText>,
204    tokens: Vec<Token>,
205    eof: Token,
206    /// Index of the current significant (non-trivia) token.
207    cursor: usize,
208    /// UTF-16 end of the most recently consumed significant token.
209    prev_end: usize,
210    diagnostics: Vec<Diagnostic>,
211    next_node_id: u32,
212    journal: Vec<RescanEdit>,
213    depth: u32,
214}
215
216fn is_trivia(kind: TokenKind) -> bool {
217    matches!(
218        kind,
219        TokenKind::Whitespace
220            | TokenKind::LineComment
221            | TokenKind::BlockComment
222            | TokenKind::Shebang
223            | TokenKind::Unknown
224    )
225}
226
227fn empty_range(at: Utf16Pos) -> TextRange {
228    TextRange::new(at, at).expect("an empty range is ordered")
229}
230
231fn is_line_terminator(c: char) -> bool {
232    matches!(c, '\n' | '\r' | '\u{2028}' | '\u{2029}')
233}
234
235fn is_id_continue(c: char) -> bool {
236    c == '$' || c == '_' || c == '\u{200C}' || c == '\u{200D}' || c.is_alphanumeric()
237}
238
239/// Returns whether a token may serve as an identifier reference or binding
240/// name. This covers the scanner's contextual keywords, which the grammar
241/// treats as ordinary identifiers outside their special positions, but not the
242/// hard reserved words.
243fn is_identifier_like(kind: TokenKind) -> bool {
244    matches!(
245        kind,
246        TokenKind::Identifier
247            | TokenKind::KwAbstract
248            | TokenKind::KwAccessor
249            | TokenKind::KwAny
250            | TokenKind::KwAs
251            | TokenKind::KwAsserts
252            | TokenKind::KwAsync
253            | TokenKind::KwAwait
254            | TokenKind::KwBigint
255            | TokenKind::KwBoolean
256            | TokenKind::KwConstructor
257            | TokenKind::KwDeclare
258            | TokenKind::KwFrom
259            | TokenKind::KwGet
260            | TokenKind::KwImplements
261            | TokenKind::KwInfer
262            | TokenKind::KwInterface
263            | TokenKind::KwIs
264            | TokenKind::KwKeyof
265            | TokenKind::KwLet
266            | TokenKind::KwNamespace
267            | TokenKind::KwNever
268            | TokenKind::KwNumber
269            | TokenKind::KwObject
270            | TokenKind::KwOf
271            | TokenKind::KwOverride
272            | TokenKind::KwPackage
273            | TokenKind::KwPrivate
274            | TokenKind::KwProtected
275            | TokenKind::KwPublic
276            | TokenKind::KwReadonly
277            | TokenKind::KwSatisfies
278            | TokenKind::KwSet
279            | TokenKind::KwStatic
280            | TokenKind::KwString
281            | TokenKind::KwSymbol
282            | TokenKind::KwType
283            | TokenKind::KwUndefined
284            | TokenKind::KwUnique
285            | TokenKind::KwUnknown
286            | TokenKind::KwYield
287    )
288}
289
290/// Returns whether a token can appear as a property name after `.`, in an
291/// object literal, or as a class member name. Every keyword qualifies.
292fn is_any_word(kind: TokenKind) -> bool {
293    is_identifier_like(kind)
294        || matches!(
295            kind,
296            TokenKind::KwBreak
297                | TokenKind::KwCase
298                | TokenKind::KwCatch
299                | TokenKind::KwClass
300                | TokenKind::KwConst
301                | TokenKind::KwContinue
302                | TokenKind::KwDebugger
303                | TokenKind::KwDefault
304                | TokenKind::KwDelete
305                | TokenKind::KwDo
306                | TokenKind::KwElse
307                | TokenKind::KwEnum
308                | TokenKind::KwExport
309                | TokenKind::KwExtends
310                | TokenKind::KwFalse
311                | TokenKind::KwFinally
312                | TokenKind::KwFor
313                | TokenKind::KwFunction
314                | TokenKind::KwIf
315                | TokenKind::KwImport
316                | TokenKind::KwIn
317                | TokenKind::KwInstanceof
318                | TokenKind::KwNew
319                | TokenKind::KwNull
320                | TokenKind::KwReturn
321                | TokenKind::KwSuper
322                | TokenKind::KwSwitch
323                | TokenKind::KwThis
324                | TokenKind::KwThrow
325                | TokenKind::KwTrue
326                | TokenKind::KwTry
327                | TokenKind::KwTypeof
328                | TokenKind::KwVar
329                | TokenKind::KwVoid
330                | TokenKind::KwWhile
331                | TokenKind::KwWith
332        )
333}
334
335impl Parser {
336    fn new(
337        source_id: SourceId,
338        script_kind: ScriptKind,
339        source: Arc<SourceText>,
340        tokens: Vec<Token>,
341        eof: Token,
342    ) -> Self {
343        let mut parser = Self {
344            source_id,
345            script_kind,
346            source,
347            tokens,
348            eof,
349            cursor: 0,
350            prev_end: 0,
351            diagnostics: Vec::new(),
352            next_node_id: 0,
353            journal: Vec::new(),
354            depth: 0,
355        };
356        parser.cursor = parser.next_significant(0);
357        parser
358    }
359
360    // ------------------------------------------------------------------
361    // Cursor primitives
362    // ------------------------------------------------------------------
363
364    fn next_significant(&self, mut index: usize) -> usize {
365        while index < self.tokens.len() && is_trivia(self.tokens[index].kind()) {
366            index += 1;
367        }
368        index
369    }
370
371    fn cur(&self) -> Token {
372        self.tokens.get(self.cursor).copied().unwrap_or(self.eof)
373    }
374
375    fn kind(&self) -> TokenKind {
376        self.cur().kind()
377    }
378
379    fn at(&self, kind: TokenKind) -> bool {
380        self.kind() == kind
381    }
382
383    fn at_eof(&self) -> bool {
384        self.cursor >= self.tokens.len()
385    }
386
387    /// Returns the `n`-th significant token after the current one.
388    fn nth(&self, n: usize) -> Token {
389        let mut index = self.cursor;
390        for _ in 0..n {
391            index = self.next_significant(index + 1);
392        }
393        self.tokens.get(index).copied().unwrap_or(self.eof)
394    }
395
396    fn nth_kind(&self, n: usize) -> TokenKind {
397        self.nth(n).kind()
398    }
399
400    fn bump(&mut self) -> Token {
401        let token = self.cur();
402        if self.cursor < self.tokens.len() {
403            self.prev_end = token.range().end().get();
404            self.cursor = self.next_significant(self.cursor + 1);
405        }
406        token
407    }
408
409    fn eat(&mut self, kind: TokenKind) -> Option<Token> {
410        if self.at(kind) {
411            Some(self.bump())
412        } else {
413            None
414        }
415    }
416
417    fn cur_start(&self) -> Utf16Pos {
418        self.cur().range().start()
419    }
420
421    /// The range from `start` to the end of the last consumed token. When no
422    /// token was consumed, the range is empty at `start`.
423    fn span_from(&self, start: Utf16Pos) -> TextRange {
424        let end = self.prev_end.max(start.get());
425        TextRange::new(start, Utf16Pos::new(end)).expect("spans grow forward")
426    }
427
428    fn fresh_id(&mut self) -> NodeId {
429        let id = NodeId::new(self.next_node_id);
430        self.next_node_id += 1;
431        id
432    }
433
434    fn node<T>(&mut self, start: Utf16Pos, data: T) -> Node<T> {
435        let range = self.span_from(start);
436        let id = self.fresh_id();
437        Node::new(id, range, data)
438    }
439
440    fn node_at<T>(&mut self, range: TextRange, data: T) -> Node<T> {
441        let id = self.fresh_id();
442        Node::new(id, range, data)
443    }
444
445    fn lexeme(&self, token: Token) -> &str {
446        if token.is_missing() {
447            return "";
448        }
449        let range = token.range();
450        let (Ok(start), Ok(end)) = (
451            self.source.utf16_to_byte(range.start()),
452            self.source.utf16_to_byte(range.end()),
453        ) else {
454            return "";
455        };
456        self.source.as_str().get(start..end).unwrap_or("")
457    }
458
459    fn cur_lexeme(&self) -> &str {
460        self.lexeme(self.cur())
461    }
462
463    /// Returns whether a line terminator sits between the previous consumed
464    /// significant token and the current one.
465    fn has_newline_before(&self) -> bool {
466        self.newline_in_gap(self.prev_end, self.cur_start().get())
467    }
468
469    /// Returns whether a line terminator sits between significant tokens `n-1`
470    /// and `n` ahead of the cursor.
471    fn has_newline_before_nth(&self, n: usize) -> bool {
472        let before = if n == 0 {
473            self.prev_end
474        } else {
475            self.nth(n - 1).range().end().get()
476        };
477        self.newline_in_gap(before, self.nth(n).range().start().get())
478    }
479
480    fn newline_in_gap(&self, from_utf16: usize, to_utf16: usize) -> bool {
481        if to_utf16 <= from_utf16 {
482            return false;
483        }
484        let (Ok(start), Ok(end)) = (
485            self.source.utf16_to_byte(Utf16Pos::new(from_utf16)),
486            self.source.utf16_to_byte(Utf16Pos::new(to_utf16)),
487        ) else {
488            return false;
489        };
490        self.source.as_str()[start..end]
491            .chars()
492            .any(is_line_terminator)
493    }
494
495    // ------------------------------------------------------------------
496    // Diagnostics and recovery products
497    // ------------------------------------------------------------------
498
499    fn error_at(&mut self, code: DiagnosticCode, range: TextRange, message: &'static str) {
500        self.diagnostics
501            .push(Diagnostic::error(code, self.source_id, range, message));
502    }
503
504    fn error_here(&mut self, code: DiagnosticCode, message: &'static str) {
505        let range = if self.at_eof() {
506            empty_range(self.eof.range().start())
507        } else {
508            self.cur().range()
509        };
510        self.error_at(code, range, message);
511    }
512
513    /// Consumes `kind` or records a diagnostic and returns a missing token
514    /// anchored at the current position.
515    fn expect(&mut self, kind: TokenKind, message: &'static str) -> Token {
516        if let Some(token) = self.eat(kind) {
517            return token;
518        }
519        self.error_here(EXPECTED_TOKEN, message);
520        Token::missing(kind, empty_range(self.cur_start()))
521    }
522
523    fn missing_token(&self, kind: TokenKind) -> Token {
524        Token::missing(kind, empty_range(self.cur_start()))
525    }
526
527    fn missing_expr(&mut self) -> Expr {
528        let start = self.cur_start();
529        self.node_at(
530            empty_range(start),
531            Expression::Missing(MissingNode::new(NodeKind::MissingExpression)),
532        )
533    }
534
535    fn missing_type(&mut self) -> Ty {
536        let start = self.cur_start();
537        self.node_at(
538            empty_range(start),
539            TypeNode::Missing(MissingNode::new(NodeKind::MissingType)),
540        )
541    }
542
543    fn missing_pattern(&mut self) -> Pattern {
544        let start = self.cur_start();
545        self.node_at(
546            empty_range(start),
547            BindingPattern::Missing(MissingNode::new(NodeKind::MissingBindingPattern)),
548        )
549    }
550
551    fn missing_statement(&mut self) -> Stmt {
552        let start = self.cur_start();
553        self.node_at(
554            empty_range(start),
555            Statement::Missing(MissingNode::new(NodeKind::MissingStatement)),
556        )
557    }
558
559    fn missing_ident(&mut self) -> IdentifierNode {
560        let token = self.missing_token(TokenKind::Identifier);
561        let range = token.range();
562        self.node_at(range, Identifier::new(token))
563    }
564
565    fn ident_from(&mut self, token: Token) -> IdentifierNode {
566        let range = token.range();
567        self.node_at(range, Identifier::new(token))
568    }
569
570    fn expect_identifier(&mut self, message: &'static str) -> IdentifierNode {
571        if is_identifier_like(self.kind()) {
572            let token = self.bump();
573            return self.ident_from(token);
574        }
575        self.error_here(EXPECTED_IDENTIFIER, message);
576        self.missing_ident()
577    }
578
579    /// Records a TypeScript-only construct when the script kind is JavaScript.
580    fn note_typescript_syntax(&mut self, range: TextRange) {
581        if matches!(
582            self.script_kind,
583            ScriptKind::JavaScript | ScriptKind::JavaScriptReact
584        ) {
585            self.error_at(
586                TYPESCRIPT_SYNTAX_IN_JAVASCRIPT,
587                range,
588                "TypeScript syntax is not allowed in a JavaScript source",
589            );
590        }
591    }
592
593    fn is_typescript(&self) -> bool {
594        matches!(
595            self.script_kind,
596            ScriptKind::TypeScript | ScriptKind::TypeScriptReact | ScriptKind::Json
597        )
598    }
599
600    // ------------------------------------------------------------------
601    // Depth guard
602    // ------------------------------------------------------------------
603
604    fn enter(&mut self) -> bool {
605        if self.depth >= MAX_DEPTH {
606            self.error_here(
607                NESTING_TOO_DEEP,
608                "this construct is nested too deeply to parse",
609            );
610            return false;
611        }
612        self.depth += 1;
613        true
614    }
615
616    fn leave(&mut self) {
617        self.depth -= 1;
618    }
619
620    // ------------------------------------------------------------------
621    // Speculation
622    // ------------------------------------------------------------------
623
624    fn checkpoint(&self) -> ParserCheckpoint {
625        ParserCheckpoint {
626            cursor: self.cursor,
627            prev_end: self.prev_end,
628            diagnostics: self.diagnostics.len(),
629            next_node_id: self.next_node_id,
630            journal: self.journal.len(),
631        }
632    }
633
634    fn rollback(&mut self, checkpoint: ParserCheckpoint) {
635        while self.journal.len() > checkpoint.journal {
636            let edit = self.journal.pop().expect("journal length checked");
637            let end = edit.index + edit.inserted;
638            self.tokens.splice(edit.index..end, edit.removed);
639        }
640        self.cursor = checkpoint.cursor;
641        self.prev_end = checkpoint.prev_end;
642        self.diagnostics.truncate(checkpoint.diagnostics);
643        self.next_node_id = checkpoint.next_node_id;
644    }
645
646    // ------------------------------------------------------------------
647    // Token-cursor rescans
648    // ------------------------------------------------------------------
649
650    /// Replaces `tokens[index..=last]` with `replacement`, journaling the edit.
651    fn replace_tokens(&mut self, index: usize, last: usize, replacement: Vec<Token>) {
652        let inserted = replacement.len();
653        let removed: Vec<Token> = self.tokens.splice(index..=last, replacement).collect();
654        self.journal.push(RescanEdit {
655            index,
656            removed,
657            inserted,
658        });
659    }
660
661    /// Reinterprets the current `/`/`/=` token as a regular-expression
662    /// literal, merging the covered tokens. Grammar context (expression start)
663    /// is the caller's assertion; the re-lex itself mirrors the scanner rules.
664    fn rescan_regex_here(&mut self) {
665        if !matches!(self.kind(), TokenKind::Slash | TokenKind::SlashEq) || self.at_eof() {
666            return;
667        }
668        let index = self.cursor;
669        let start = self.tokens[index].range().start();
670        let Ok(start_byte) = self.source.utf16_to_byte(start) else {
671            return;
672        };
673        let text = &self.source.as_str()[start_byte..];
674
675        // Mirror of `Scanner::scan_regex`: body with classes and escapes, then
676        // identifier-continue flags. Unterminated forms end at the offending
677        // position without consuming the terminator.
678        let mut chars = text.chars();
679        let mut consumed = 0usize;
680        let take = |chars: &mut std::str::Chars<'_>, consumed: &mut usize| -> Option<char> {
681            let c = chars.next()?;
682            *consumed += c.len_utf16();
683            Some(c)
684        };
685        let _slash = take(&mut chars, &mut consumed);
686        let mut in_class = false;
687        let mut terminated = false;
688        loop {
689            let mut peek = chars.clone();
690            match peek.next() {
691                None => break,
692                Some(c) if is_line_terminator(c) => break,
693                Some('\\') => {
694                    take(&mut chars, &mut consumed);
695                    let mut after = chars.clone();
696                    match after.next() {
697                        None => {}
698                        Some(c) if is_line_terminator(c) => break,
699                        Some(_) => {
700                            take(&mut chars, &mut consumed);
701                        }
702                    }
703                }
704                Some('[') => {
705                    in_class = true;
706                    take(&mut chars, &mut consumed);
707                }
708                Some(']') => {
709                    in_class = false;
710                    take(&mut chars, &mut consumed);
711                }
712                Some('/') if !in_class => {
713                    take(&mut chars, &mut consumed);
714                    terminated = true;
715                    break;
716                }
717                Some(_) => {
718                    take(&mut chars, &mut consumed);
719                }
720            }
721        }
722        if terminated {
723            loop {
724                let mut peek = chars.clone();
725                match peek.next() {
726                    Some(c) if is_id_continue(c) => {
727                        take(&mut chars, &mut consumed);
728                    }
729                    _ => break,
730                }
731            }
732        }
733        let mut end = start.get() + consumed;
734        if !terminated {
735            self.error_at(
736                UNTERMINATED_REGEX,
737                TextRange::new(start, Utf16Pos::new(end)).expect("regex spans grow forward"),
738                "unterminated regular expression literal",
739            );
740        }
741
742        // Absorb the pre-scanned tokens the literal covers. The default pass
743        // can form a token that straddles the grammar-correct regex end: for
744        // `/...\/.../` its two adjacent slashes look like a line comment.
745        // Never widen the regex to that token's end. Re-scan only the trailing
746        // fragment and append its shifted tokens so the final stream remains
747        // byte-exact and the parser still sees the code after the literal.
748        let mut last = index;
749        while last + 1 < self.tokens.len() && self.tokens[last].range().end().get() < end {
750            last += 1;
751        }
752        let covered_end = self.tokens[last].range().end().get();
753        if covered_end < end {
754            end = covered_end;
755        }
756        let range = TextRange::new(start, Utf16Pos::new(end)).expect("regex spans grow forward");
757        let mut replacement = vec![Token::new(TokenKind::RegularExpressionLiteral, range)];
758        if covered_end > end {
759            replacement.extend(self.scan_shifted_fragment(end, covered_end));
760        }
761        self.replace_tokens(index, last, replacement);
762    }
763
764    /// Scans `[start, end)` as an isolated fragment and shifts every produced
765    /// token and diagnostic back into the owning source's UTF-16 coordinates.
766    /// This is used only for a base token's tail after a committed regex
767    /// rescan; ordinary parser lexing always reuses the scanner's full stream.
768    fn scan_shifted_fragment(&mut self, start: usize, end: usize) -> Vec<Token> {
769        let (Ok(start_byte), Ok(end_byte)) = (
770            self.source.utf16_to_byte(Utf16Pos::new(start)),
771            self.source.utf16_to_byte(Utf16Pos::new(end)),
772        ) else {
773            return Vec::new();
774        };
775        let fragment = Arc::new(SourceText::new(
776            self.source.as_str()[start_byte..end_byte].to_owned(),
777        ));
778        let recovered = crate::scanner::scan(self.source_id, self.script_kind, fragment);
779        let (scanned, diagnostics) = recovered.into_parts();
780        for diagnostic in diagnostics {
781            let range = diagnostic.range();
782            let shifted = TextRange::new(
783                Utf16Pos::new(start + range.start().get()),
784                Utf16Pos::new(start + range.end().get()),
785            )
786            .expect("shift preserves range ordering");
787            self.diagnostics.push(Diagnostic::new(
788                diagnostic.severity(),
789                diagnostic.code(),
790                diagnostic.source_id(),
791                shifted,
792                diagnostic.message(),
793            ));
794        }
795        scanned
796            .tokens()
797            .iter()
798            .map(|token| {
799                let range = token.range();
800                Token::new(
801                    token.kind(),
802                    TextRange::new(
803                        Utf16Pos::new(start + range.start().get()),
804                        Utf16Pos::new(start + range.end().get()),
805                    )
806                    .expect("shift preserves token ordering"),
807                )
808            })
809            .collect()
810    }
811
812    /// Returns whether the current token begins with `>` so a type or heritage
813    /// close can split it.
814    fn at_greater_like(&self) -> bool {
815        matches!(
816            self.kind(),
817            TokenKind::GreaterThan
818                | TokenKind::GreaterGreater
819                | TokenKind::GreaterGreaterGreater
820                | TokenKind::GreaterThanEq
821                | TokenKind::GreaterGreaterEq
822                | TokenKind::GreaterGreaterGreaterEq
823        )
824    }
825
826    /// Consumes exactly one `>`, splitting a greedily formed operator when
827    /// needed. Mirrors `Scanner::rescan_greater_than` at the token level.
828    fn expect_type_close(&mut self, message: &'static str) -> Token {
829        if self.at(TokenKind::GreaterThan) {
830            return self.bump();
831        }
832        let remainder = match self.kind() {
833            TokenKind::GreaterGreater => Some(TokenKind::GreaterThan),
834            TokenKind::GreaterGreaterGreater => Some(TokenKind::GreaterGreater),
835            TokenKind::GreaterThanEq => Some(TokenKind::Eq),
836            TokenKind::GreaterGreaterEq => Some(TokenKind::GreaterThanEq),
837            TokenKind::GreaterGreaterGreaterEq => Some(TokenKind::GreaterGreaterEq),
838            _ => None,
839        };
840        let Some(remainder) = remainder else {
841            self.error_here(EXPECTED_TOKEN, message);
842            return Token::missing(TokenKind::GreaterThan, empty_range(self.cur_start()));
843        };
844        let index = self.cursor;
845        let range = self.tokens[index].range();
846        let split = Utf16Pos::new(range.start().get() + 1);
847        let head = Token::new(
848            TokenKind::GreaterThan,
849            TextRange::new(range.start(), split).expect("split point is inside the token"),
850        );
851        let tail = Token::new(
852            remainder,
853            TextRange::new(split, range.end()).expect("split point is inside the token"),
854        );
855        self.replace_tokens(index, index, vec![head, tail]);
856        self.bump()
857    }
858
859    /// Returns whether the current token begins with `<` so a type context can
860    /// open on it.
861    fn at_less_like(&self) -> bool {
862        matches!(
863            self.kind(),
864            TokenKind::LessThan | TokenKind::LessLess | TokenKind::LessLessEq
865        )
866    }
867
868    /// Consumes exactly one `<`, splitting `<<`/`<<=` when a type context
869    /// opens inside a greedily formed operator.
870    fn expect_type_open(&mut self, message: &'static str) -> Token {
871        if self.at(TokenKind::LessThan) {
872            return self.bump();
873        }
874        let remainder = match self.kind() {
875            TokenKind::LessLess => Some(TokenKind::LessThan),
876            TokenKind::LessLessEq => Some(TokenKind::LessThanEq),
877            _ => None,
878        };
879        let Some(remainder) = remainder else {
880            self.error_here(EXPECTED_TOKEN, message);
881            return Token::missing(TokenKind::LessThan, empty_range(self.cur_start()));
882        };
883        let index = self.cursor;
884        let range = self.tokens[index].range();
885        let split = Utf16Pos::new(range.start().get() + 1);
886        let head = Token::new(
887            TokenKind::LessThan,
888            TextRange::new(range.start(), split).expect("split point is inside the token"),
889        );
890        let tail = Token::new(
891            remainder,
892            TextRange::new(split, range.end()).expect("split point is inside the token"),
893        );
894        self.replace_tokens(index, index, vec![head, tail]);
895        self.bump()
896    }
897
898    // ------------------------------------------------------------------
899    // Automatic semicolon insertion
900    // ------------------------------------------------------------------
901
902    /// Consumes a statement terminator: an explicit `;`, or an automatic
903    /// semicolon before `}`, at end of file, or after a line terminator.
904    fn expect_semicolon(&mut self) {
905        if self.eat(TokenKind::Semicolon).is_some() {
906            return;
907        }
908        if self.at(TokenKind::RBrace) || self.at_eof() || self.has_newline_before() {
909            return;
910        }
911        self.error_here(EXPECTED_TOKEN, "expected `;`");
912    }
913}
914
915// ---------------------------------------------------------------------------
916// Statements and declarations
917// ---------------------------------------------------------------------------
918
919impl Parser {
920    /// Parses statements until one of `stop` (or end of file), with a forward
921    /// progress guard: an iteration that consumes nothing skips one token.
922    fn parse_statements_until(&mut self, stop: &[TokenKind]) -> Vec<Stmt> {
923        let mut statements = Vec::new();
924        while !self.at_eof() && !stop.contains(&self.kind()) {
925            let before = self.cursor;
926            let statement = self.parse_statement();
927            statements.push(statement);
928            if self.cursor == before {
929                let skipped = self.bump();
930                self.error_at(
931                    UNEXPECTED_TOKEN,
932                    skipped.range(),
933                    "this token was skipped during recovery",
934                );
935            }
936        }
937        statements
938    }
939
940    fn parse_statement(&mut self) -> Stmt {
941        if !self.enter() {
942            let skipped = self.bump();
943            let statement = self.missing_statement();
944            let _ = skipped;
945            return statement;
946        }
947        let statement = self.parse_statement_inner();
948        self.leave();
949        statement
950    }
951
952    fn parse_statement_inner(&mut self) -> Stmt {
953        let start = self.cur_start();
954        match self.kind() {
955            TokenKind::Semicolon => {
956                self.bump();
957                self.node(start, Statement::Empty)
958            }
959            TokenKind::LBrace => {
960                let block = self.parse_block();
961                self.node(start, Statement::Block(block))
962            }
963            TokenKind::KwConst if self.nth_kind(1) == TokenKind::KwEnum => {
964                self.bump();
965                self.parse_enum_declaration(start, true)
966            }
967            TokenKind::KwVar | TokenKind::KwLet | TokenKind::KwConst
968                if self.at_variable_declaration() =>
969            {
970                self.parse_variable_statement(start)
971            }
972            TokenKind::Identifier
973                if self.cur_lexeme() == "using" && self.at_using_declaration(0) =>
974            {
975                self.parse_variable_statement(start)
976            }
977            TokenKind::KwAwait
978                if self.nth(1).kind() == TokenKind::Identifier
979                    && self.lexeme(self.nth(1)) == "using"
980                    && self.at_using_declaration(1) =>
981            {
982                self.parse_variable_statement(start)
983            }
984            TokenKind::KwFunction => {
985                let function = self.parse_function_like(Vec::new(), false, true);
986                self.node(start, Statement::Function(FunctionDeclaration { function }))
987            }
988            TokenKind::KwAsync
989                if self.nth_kind(1) == TokenKind::KwFunction && !self.has_newline_before_nth(1) =>
990            {
991                self.bump();
992                let function = self.parse_function_like(Vec::new(), true, true);
993                self.node(start, Statement::Function(FunctionDeclaration { function }))
994            }
995            TokenKind::KwClass => {
996                let class = self.parse_class(Vec::new(), DeclarationModifiers::default(), true);
997                self.node(start, Statement::Class(class))
998            }
999            TokenKind::At => self.parse_decorated_statement(start),
1000            TokenKind::KwAbstract if self.nth_kind(1) == TokenKind::KwClass => {
1001                let range = self.cur().range();
1002                self.note_typescript_syntax(range);
1003                self.bump();
1004                let modifiers = DeclarationModifiers {
1005                    is_abstract: true,
1006                    ..DeclarationModifiers::default()
1007                };
1008                let class = self.parse_class(Vec::new(), modifiers, true);
1009                self.node(start, Statement::Class(class))
1010            }
1011            TokenKind::KwIf => self.parse_if_statement(start),
1012            TokenKind::KwSwitch => self.parse_switch_statement(start),
1013            TokenKind::KwFor => self.parse_for_statement(start),
1014            TokenKind::KwWhile => self.parse_while_statement(start),
1015            TokenKind::KwDo => self.parse_do_while_statement(start),
1016            TokenKind::KwTry => self.parse_try_statement(start),
1017            TokenKind::KwWith => self.parse_with_statement(start),
1018            TokenKind::KwReturn => self.parse_return_statement(start),
1019            TokenKind::KwThrow => self.parse_throw_statement(start),
1020            TokenKind::KwBreak => self.parse_jump_statement(start, true),
1021            TokenKind::KwContinue => self.parse_jump_statement(start, false),
1022            TokenKind::KwDebugger => {
1023                self.bump();
1024                self.expect_semicolon();
1025                self.node(start, Statement::Debugger)
1026            }
1027            TokenKind::KwImport
1028                if !matches!(self.nth_kind(1), TokenKind::LParen | TokenKind::Dot) =>
1029            {
1030                self.parse_import_statement(start)
1031            }
1032            TokenKind::KwExport => self.parse_export_statement(start),
1033            TokenKind::KwInterface if is_identifier_like(self.nth_kind(1)) => {
1034                self.parse_interface_declaration(start)
1035            }
1036            TokenKind::KwType
1037                if is_identifier_like(self.nth_kind(1))
1038                    && matches!(self.nth_kind(2), TokenKind::Eq | TokenKind::LessThan)
1039                    && !self.has_newline_before_nth(1) =>
1040            {
1041                self.parse_type_alias_declaration(start)
1042            }
1043            TokenKind::KwEnum if is_identifier_like(self.nth_kind(1)) => {
1044                self.parse_enum_declaration(start, false)
1045            }
1046            TokenKind::KwNamespace
1047                if is_identifier_like(self.nth_kind(1))
1048                    && matches!(self.nth_kind(2), TokenKind::LBrace | TokenKind::Dot) =>
1049            {
1050                self.parse_namespace_declaration(start)
1051            }
1052            TokenKind::KwDeclare if self.at_declare_statement() => {
1053                let range = self.cur().range();
1054                self.note_typescript_syntax(range);
1055                self.bump();
1056                let inner = self.parse_statement();
1057                self.node(start, Statement::Declare(Box::new(inner)))
1058            }
1059            TokenKind::Identifier
1060                if matches!(self.cur_lexeme(), "global" | "module")
1061                    && matches!(
1062                        self.nth_kind(1),
1063                        TokenKind::LBrace | TokenKind::StringLiteral
1064                    ) =>
1065            {
1066                self.parse_contextual_namespace(start)
1067            }
1068            kind if is_identifier_like(kind)
1069                && self.nth_kind(1) == TokenKind::Colon
1070                && !matches!(kind, TokenKind::KwDefault) =>
1071            {
1072                let label_token = self.bump();
1073                let label = self.ident_from(label_token);
1074                self.bump();
1075                let body = self.parse_statement();
1076                self.node(
1077                    start,
1078                    Statement::Labeled(LabeledStatement {
1079                        label,
1080                        body: Box::new(body),
1081                    }),
1082                )
1083            }
1084            _ => self.parse_expression_statement(start),
1085        }
1086    }
1087
1088    /// `var` and `const` are reserved and always begin a declaration; `let` is
1089    /// contextual, so it starts one only when a binding follows and is
1090    /// otherwise an ordinary identifier.
1091    fn at_variable_declaration(&self) -> bool {
1092        if self.at(TokenKind::KwVar) || self.at(TokenKind::KwConst) {
1093            return true;
1094        }
1095        let next = self.nth_kind(1);
1096        is_identifier_like(next) || matches!(next, TokenKind::LBracket | TokenKind::LBrace)
1097    }
1098
1099    /// A `using` declaration requires an identifier binding on the same line.
1100    /// The binding may carry a TypeScript type annotation, so a `:` is accepted
1101    /// only when a top-level `=` initializer follows the annotation. Because an
1102    /// ordinary expression never starts with two adjacent identifiers, this
1103    /// never steals a non-declaration.
1104    fn at_using_declaration(&self, offset: usize) -> bool {
1105        if !is_identifier_like(self.nth_kind(offset + 1)) || self.has_newline_before_nth(offset + 1)
1106        {
1107            return false;
1108        }
1109        match self.nth_kind(offset + 2) {
1110            TokenKind::Eq | TokenKind::Semicolon | TokenKind::KwOf => true,
1111            TokenKind::Colon => self.type_annotation_precedes_eq(offset + 2),
1112            _ => false,
1113        }
1114    }
1115
1116    /// Scans from the annotation colon at significant offset `colon_offset` and
1117    /// reports whether a top-level `=` (the declaration initializer) follows the
1118    /// type. Parenthesis, array, and object brackets are balanced so a `;` or
1119    /// `=` inside the type (an object-type member separator, a construct-
1120    /// signature default) does not end the scan early; type-argument `<>` is not
1121    /// tracked, which is safe because `using IDENT :` is never an ordinary
1122    /// expression, so any top-level `=` still means a declaration. A single
1123    /// linear pass over raw token indices keeps this from becoming quadratic on
1124    /// hostile input.
1125    fn type_annotation_precedes_eq(&self, colon_offset: usize) -> bool {
1126        let mut index = self.cursor;
1127        for _ in 0..colon_offset {
1128            index = self.next_significant(index + 1);
1129        }
1130        let mut depth = 0i32;
1131        loop {
1132            index = self.next_significant(index + 1);
1133            match self.tokens.get(index).copied().unwrap_or(self.eof).kind() {
1134                TokenKind::LParen | TokenKind::LBracket | TokenKind::LBrace => depth += 1,
1135                TokenKind::RParen | TokenKind::RBracket | TokenKind::RBrace => {
1136                    depth -= 1;
1137                    if depth < 0 {
1138                        return false;
1139                    }
1140                }
1141                TokenKind::Eq if depth == 0 => return true,
1142                TokenKind::Semicolon if depth == 0 => return false,
1143                TokenKind::EndOfFile => return false,
1144                _ => {}
1145            }
1146        }
1147    }
1148
1149    /// `declare` prefixes a following declaration only when one can start.
1150    fn at_declare_statement(&self) -> bool {
1151        if self.has_newline_before_nth(1) {
1152            return false;
1153        }
1154        if self.nth_kind(1) == TokenKind::Identifier
1155            && matches!(self.lexeme(self.nth(1)), "global" | "module")
1156        {
1157            return true;
1158        }
1159        matches!(
1160            self.nth_kind(1),
1161            TokenKind::KwVar
1162                | TokenKind::KwLet
1163                | TokenKind::KwConst
1164                | TokenKind::KwFunction
1165                | TokenKind::KwClass
1166                | TokenKind::KwAbstract
1167                | TokenKind::KwInterface
1168                | TokenKind::KwType
1169                | TokenKind::KwEnum
1170                | TokenKind::KwNamespace
1171                | TokenKind::KwAsync
1172        )
1173    }
1174
1175    fn parse_block(&mut self) -> BlockNode {
1176        let start = self.cur_start();
1177        self.expect(TokenKind::LBrace, "expected `{`");
1178        let statements = self.parse_statements_until(&[TokenKind::RBrace]);
1179        self.expect(TokenKind::RBrace, "expected `}`");
1180        self.node(start, Block { statements })
1181    }
1182
1183    fn parse_variable_statement(&mut self, start: Utf16Pos) -> Stmt {
1184        let declaration = self.parse_variable_declaration(true);
1185        self.expect_semicolon();
1186        self.node(start, Statement::Variable(declaration))
1187    }
1188
1189    fn variable_kind(&mut self) -> VariableKind {
1190        match self.kind() {
1191            TokenKind::KwVar => {
1192                self.bump();
1193                VariableKind::Var
1194            }
1195            TokenKind::KwLet => {
1196                self.bump();
1197                VariableKind::Let
1198            }
1199            TokenKind::KwConst => {
1200                self.bump();
1201                VariableKind::Const
1202            }
1203            TokenKind::KwAwait => {
1204                self.bump();
1205                // The caller verified `using` follows.
1206                self.bump();
1207                VariableKind::AwaitUsing
1208            }
1209            _ => {
1210                // `using` as a plain identifier token.
1211                self.bump();
1212                VariableKind::Using
1213            }
1214        }
1215    }
1216
1217    /// Parses a `var`/`let`/`const`/`using` declaration. `allow_in` is false
1218    /// inside a `for (...)` head before the `in`/`of` decision.
1219    fn parse_variable_declaration(&mut self, allow_in: bool) -> VariableDeclaration {
1220        let kind = self.variable_kind();
1221        let mut declarations = Vec::new();
1222        loop {
1223            let declarator = self.parse_variable_declarator(allow_in);
1224            declarations.push(declarator);
1225            if self.eat(TokenKind::Comma).is_none() {
1226                break;
1227            }
1228        }
1229        VariableDeclaration { kind, declarations }
1230    }
1231
1232    fn parse_variable_declarator(&mut self, allow_in: bool) -> VariableDeclaratorNode {
1233        let start = self.cur_start();
1234        let binding = self.parse_binding_pattern();
1235        let mut definite = false;
1236        if self.at(TokenKind::Bang) && !self.has_newline_before() {
1237            let range = self.cur().range();
1238            self.note_typescript_syntax(range);
1239            self.bump();
1240            definite = true;
1241        }
1242        let type_annotation = self.parse_optional_type_annotation();
1243        let initializer = if self.eat(TokenKind::Eq).is_some() {
1244            Some(Box::new(self.parse_assignment_expression(!allow_in)))
1245        } else {
1246            None
1247        };
1248        self.node(
1249            start,
1250            VariableDeclarator {
1251                binding,
1252                definite,
1253                type_annotation,
1254                initializer,
1255            },
1256        )
1257    }
1258
1259    fn parse_optional_type_annotation(&mut self) -> Option<TypeAnnotationNode> {
1260        if !self.at(TokenKind::Colon) {
1261            return None;
1262        }
1263        let start = self.cur_start();
1264        let colon_range = self.cur().range();
1265        self.note_typescript_syntax(colon_range);
1266        self.bump();
1267        let type_node = self.parse_type();
1268        Some(self.node(
1269            start,
1270            TypeAnnotation {
1271                type_node: Box::new(type_node),
1272            },
1273        ))
1274    }
1275
1276    fn parse_expression_statement(&mut self, start: Utf16Pos) -> Stmt {
1277        let before = self.cursor;
1278        let expression = self.parse_expression(false);
1279        if self.cursor == before {
1280            // Nothing could begin an expression: skip one token for progress.
1281            let skipped = self.bump();
1282            self.error_at(
1283                UNEXPECTED_TOKEN,
1284                skipped.range(),
1285                "this token cannot begin a statement",
1286            );
1287            return self.missing_statement();
1288        }
1289        self.expect_semicolon();
1290        self.node(
1291            start,
1292            Statement::Expression(ExpressionStatement {
1293                expression: Box::new(expression),
1294            }),
1295        )
1296    }
1297
1298    fn parse_if_statement(&mut self, start: Utf16Pos) -> Stmt {
1299        self.bump();
1300        self.expect(TokenKind::LParen, "expected `(`");
1301        let test = self.parse_expression(false);
1302        self.expect(TokenKind::RParen, "expected `)`");
1303        let consequent = self.parse_statement();
1304        let alternate = if self.eat(TokenKind::KwElse).is_some() {
1305            Some(Box::new(self.parse_statement()))
1306        } else {
1307            None
1308        };
1309        self.node(
1310            start,
1311            Statement::If(IfStatement {
1312                test: Box::new(test),
1313                consequent: Box::new(consequent),
1314                alternate,
1315            }),
1316        )
1317    }
1318
1319    fn parse_switch_statement(&mut self, start: Utf16Pos) -> Stmt {
1320        self.bump();
1321        self.expect(TokenKind::LParen, "expected `(`");
1322        let discriminant = self.parse_expression(false);
1323        self.expect(TokenKind::RParen, "expected `)`");
1324        self.expect(TokenKind::LBrace, "expected `{`");
1325        let mut cases = Vec::new();
1326        while !self.at_eof() && !self.at(TokenKind::RBrace) {
1327            let case_start = self.cur_start();
1328            let test = if self.eat(TokenKind::KwCase).is_some() {
1329                Some(Box::new(self.parse_expression(false)))
1330            } else if self.eat(TokenKind::KwDefault).is_some() {
1331                None
1332            } else {
1333                let skipped = self.bump();
1334                self.error_at(
1335                    UNEXPECTED_TOKEN,
1336                    skipped.range(),
1337                    "expected `case` or `default`",
1338                );
1339                continue;
1340            };
1341            self.expect(TokenKind::Colon, "expected `:`");
1342            let consequent = self.parse_statements_until(&[
1343                TokenKind::KwCase,
1344                TokenKind::KwDefault,
1345                TokenKind::RBrace,
1346            ]);
1347            let case: SwitchCaseNode = self.node(case_start, SwitchCase { test, consequent });
1348            cases.push(case);
1349        }
1350        self.expect(TokenKind::RBrace, "expected `}`");
1351        self.node(
1352            start,
1353            Statement::Switch(SwitchStatement {
1354                discriminant: Box::new(discriminant),
1355                cases,
1356            }),
1357        )
1358    }
1359
1360    fn parse_for_statement(&mut self, start: Utf16Pos) -> Stmt {
1361        self.bump();
1362        let is_await = self.eat(TokenKind::KwAwait).is_some();
1363        self.expect(TokenKind::LParen, "expected `(`");
1364
1365        // Empty initializer.
1366        if self.eat(TokenKind::Semicolon).is_some() {
1367            return self.finish_classic_for(start, None);
1368        }
1369
1370        let decl_start = matches!(
1371            self.kind(),
1372            TokenKind::KwVar | TokenKind::KwLet | TokenKind::KwConst
1373        ) && self.at_variable_declaration()
1374            || (self.at(TokenKind::Identifier)
1375                && self.cur_lexeme() == "using"
1376                && is_identifier_like(self.nth_kind(1)))
1377            || (self.at(TokenKind::KwAwait)
1378                && self.nth(1).kind() == TokenKind::Identifier
1379                && self.lexeme(self.nth(1)) == "using");
1380
1381        if decl_start {
1382            let kind = self.variable_kind();
1383            let first = self.parse_for_head_declarator();
1384            match self.kind() {
1385                TokenKind::KwIn => {
1386                    self.bump();
1387                    let object = self.parse_expression(false);
1388                    let body = self.finish_for_body();
1389                    let binding = ForBinding::Variable(VariableDeclaration {
1390                        kind,
1391                        declarations: vec![first],
1392                    });
1393                    return self.node(
1394                        start,
1395                        Statement::ForIn(ForInStatement {
1396                            binding,
1397                            object: Box::new(object),
1398                            body: Box::new(body),
1399                        }),
1400                    );
1401                }
1402                TokenKind::KwOf => {
1403                    self.bump();
1404                    let iterable = self.parse_assignment_expression(false);
1405                    let body = self.finish_for_body();
1406                    let binding = ForBinding::Variable(VariableDeclaration {
1407                        kind,
1408                        declarations: vec![first],
1409                    });
1410                    let mode = if is_await {
1411                        ForOfMode::Async
1412                    } else {
1413                        ForOfMode::Sync
1414                    };
1415                    return self.node(
1416                        start,
1417                        Statement::ForOf(ForOfStatement {
1418                            mode,
1419                            binding,
1420                            iterable: Box::new(iterable),
1421                            body: Box::new(body),
1422                        }),
1423                    );
1424                }
1425                _ => {
1426                    // Classic head: finish this declarator's initializer and
1427                    // any further declarators.
1428                    let mut declarations = vec![self.finish_for_declarator(first)];
1429                    while self.eat(TokenKind::Comma).is_some() {
1430                        declarations.push(self.parse_variable_declarator(false));
1431                    }
1432                    self.expect(TokenKind::Semicolon, "expected `;`");
1433                    let initializer = Some(ForInitializer::Variable(VariableDeclaration {
1434                        kind,
1435                        declarations,
1436                    }));
1437                    return self.finish_classic_for(start, initializer);
1438                }
1439            }
1440        }
1441
1442        // Expression head.
1443        let expression = self.parse_expression(true);
1444        match self.kind() {
1445            TokenKind::KwIn => {
1446                self.bump();
1447                let target = self.expression_to_target(expression);
1448                let object = self.parse_expression(false);
1449                let body = self.finish_for_body();
1450                self.node(
1451                    start,
1452                    Statement::ForIn(ForInStatement {
1453                        binding: ForBinding::Target(target),
1454                        object: Box::new(object),
1455                        body: Box::new(body),
1456                    }),
1457                )
1458            }
1459            TokenKind::KwOf => {
1460                self.bump();
1461                let target = self.expression_to_target(expression);
1462                let iterable = self.parse_assignment_expression(false);
1463                let body = self.finish_for_body();
1464                let mode = if is_await {
1465                    ForOfMode::Async
1466                } else {
1467                    ForOfMode::Sync
1468                };
1469                self.node(
1470                    start,
1471                    Statement::ForOf(ForOfStatement {
1472                        mode,
1473                        binding: ForBinding::Target(target),
1474                        iterable: Box::new(iterable),
1475                        body: Box::new(body),
1476                    }),
1477                )
1478            }
1479            _ => {
1480                self.expect(TokenKind::Semicolon, "expected `;`");
1481                self.finish_classic_for(
1482                    start,
1483                    Some(ForInitializer::Expression(Box::new(expression))),
1484                )
1485            }
1486        }
1487    }
1488
1489    /// Parses a for-head declarator up to (but excluding) any initializer, so
1490    /// the caller can decide between `in`/`of` and a classic head.
1491    fn parse_for_head_declarator(&mut self) -> VariableDeclaratorNode {
1492        let start = self.cur_start();
1493        let binding = self.parse_binding_pattern();
1494        let type_annotation = self.parse_optional_type_annotation();
1495        self.node(
1496            start,
1497            VariableDeclarator {
1498                binding,
1499                definite: false,
1500                type_annotation,
1501                initializer: None,
1502            },
1503        )
1504    }
1505
1506    /// Attaches an `=` initializer to a for-head declarator in a classic head.
1507    fn finish_for_declarator(
1508        &mut self,
1509        declarator: VariableDeclaratorNode,
1510    ) -> VariableDeclaratorNode {
1511        if !self.at(TokenKind::Eq) {
1512            return declarator;
1513        }
1514        self.bump();
1515        let initializer = self.parse_assignment_expression(true);
1516        let start = declarator.range().start();
1517        let id = declarator.id();
1518        let mut data = declarator.into_data();
1519        data.initializer = Some(Box::new(initializer));
1520        Node::new(id, self.span_from(start), data)
1521    }
1522
1523    fn finish_classic_for(&mut self, start: Utf16Pos, initializer: Option<ForInitializer>) -> Stmt {
1524        let test = if self.at(TokenKind::Semicolon) {
1525            None
1526        } else {
1527            Some(Box::new(self.parse_expression(false)))
1528        };
1529        self.expect(TokenKind::Semicolon, "expected `;`");
1530        let update = if self.at(TokenKind::RParen) {
1531            None
1532        } else {
1533            Some(Box::new(self.parse_expression(false)))
1534        };
1535        let body = self.finish_for_body();
1536        self.node(
1537            start,
1538            Statement::For(ForStatement {
1539                initializer,
1540                test,
1541                update,
1542                body: Box::new(body),
1543            }),
1544        )
1545    }
1546
1547    fn finish_for_body(&mut self) -> Stmt {
1548        self.expect(TokenKind::RParen, "expected `)`");
1549        self.parse_statement()
1550    }
1551
1552    fn parse_while_statement(&mut self, start: Utf16Pos) -> Stmt {
1553        self.bump();
1554        self.expect(TokenKind::LParen, "expected `(`");
1555        let test = self.parse_expression(false);
1556        self.expect(TokenKind::RParen, "expected `)`");
1557        let body = self.parse_statement();
1558        self.node(
1559            start,
1560            Statement::While(WhileStatement {
1561                test: Box::new(test),
1562                body: Box::new(body),
1563            }),
1564        )
1565    }
1566
1567    fn parse_do_while_statement(&mut self, start: Utf16Pos) -> Stmt {
1568        self.bump();
1569        let body = self.parse_statement();
1570        self.expect(TokenKind::KwWhile, "expected `while`");
1571        self.expect(TokenKind::LParen, "expected `(`");
1572        let test = self.parse_expression(false);
1573        self.expect(TokenKind::RParen, "expected `)`");
1574        let _ = self.eat(TokenKind::Semicolon);
1575        self.node(
1576            start,
1577            Statement::DoWhile(DoWhileStatement {
1578                body: Box::new(body),
1579                test: Box::new(test),
1580            }),
1581        )
1582    }
1583
1584    fn parse_try_statement(&mut self, start: Utf16Pos) -> Stmt {
1585        self.bump();
1586        let block = self.parse_block();
1587        let handler = if self.at(TokenKind::KwCatch) {
1588            let catch_start = self.cur_start();
1589            self.bump();
1590            let binding = if self.eat(TokenKind::LParen).is_some() {
1591                let pattern = self.parse_binding_pattern();
1592                // A catch-parameter annotation is type-only syntax the fixed
1593                // catch clause cannot retain; it is parsed and erased here.
1594                let _ = self.parse_optional_type_annotation();
1595                self.expect(TokenKind::RParen, "expected `)`");
1596                Some(pattern)
1597            } else {
1598                None
1599            };
1600            let body = self.parse_block();
1601            let clause: CatchClauseNode = self.node(catch_start, CatchClause { binding, body });
1602            Some(clause)
1603        } else {
1604            None
1605        };
1606        let finalizer = if self.eat(TokenKind::KwFinally).is_some() {
1607            Some(self.parse_block())
1608        } else {
1609            None
1610        };
1611        if handler.is_none() && finalizer.is_none() {
1612            self.error_here(EXPECTED_TOKEN, "expected `catch` or `finally`");
1613        }
1614        self.node(
1615            start,
1616            Statement::Try(TryStatement {
1617                block,
1618                handler,
1619                finalizer,
1620            }),
1621        )
1622    }
1623
1624    fn parse_with_statement(&mut self, start: Utf16Pos) -> Stmt {
1625        self.bump();
1626        self.expect(TokenKind::LParen, "expected `(`");
1627        let object = self.parse_expression(false);
1628        self.expect(TokenKind::RParen, "expected `)`");
1629        let body = self.parse_statement();
1630        self.node(
1631            start,
1632            Statement::With(WithStatement {
1633                object: Box::new(object),
1634                body: Box::new(body),
1635            }),
1636        )
1637    }
1638
1639    fn parse_return_statement(&mut self, start: Utf16Pos) -> Stmt {
1640        self.bump();
1641        let argument = if self.at(TokenKind::Semicolon)
1642            || self.at(TokenKind::RBrace)
1643            || self.at_eof()
1644            || self.has_newline_before()
1645        {
1646            None
1647        } else {
1648            Some(Box::new(self.parse_expression(false)))
1649        };
1650        self.expect_semicolon();
1651        self.node(start, Statement::Return(ReturnStatement { argument }))
1652    }
1653
1654    fn parse_throw_statement(&mut self, start: Utf16Pos) -> Stmt {
1655        self.bump();
1656        let argument = if self.has_newline_before() {
1657            self.error_here(
1658                EXPECTED_EXPRESSION,
1659                "a `throw` argument must start on the same line",
1660            );
1661            self.missing_expr()
1662        } else {
1663            self.parse_expression(false)
1664        };
1665        self.expect_semicolon();
1666        self.node(
1667            start,
1668            Statement::Throw(ThrowStatement {
1669                argument: Box::new(argument),
1670            }),
1671        )
1672    }
1673
1674    fn parse_jump_statement(&mut self, start: Utf16Pos, is_break: bool) -> Stmt {
1675        self.bump();
1676        let label = if is_identifier_like(self.kind()) && !self.has_newline_before() {
1677            let token = self.bump();
1678            Some(self.ident_from(token))
1679        } else {
1680            None
1681        };
1682        self.expect_semicolon();
1683        let jump = JumpStatement { label };
1684        let statement = if is_break {
1685            Statement::Break(jump)
1686        } else {
1687            Statement::Continue(jump)
1688        };
1689        self.node(start, statement)
1690    }
1691
1692    fn parse_decorated_statement(&mut self, start: Utf16Pos) -> Stmt {
1693        let decorators = self.parse_decorators();
1694        let mut modifiers = DeclarationModifiers::default();
1695        if self.at(TokenKind::KwExport) {
1696            // `@dec export class` is legal ordering; re-enter export handling
1697            // with the decorators attached to the exported class.
1698            let export_start = self.cur_start();
1699            self.bump();
1700            let is_default = self.eat(TokenKind::KwDefault).is_some();
1701            if self.at(TokenKind::KwAbstract) {
1702                let range = self.cur().range();
1703                self.note_typescript_syntax(range);
1704                self.bump();
1705                modifiers.is_abstract = true;
1706            }
1707            if !self.at(TokenKind::KwClass) {
1708                self.error_here(EXPECTED_TOKEN, "decorators must precede a class");
1709            }
1710            let class = self.parse_class(decorators, modifiers, !is_default);
1711            let declaration = if is_default {
1712                ExportDeclaration::Default(ExportDefaultDeclaration {
1713                    value: ExportDefaultValue::Class(class),
1714                })
1715            } else {
1716                let class_stmt = self.node(export_start, Statement::Class(class));
1717                ExportDeclaration::Named(ExportNamedDeclaration::Declaration(Box::new(class_stmt)))
1718            };
1719            return self.node(start, Statement::Export(declaration));
1720        }
1721        if self.at(TokenKind::KwAbstract) && self.nth_kind(1) == TokenKind::KwClass {
1722            let range = self.cur().range();
1723            self.note_typescript_syntax(range);
1724            self.bump();
1725            modifiers.is_abstract = true;
1726        }
1727        if !self.at(TokenKind::KwClass) {
1728            self.error_here(EXPECTED_TOKEN, "decorators must precede a class");
1729            return self.missing_statement();
1730        }
1731        let class = self.parse_class(decorators, modifiers, true);
1732        self.node(start, Statement::Class(class))
1733    }
1734
1735    fn parse_decorators(&mut self) -> Vec<DecoratorNode> {
1736        let mut decorators = Vec::new();
1737        while self.at(TokenKind::At) {
1738            let start = self.cur_start();
1739            self.bump();
1740            let expression = self.parse_lhs_expression(false);
1741            let decorator: DecoratorNode = self.node(
1742                start,
1743                Decorator {
1744                    expression: Box::new(expression),
1745                },
1746            );
1747            decorators.push(decorator);
1748        }
1749        decorators
1750    }
1751}
1752
1753// ---------------------------------------------------------------------------
1754// Classes, interfaces, enums, namespaces
1755// ---------------------------------------------------------------------------
1756
1757impl Parser {
1758    fn parse_class(
1759        &mut self,
1760        decorators: Vec<DecoratorNode>,
1761        modifiers: DeclarationModifiers,
1762        require_name: bool,
1763    ) -> ClassDeclaration {
1764        self.expect(TokenKind::KwClass, "expected `class`");
1765        let name = if is_identifier_like(self.kind()) {
1766            let token = self.bump();
1767            Some(self.ident_from(token))
1768        } else {
1769            if require_name && !self.at(TokenKind::LBrace) && !self.at(TokenKind::KwExtends) {
1770                self.error_here(EXPECTED_IDENTIFIER, "expected a class name");
1771            }
1772            None
1773        };
1774        let type_parameters = self.parse_optional_type_parameters();
1775
1776        let mut extends = None;
1777        let mut implements = Vec::new();
1778        loop {
1779            if self.at(TokenKind::KwExtends) && extends.is_none() {
1780                self.bump();
1781                let expression = self.parse_lhs_expression(true);
1782                let type_arguments = self.try_parse_type_arguments_in_heritage();
1783                extends = Some(ClassHeritage {
1784                    expression: Box::new(expression),
1785                    type_arguments,
1786                });
1787            } else if self.at(TokenKind::KwImplements) {
1788                let range = self.cur().range();
1789                self.note_typescript_syntax(range);
1790                self.bump();
1791                loop {
1792                    implements.push(self.parse_type());
1793                    if self.eat(TokenKind::Comma).is_none() {
1794                        break;
1795                    }
1796                }
1797            } else {
1798                break;
1799            }
1800        }
1801
1802        self.expect(TokenKind::LBrace, "expected `{`");
1803        let mut members = Vec::new();
1804        while !self.at_eof() && !self.at(TokenKind::RBrace) {
1805            let before = self.cursor;
1806            let member = self.parse_class_member();
1807            members.push(member);
1808            if self.cursor == before {
1809                let skipped = self.bump();
1810                self.error_at(
1811                    UNEXPECTED_TOKEN,
1812                    skipped.range(),
1813                    "this token was skipped inside a class body",
1814                );
1815            }
1816        }
1817        self.expect(TokenKind::RBrace, "expected `}`");
1818
1819        ClassDeclaration {
1820            decorators,
1821            modifiers,
1822            name,
1823            type_parameters,
1824            extends,
1825            implements,
1826            members,
1827        }
1828    }
1829
1830    /// Type arguments on a heritage clause (`extends Base<T>`). The `<` here
1831    /// is unambiguous, so no speculation is required.
1832    fn try_parse_type_arguments_in_heritage(&mut self) -> Option<TypeArgumentList> {
1833        if !self.at_less_like() {
1834            return None;
1835        }
1836        Some(self.parse_type_arguments())
1837    }
1838
1839    fn parse_class_member(&mut self) -> ClassMemberNode {
1840        let start = self.cur_start();
1841        let decorators = self.parse_decorators();
1842        let mut modifiers = DeclarationModifiers::default();
1843        let mut is_async = false;
1844        let mut property_modifier = PropertyModifier::None;
1845        let mut is_accessor = false;
1846        let mut typescript_modifier: Option<TextRange> = None;
1847
1848        loop {
1849            let kind = self.kind();
1850            if !self.modifier_is_followed_by_member(1) {
1851                break;
1852            }
1853            match kind {
1854                TokenKind::KwPublic => {
1855                    typescript_modifier = Some(self.cur().range());
1856                    modifiers.accessibility = Some(Accessibility::Public);
1857                }
1858                TokenKind::KwProtected => {
1859                    typescript_modifier = Some(self.cur().range());
1860                    modifiers.accessibility = Some(Accessibility::Protected);
1861                }
1862                TokenKind::KwPrivate => {
1863                    typescript_modifier = Some(self.cur().range());
1864                    modifiers.accessibility = Some(Accessibility::Private);
1865                }
1866                TokenKind::KwStatic => modifiers.is_static = true,
1867                TokenKind::KwAbstract => {
1868                    typescript_modifier = Some(self.cur().range());
1869                    modifiers.is_abstract = true;
1870                }
1871                TokenKind::KwOverride => {
1872                    typescript_modifier = Some(self.cur().range());
1873                    modifiers.is_override = true;
1874                }
1875                TokenKind::KwReadonly => {
1876                    typescript_modifier = Some(self.cur().range());
1877                    modifiers.is_readonly = true;
1878                }
1879                TokenKind::KwDeclare => {
1880                    typescript_modifier = Some(self.cur().range());
1881                    modifiers.is_declare = true;
1882                }
1883                TokenKind::KwAsync if !self.has_newline_before_nth(1) => is_async = true,
1884                TokenKind::KwAccessor if !self.has_newline_before_nth(1) => is_accessor = true,
1885                TokenKind::KwGet => property_modifier = PropertyModifier::Get,
1886                TokenKind::KwSet => property_modifier = PropertyModifier::Set,
1887                _ => break,
1888            }
1889            self.bump();
1890            if matches!(kind, TokenKind::KwGet | TokenKind::KwSet) {
1891                break;
1892            }
1893        }
1894
1895        if let Some(range) = typescript_modifier {
1896            self.note_typescript_syntax(range);
1897        }
1898
1899        // `static { ... }` initializer block.
1900        if modifiers.is_static
1901            && self.at(TokenKind::LBrace)
1902            && property_modifier == PropertyModifier::None
1903            && !is_async
1904        {
1905            let block = self.parse_block();
1906            return self.node(start, ClassMember::StaticBlock(block));
1907        }
1908
1909        // Index signature `[key: string]: T`.
1910        if self.at(TokenKind::LBracket) && self.at_index_signature() {
1911            let range = self.cur().range();
1912            self.note_typescript_syntax(range);
1913            let parameters = self.parse_parameter_list();
1914            let type_annotation = match self.parse_optional_type_annotation() {
1915                Some(annotation) => annotation,
1916                None => {
1917                    self.error_here(EXPECTED_TOKEN, "an index signature requires a type");
1918                    self.missing_type_annotation()
1919                }
1920            };
1921            self.expect_semicolon();
1922            return self.node(
1923                start,
1924                ClassMember::IndexSignature(IndexSignature {
1925                    readonly: modifiers.is_readonly,
1926                    parameters,
1927                    type_annotation,
1928                }),
1929            );
1930        }
1931
1932        let is_generator = self.eat(TokenKind::Star).is_some();
1933        let name = self.parse_property_name();
1934        let optional = self.eat(TokenKind::Question).is_some();
1935        let definite = if self.at(TokenKind::Bang) && !self.has_newline_before() {
1936            self.bump();
1937            true
1938        } else {
1939            false
1940        };
1941
1942        // Constructor.
1943        if !is_accessor
1944            && property_modifier == PropertyModifier::None
1945            && self.is_constructor_name(&name)
1946            && self.at(TokenKind::LParen)
1947        {
1948            let parameters = self.parse_parameter_list();
1949            let return_type = self.parse_optional_type_annotation();
1950            if self.at(TokenKind::LBrace) {
1951                let body = self.parse_block();
1952                let _ = return_type;
1953                return self.node(
1954                    start,
1955                    ClassMember::Constructor(ConstructorDeclaration {
1956                        modifiers,
1957                        parameters,
1958                        body,
1959                    }),
1960                );
1961            }
1962            // A bodyless constructor overload signature is retained as a
1963            // method so no body is fabricated.
1964            self.expect_semicolon();
1965            return self.node(
1966                start,
1967                ClassMember::Method(MethodDeclaration {
1968                    modifiers,
1969                    modifier: PropertyModifier::None,
1970                    name,
1971                    optional,
1972                    function: FunctionLike {
1973                        decorators,
1974                        name: None,
1975                        is_async: false,
1976                        is_generator: false,
1977                        type_parameters: None,
1978                        parameters,
1979                        return_type,
1980                        body: None,
1981                    },
1982                }),
1983            );
1984        }
1985
1986        // Method, getter, or setter.
1987        if self.at(TokenKind::LParen) || self.at_less_like() || is_generator {
1988            let type_parameters = self.parse_optional_type_parameters();
1989            let parameters = self.parse_parameter_list();
1990            let return_type = self.parse_optional_type_annotation();
1991            let body = if self.at(TokenKind::LBrace) {
1992                Some(FunctionBody::Block(self.parse_block()))
1993            } else {
1994                self.expect_semicolon();
1995                None
1996            };
1997            return self.node(
1998                start,
1999                ClassMember::Method(MethodDeclaration {
2000                    modifiers,
2001                    modifier: property_modifier,
2002                    name,
2003                    optional,
2004                    function: FunctionLike {
2005                        decorators,
2006                        name: None,
2007                        is_async,
2008                        is_generator,
2009                        type_parameters,
2010                        parameters,
2011                        return_type,
2012                        body,
2013                    },
2014                }),
2015            );
2016        }
2017
2018        // Property or auto-accessor.
2019        let type_annotation = self.parse_optional_type_annotation();
2020        let initializer = if self.eat(TokenKind::Eq).is_some() {
2021            Some(Box::new(self.parse_assignment_expression(false)))
2022        } else {
2023            None
2024        };
2025        self.expect_semicolon();
2026        if is_accessor {
2027            return self.node(
2028                start,
2029                ClassMember::AutoAccessor(AutoAccessor {
2030                    modifiers,
2031                    name,
2032                    type_annotation,
2033                    initializer,
2034                }),
2035            );
2036        }
2037        self.node(
2038            start,
2039            ClassMember::Property(ClassProperty {
2040                modifiers,
2041                name,
2042                optional,
2043                definite,
2044                type_annotation,
2045                initializer,
2046            }),
2047        )
2048    }
2049
2050    /// A keyword is a member modifier only when a member can still start after
2051    /// it; otherwise it is the member's own name.
2052    fn modifier_is_followed_by_member(&self, offset: usize) -> bool {
2053        if !matches!(
2054            self.kind(),
2055            TokenKind::KwPublic
2056                | TokenKind::KwProtected
2057                | TokenKind::KwPrivate
2058                | TokenKind::KwStatic
2059                | TokenKind::KwAbstract
2060                | TokenKind::KwOverride
2061                | TokenKind::KwReadonly
2062                | TokenKind::KwDeclare
2063                | TokenKind::KwAsync
2064                | TokenKind::KwAccessor
2065                | TokenKind::KwGet
2066                | TokenKind::KwSet
2067        ) {
2068            return false;
2069        }
2070        let next = self.nth_kind(offset);
2071        is_any_word(next)
2072            || matches!(
2073                next,
2074                TokenKind::LBracket
2075                    | TokenKind::StringLiteral
2076                    | TokenKind::NumericLiteral
2077                    | TokenKind::PrivateIdentifier
2078                    | TokenKind::Star
2079            )
2080            || (self.at(TokenKind::KwStatic) && next == TokenKind::LBrace)
2081    }
2082
2083    /// Returns whether `name` is exactly the `constructor` identifier, so a
2084    /// method named `constructors` is not misread as a constructor.
2085    fn is_constructor_name(&self, name: &PropertyName) -> bool {
2086        let PropertyName::Identifier(node) = name else {
2087            return false;
2088        };
2089        self.lexeme(*node.data().token()) == "constructor"
2090    }
2091
2092    /// Distinguishes `[key: string]: T` from a computed member name.
2093    fn at_index_signature(&self) -> bool {
2094        is_identifier_like(self.nth_kind(1)) && self.nth_kind(2) == TokenKind::Colon
2095    }
2096
2097    fn missing_type_annotation(&mut self) -> TypeAnnotationNode {
2098        let start = self.cur_start();
2099        let type_node = self.missing_type();
2100        self.node_at(
2101            empty_range(start),
2102            TypeAnnotation {
2103                type_node: Box::new(type_node),
2104            },
2105        )
2106    }
2107
2108    fn parse_interface_declaration(&mut self, start: Utf16Pos) -> Stmt {
2109        let keyword_range = self.cur().range();
2110        self.note_typescript_syntax(keyword_range);
2111        self.bump();
2112        let name = self.expect_identifier("expected an interface name");
2113        let type_parameters = self.parse_optional_type_parameters();
2114        let mut extends = Vec::new();
2115        if self.eat(TokenKind::KwExtends).is_some() {
2116            loop {
2117                let entity = self.parse_entity_name();
2118                let type_arguments = if self.at_less_like() {
2119                    Some(self.parse_type_arguments())
2120                } else {
2121                    None
2122                };
2123                extends.push(TypeReference {
2124                    name: entity,
2125                    type_arguments,
2126                });
2127                if self.eat(TokenKind::Comma).is_none() {
2128                    break;
2129                }
2130            }
2131        }
2132        let members = self.parse_type_members();
2133        self.node(
2134            start,
2135            Statement::Interface(InterfaceDeclaration {
2136                name,
2137                type_parameters,
2138                extends,
2139                members,
2140            }),
2141        )
2142    }
2143
2144    fn parse_type_alias_declaration(&mut self, start: Utf16Pos) -> Stmt {
2145        let keyword_range = self.cur().range();
2146        self.note_typescript_syntax(keyword_range);
2147        self.bump();
2148        let name = self.expect_identifier("expected a type alias name");
2149        let type_parameters = self.parse_optional_type_parameters();
2150        self.expect(TokenKind::Eq, "expected `=`");
2151        let type_node = self.parse_type();
2152        self.expect_semicolon();
2153        self.node(
2154            start,
2155            Statement::TypeAlias(TypeAliasDeclaration {
2156                name,
2157                type_parameters,
2158                type_node: Box::new(type_node),
2159            }),
2160        )
2161    }
2162
2163    fn parse_enum_declaration(&mut self, start: Utf16Pos, is_const: bool) -> Stmt {
2164        let keyword_range = self.cur().range();
2165        self.note_typescript_syntax(keyword_range);
2166        self.expect(TokenKind::KwEnum, "expected `enum`");
2167        let name = self.expect_identifier("expected an enum name");
2168        self.expect(TokenKind::LBrace, "expected `{`");
2169        let mut members = Vec::new();
2170        while !self.at_eof() && !self.at(TokenKind::RBrace) {
2171            let before = self.cursor;
2172            let member_start = self.cur_start();
2173            let name = self.parse_property_name();
2174            let initializer = if self.eat(TokenKind::Eq).is_some() {
2175                Some(Box::new(self.parse_assignment_expression(false)))
2176            } else {
2177                None
2178            };
2179            let member: EnumMemberNode = self.node(member_start, EnumMember { name, initializer });
2180            members.push(member);
2181            if self.eat(TokenKind::Comma).is_none() && !self.at(TokenKind::RBrace) {
2182                self.error_here(EXPECTED_TOKEN, "expected `,`");
2183            }
2184            if self.cursor == before {
2185                let skipped = self.bump();
2186                self.error_at(
2187                    UNEXPECTED_TOKEN,
2188                    skipped.range(),
2189                    "this token was skipped inside an enum body",
2190                );
2191            }
2192        }
2193        self.expect(TokenKind::RBrace, "expected `}`");
2194        self.node(
2195            start,
2196            Statement::Enum(EnumDeclaration {
2197                is_const,
2198                name,
2199                members,
2200            }),
2201        )
2202    }
2203
2204    /// Parses `namespace A.B.C { ... }`, desugaring the dotted form into
2205    /// nested single-name declarations because the node carries one name.
2206    fn parse_namespace_declaration(&mut self, start: Utf16Pos) -> Stmt {
2207        let keyword_range = self.cur().range();
2208        self.note_typescript_syntax(keyword_range);
2209        self.bump();
2210        let name = self.expect_identifier("expected a namespace name");
2211        let body = if self.at(TokenKind::Dot) {
2212            let inner_start = self.cur_start();
2213            self.bump();
2214            let inner = self.parse_namespace_tail(inner_start);
2215            let statements = vec![inner];
2216            self.node(inner_start, Block { statements })
2217        } else {
2218            self.parse_block()
2219        };
2220        self.node(
2221            start,
2222            Statement::Namespace(NamespaceDeclaration { name, body }),
2223        )
2224    }
2225
2226    fn parse_namespace_tail(&mut self, start: Utf16Pos) -> Stmt {
2227        let name = self.expect_identifier("expected a namespace name");
2228        let body = if self.at(TokenKind::Dot) {
2229            let inner_start = self.cur_start();
2230            self.bump();
2231            let inner = self.parse_namespace_tail(inner_start);
2232            let statements = vec![inner];
2233            self.node(inner_start, Block { statements })
2234        } else {
2235            self.parse_block()
2236        };
2237        self.node(
2238            start,
2239            Statement::Namespace(NamespaceDeclaration { name, body }),
2240        )
2241    }
2242
2243    /// Parses ambient `global { ... }` and `module Name { ... }` forms after a
2244    /// `declare` wrapper. A string-named module cannot be represented by the
2245    /// namespace node's identifier field, so recovery records a stable
2246    /// unsupported-syntax diagnostic and keeps a missing name.
2247    fn parse_contextual_namespace(&mut self, start: Utf16Pos) -> Stmt {
2248        let keyword = self.bump();
2249        let is_global = self.lexeme(keyword) == "global";
2250        let name = if is_global {
2251            self.ident_from(keyword)
2252        } else if is_identifier_like(self.kind()) {
2253            self.expect_identifier("expected a module name")
2254        } else if self.at(TokenKind::StringLiteral) {
2255            let range = self.cur().range();
2256            self.error_at(
2257                UNSUPPORTED_SYNTAX,
2258                range,
2259                "a string-named module is not representable in this syntax tree",
2260            );
2261            self.bump();
2262            self.missing_ident()
2263        } else {
2264            self.error_here(EXPECTED_IDENTIFIER, "expected a module name");
2265            self.missing_ident()
2266        };
2267        let body = self.parse_block();
2268        self.node(
2269            start,
2270            Statement::Namespace(NamespaceDeclaration { name, body }),
2271        )
2272    }
2273}
2274
2275// ---------------------------------------------------------------------------
2276// Modules
2277// ---------------------------------------------------------------------------
2278
2279impl Parser {
2280    fn parse_import_statement(&mut self, start: Utf16Pos) -> Stmt {
2281        self.bump();
2282
2283        // `import "module";`
2284        if self.at(TokenKind::StringLiteral) {
2285            let source = self.parse_string_literal();
2286            let attributes = self.parse_optional_import_attributes();
2287            self.expect_semicolon();
2288            return self.node(
2289                start,
2290                Statement::Import(ImportDeclaration {
2291                    type_only: false,
2292                    clause: None,
2293                    source,
2294                    attributes,
2295                }),
2296            );
2297        }
2298
2299        // `import type ...`, unless `type` is itself the imported binding.
2300        let type_only = self.at(TokenKind::KwType) && self.type_keyword_is_modifier();
2301        if type_only {
2302            let range = self.cur().range();
2303            self.note_typescript_syntax(range);
2304            self.bump();
2305        }
2306
2307        // `import x = require("m")` / `import x = A.B`.
2308        if is_identifier_like(self.kind()) && self.nth_kind(1) == TokenKind::Eq {
2309            let range = self.cur().range();
2310            self.note_typescript_syntax(range);
2311            let local = self.expect_identifier("expected an import name");
2312            self.bump();
2313            let reference = self.parse_external_module_reference();
2314            self.expect_semicolon();
2315            return self.node(
2316                start,
2317                Statement::ImportEquals(ImportEqualsDeclaration {
2318                    is_type_only: type_only,
2319                    local,
2320                    reference,
2321                }),
2322            );
2323        }
2324
2325        let clause = self.parse_import_clause();
2326        self.expect(TokenKind::KwFrom, "expected `from`");
2327        let source = self.parse_string_literal();
2328        let attributes = self.parse_optional_import_attributes();
2329        self.expect_semicolon();
2330        self.node(
2331            start,
2332            Statement::Import(ImportDeclaration {
2333                type_only,
2334                clause: Some(clause),
2335                source,
2336                attributes,
2337            }),
2338        )
2339    }
2340
2341    /// In `import type X from "m"`, `type` is a modifier. In
2342    /// `import type from "m"` and `import type, {x} from "m"`, it is the
2343    /// default binding's name.
2344    fn type_keyword_is_modifier(&self) -> bool {
2345        !matches!(
2346            self.nth_kind(1),
2347            TokenKind::KwFrom | TokenKind::Comma | TokenKind::Eq
2348        )
2349    }
2350
2351    fn parse_external_module_reference(&mut self) -> ExternalModuleReference {
2352        if is_identifier_like(self.kind())
2353            && self.cur_lexeme() == "require"
2354            && self.nth_kind(1) == TokenKind::LParen
2355        {
2356            self.bump();
2357            self.bump();
2358            let source = self.parse_string_literal();
2359            self.expect(TokenKind::RParen, "expected `)`");
2360            return ExternalModuleReference::Require(source);
2361        }
2362        if is_identifier_like(self.kind()) {
2363            return ExternalModuleReference::Qualified(self.parse_entity_name());
2364        }
2365        self.error_here(EXPECTED_IDENTIFIER, "expected a module reference");
2366        ExternalModuleReference::Missing(MissingNode::new(NodeKind::Identifier))
2367    }
2368
2369    fn parse_import_clause(&mut self) -> ImportClause {
2370        // `* as ns`
2371        if self.at(TokenKind::Star) {
2372            let binding = self.parse_namespace_import();
2373            return ImportClause {
2374                default: None,
2375                binding: Some(binding),
2376            };
2377        }
2378        // `{ ... }`
2379        if self.at(TokenKind::LBrace) {
2380            let specifiers = self.parse_named_imports();
2381            return ImportClause {
2382                default: None,
2383                binding: Some(ImportBinding::Named(specifiers)),
2384            };
2385        }
2386        // `def`, `def, { ... }`, `def, * as ns`
2387        let default = if is_identifier_like(self.kind()) {
2388            let token = self.bump();
2389            Some(self.ident_from(token))
2390        } else {
2391            self.error_here(EXPECTED_IDENTIFIER, "expected an import binding");
2392            None
2393        };
2394        let mut binding = None;
2395        if self.eat(TokenKind::Comma).is_some() {
2396            if self.at(TokenKind::Star) {
2397                binding = Some(self.parse_namespace_import());
2398            } else if self.at(TokenKind::LBrace) {
2399                binding = Some(ImportBinding::Named(self.parse_named_imports()));
2400            } else {
2401                self.error_here(EXPECTED_TOKEN, "expected `{` or `*` after `,`");
2402            }
2403        }
2404        ImportClause { default, binding }
2405    }
2406
2407    fn parse_namespace_import(&mut self) -> ImportBinding {
2408        self.bump();
2409        self.expect(TokenKind::KwAs, "expected `as`");
2410        let name = self.expect_identifier("expected a namespace import name");
2411        ImportBinding::Namespace(name)
2412    }
2413
2414    fn parse_named_imports(&mut self) -> Vec<ImportSpecifierNode> {
2415        self.expect(TokenKind::LBrace, "expected `{`");
2416        let mut specifiers = Vec::new();
2417        while !self.at_eof() && !self.at(TokenKind::RBrace) {
2418            let before = self.cursor;
2419            let start = self.cur_start();
2420            let mode = if self.at(TokenKind::KwType) && self.specifier_type_is_modifier() {
2421                self.bump();
2422                ImportSpecifierMode::TypeOnly
2423            } else {
2424                ImportSpecifierMode::Value
2425            };
2426            let imported = self.parse_module_export_name();
2427            let local = if self.eat(TokenKind::KwAs).is_some() {
2428                self.expect_identifier("expected a local import name")
2429            } else {
2430                match &imported {
2431                    ModuleExportName::Identifier(name) => {
2432                        let token = *name.data().token();
2433                        self.ident_from(token)
2434                    }
2435                    ModuleExportName::String(_) => {
2436                        self.error_here(
2437                            EXPECTED_TOKEN,
2438                            "a string import name requires `as` and a local binding",
2439                        );
2440                        self.missing_ident()
2441                    }
2442                    ModuleExportName::Missing(_) => self.missing_ident(),
2443                }
2444            };
2445            let specifier: ImportSpecifierNode = self.node(
2446                start,
2447                ImportSpecifier {
2448                    mode,
2449                    imported,
2450                    local,
2451                },
2452            );
2453            specifiers.push(specifier);
2454            if self.eat(TokenKind::Comma).is_none() && !self.at(TokenKind::RBrace) {
2455                self.error_here(EXPECTED_TOKEN, "expected `,`");
2456            }
2457            if self.cursor == before {
2458                let skipped = self.bump();
2459                self.error_at(
2460                    UNEXPECTED_TOKEN,
2461                    skipped.range(),
2462                    "this token was skipped inside an import list",
2463                );
2464            }
2465        }
2466        self.expect(TokenKind::RBrace, "expected `}`");
2467        specifiers
2468    }
2469
2470    /// In `{ type as x }` the first `type` is the imported name; in
2471    /// `{ type x }` and `{ type x as y }` it is the type-only modifier.
2472    fn specifier_type_is_modifier(&self) -> bool {
2473        match self.nth_kind(1) {
2474            TokenKind::KwAs => {
2475                matches!(self.nth_kind(2), TokenKind::KwAs)
2476                    || is_identifier_like(self.nth_kind(2)) && self.nth_kind(3) == TokenKind::KwAs
2477            }
2478            TokenKind::Comma | TokenKind::RBrace => false,
2479            kind => is_identifier_like(kind) || kind == TokenKind::StringLiteral,
2480        }
2481    }
2482
2483    fn parse_module_export_name(&mut self) -> ModuleExportName {
2484        if self.at(TokenKind::StringLiteral) {
2485            return ModuleExportName::String(self.parse_string_literal());
2486        }
2487        if is_any_word(self.kind()) {
2488            let token = self.bump();
2489            return ModuleExportName::Identifier(self.ident_from(token));
2490        }
2491        self.error_here(EXPECTED_IDENTIFIER, "expected a module export name");
2492        ModuleExportName::Missing(MissingNode::new(NodeKind::Identifier))
2493    }
2494
2495    fn parse_optional_import_attributes(&mut self) -> Option<ImportAttributes> {
2496        let is_with = self.at(TokenKind::KwWith);
2497        let is_assert = is_identifier_like(self.kind())
2498            && self.cur_lexeme() == "assert"
2499            && self.nth_kind(1) == TokenKind::LBrace
2500            && !self.has_newline_before();
2501        if !is_with && !is_assert {
2502            return None;
2503        }
2504        self.bump();
2505        self.expect(TokenKind::LBrace, "expected `{`");
2506        let mut entries = Vec::new();
2507        while !self.at_eof() && !self.at(TokenKind::RBrace) {
2508            let before = self.cursor;
2509            let name = self.parse_module_export_name();
2510            self.expect(TokenKind::Colon, "expected `:`");
2511            let value = self.parse_string_literal();
2512            entries.push(ImportAttribute { name, value });
2513            if self.eat(TokenKind::Comma).is_none() && !self.at(TokenKind::RBrace) {
2514                self.error_here(EXPECTED_TOKEN, "expected `,`");
2515            }
2516            if self.cursor == before {
2517                let skipped = self.bump();
2518                self.error_at(
2519                    UNEXPECTED_TOKEN,
2520                    skipped.range(),
2521                    "this token was skipped inside import attributes",
2522                );
2523            }
2524        }
2525        self.expect(TokenKind::RBrace, "expected `}`");
2526        Some(ImportAttributes { entries })
2527    }
2528
2529    fn parse_string_literal(&mut self) -> StringLiteralNode {
2530        if self.at(TokenKind::StringLiteral) {
2531            let token = self.bump();
2532            let range = token.range();
2533            return self.node_at(range, StringLiteral::new(token));
2534        }
2535        self.error_here(EXPECTED_TOKEN, "expected a string literal");
2536        let token = self.missing_token(TokenKind::StringLiteral);
2537        let range = token.range();
2538        self.node_at(range, StringLiteral::new(token))
2539    }
2540
2541    fn parse_export_statement(&mut self, start: Utf16Pos) -> Stmt {
2542        self.bump();
2543
2544        // `export * from "m"` / `export * as ns from "m"`
2545        if self.at(TokenKind::Star) {
2546            self.bump();
2547            let exported = if self.eat(TokenKind::KwAs).is_some() {
2548                Some(self.parse_module_export_name())
2549            } else {
2550                None
2551            };
2552            self.expect(TokenKind::KwFrom, "expected `from`");
2553            let source = self.parse_string_literal();
2554            let attributes = self.parse_optional_import_attributes();
2555            self.expect_semicolon();
2556            return self.node(
2557                start,
2558                Statement::Export(ExportDeclaration::All(ExportAllDeclaration {
2559                    type_only: false,
2560                    exported,
2561                    source,
2562                    attributes,
2563                })),
2564            );
2565        }
2566
2567        // `export { ... }` / `export { ... } from "m"`
2568        if self.at(TokenKind::LBrace) {
2569            return self.parse_export_specifiers(start, false);
2570        }
2571
2572        // `export type ...`
2573        if self.at(TokenKind::KwType) {
2574            let range = self.cur().range();
2575            match self.nth_kind(1) {
2576                TokenKind::LBrace => {
2577                    self.note_typescript_syntax(range);
2578                    self.bump();
2579                    return self.parse_export_specifiers(start, true);
2580                }
2581                TokenKind::Star => {
2582                    self.note_typescript_syntax(range);
2583                    self.bump();
2584                    self.bump();
2585                    let exported = if self.eat(TokenKind::KwAs).is_some() {
2586                        Some(self.parse_module_export_name())
2587                    } else {
2588                        None
2589                    };
2590                    self.expect(TokenKind::KwFrom, "expected `from`");
2591                    let source = self.parse_string_literal();
2592                    let attributes = self.parse_optional_import_attributes();
2593                    self.expect_semicolon();
2594                    return self.node(
2595                        start,
2596                        Statement::Export(ExportDeclaration::All(ExportAllDeclaration {
2597                            type_only: true,
2598                            exported,
2599                            source,
2600                            attributes,
2601                        })),
2602                    );
2603                }
2604                _ => {}
2605            }
2606        }
2607
2608        // `export = expr`
2609        if self.at(TokenKind::Eq) {
2610            let range = self.cur().range();
2611            self.note_typescript_syntax(range);
2612            self.bump();
2613            let expression = self.parse_assignment_expression(false);
2614            self.expect_semicolon();
2615            return self.node(
2616                start,
2617                Statement::Export(ExportDeclaration::Assignment(Box::new(expression))),
2618            );
2619        }
2620
2621        // `export default ...`
2622        if self.eat(TokenKind::KwDefault).is_some() {
2623            let value = self.parse_export_default_value();
2624            return self.node(
2625                start,
2626                Statement::Export(ExportDeclaration::Default(ExportDefaultDeclaration {
2627                    value,
2628                })),
2629            );
2630        }
2631
2632        // `export <declaration>`
2633        let declaration_start = self.cur_start();
2634        if self.can_start_exported_declaration() {
2635            let declaration = self.parse_statement();
2636            let _ = declaration_start;
2637            return self.node(
2638                start,
2639                Statement::Export(ExportDeclaration::Named(
2640                    ExportNamedDeclaration::Declaration(Box::new(declaration)),
2641                )),
2642            );
2643        }
2644
2645        self.error_here(UNEXPECTED_TOKEN, "expected an export declaration");
2646        let specifiers = Vec::new();
2647        self.node(
2648            start,
2649            Statement::Export(ExportDeclaration::Named(
2650                ExportNamedDeclaration::Specifiers {
2651                    type_only: false,
2652                    specifiers,
2653                    source: None,
2654                    attributes: None,
2655                },
2656            )),
2657        )
2658    }
2659
2660    fn can_start_exported_declaration(&self) -> bool {
2661        matches!(
2662            self.kind(),
2663            TokenKind::KwVar
2664                | TokenKind::KwLet
2665                | TokenKind::KwConst
2666                | TokenKind::KwFunction
2667                | TokenKind::KwClass
2668                | TokenKind::KwAbstract
2669                | TokenKind::KwAsync
2670                | TokenKind::KwEnum
2671                | TokenKind::KwInterface
2672                | TokenKind::KwType
2673                | TokenKind::KwNamespace
2674                | TokenKind::KwDeclare
2675                | TokenKind::KwImport
2676                | TokenKind::At
2677        ) || (self.at(TokenKind::Identifier) && self.cur_lexeme() == "using")
2678    }
2679
2680    fn parse_export_default_value(&mut self) -> ExportDefaultValue {
2681        match self.kind() {
2682            TokenKind::KwFunction => {
2683                let function = self.parse_function_like(Vec::new(), false, false);
2684                ExportDefaultValue::Function(function)
2685            }
2686            TokenKind::KwAsync if self.nth_kind(1) == TokenKind::KwFunction => {
2687                self.bump();
2688                let function = self.parse_function_like(Vec::new(), true, false);
2689                ExportDefaultValue::Function(function)
2690            }
2691            TokenKind::KwClass => {
2692                let class = self.parse_class(Vec::new(), DeclarationModifiers::default(), false);
2693                ExportDefaultValue::Class(class)
2694            }
2695            TokenKind::KwAbstract if self.nth_kind(1) == TokenKind::KwClass => {
2696                let range = self.cur().range();
2697                self.note_typescript_syntax(range);
2698                self.bump();
2699                let modifiers = DeclarationModifiers {
2700                    is_abstract: true,
2701                    ..DeclarationModifiers::default()
2702                };
2703                let class = self.parse_class(Vec::new(), modifiers, false);
2704                ExportDefaultValue::Class(class)
2705            }
2706            TokenKind::At => {
2707                let decorators = self.parse_decorators();
2708                if self.at(TokenKind::KwClass) {
2709                    let class =
2710                        self.parse_class(decorators, DeclarationModifiers::default(), false);
2711                    ExportDefaultValue::Class(class)
2712                } else {
2713                    self.error_here(EXPECTED_TOKEN, "decorators must precede a class");
2714                    ExportDefaultValue::Missing(MissingNode::new(NodeKind::ClassDeclaration))
2715                }
2716            }
2717            _ => {
2718                let before = self.cursor;
2719                let expression = self.parse_assignment_expression(false);
2720                if self.cursor == before {
2721                    return ExportDefaultValue::Missing(MissingNode::new(
2722                        NodeKind::MissingExpression,
2723                    ));
2724                }
2725                self.expect_semicolon();
2726                ExportDefaultValue::Expression(Box::new(expression))
2727            }
2728        }
2729    }
2730
2731    fn parse_export_specifiers(&mut self, start: Utf16Pos, type_only: bool) -> Stmt {
2732        self.expect(TokenKind::LBrace, "expected `{`");
2733        let mut specifiers = Vec::new();
2734        while !self.at_eof() && !self.at(TokenKind::RBrace) {
2735            let before = self.cursor;
2736            let specifier_start = self.cur_start();
2737            let mode = if self.at(TokenKind::KwType) && self.specifier_type_is_modifier() {
2738                self.bump();
2739                ExportSpecifierMode::TypeOnly
2740            } else {
2741                ExportSpecifierMode::Value
2742            };
2743            let local = self.parse_module_export_name();
2744            let exported = if self.eat(TokenKind::KwAs).is_some() {
2745                self.parse_module_export_name()
2746            } else {
2747                local.clone()
2748            };
2749            let specifier: ExportSpecifierNode = self.node(
2750                specifier_start,
2751                ExportSpecifier {
2752                    mode,
2753                    local,
2754                    exported,
2755                },
2756            );
2757            specifiers.push(specifier);
2758            if self.eat(TokenKind::Comma).is_none() && !self.at(TokenKind::RBrace) {
2759                self.error_here(EXPECTED_TOKEN, "expected `,`");
2760            }
2761            if self.cursor == before {
2762                let skipped = self.bump();
2763                self.error_at(
2764                    UNEXPECTED_TOKEN,
2765                    skipped.range(),
2766                    "this token was skipped inside an export list",
2767                );
2768            }
2769        }
2770        self.expect(TokenKind::RBrace, "expected `}`");
2771        let (source, attributes) = if self.eat(TokenKind::KwFrom).is_some() {
2772            let source = self.parse_string_literal();
2773            let attributes = self.parse_optional_import_attributes();
2774            (Some(source), attributes)
2775        } else {
2776            (None, None)
2777        };
2778        self.expect_semicolon();
2779        self.node(
2780            start,
2781            Statement::Export(ExportDeclaration::Named(
2782                ExportNamedDeclaration::Specifiers {
2783                    type_only,
2784                    specifiers,
2785                    source,
2786                    attributes,
2787                },
2788            )),
2789        )
2790    }
2791}
2792
2793// ---------------------------------------------------------------------------
2794// Expressions
2795// ---------------------------------------------------------------------------
2796
2797/// Binary operator binding power. Higher binds tighter; assignment and the
2798/// comma operator are handled outside this table.
2799fn binary_precedence(kind: TokenKind) -> Option<(BinaryOrLogical, u8)> {
2800    use BinaryOrLogical::{Binary, Logical};
2801    let entry = match kind {
2802        TokenKind::PipePipe => (Logical(LogicalOperator::Or), 4),
2803        TokenKind::QuestionQuestion => (Logical(LogicalOperator::Nullish), 4),
2804        TokenKind::AmpAmp => (Logical(LogicalOperator::And), 5),
2805        TokenKind::Pipe => (Binary(BinaryOperator::BitOr), 6),
2806        TokenKind::Caret => (Binary(BinaryOperator::BitXor), 7),
2807        TokenKind::Amp => (Binary(BinaryOperator::BitAnd), 8),
2808        TokenKind::EqEq => (Binary(BinaryOperator::Equal), 9),
2809        TokenKind::BangEq => (Binary(BinaryOperator::NotEqual), 9),
2810        TokenKind::EqEqEq => (Binary(BinaryOperator::StrictEqual), 9),
2811        TokenKind::BangEqEq => (Binary(BinaryOperator::StrictNotEqual), 9),
2812        TokenKind::LessThan => (Binary(BinaryOperator::LessThan), 10),
2813        TokenKind::GreaterThan => (Binary(BinaryOperator::GreaterThan), 10),
2814        TokenKind::LessThanEq => (Binary(BinaryOperator::LessThanOrEqual), 10),
2815        TokenKind::GreaterThanEq => (Binary(BinaryOperator::GreaterThanOrEqual), 10),
2816        TokenKind::KwInstanceof => (Binary(BinaryOperator::Instanceof), 10),
2817        TokenKind::KwIn => (Binary(BinaryOperator::In), 10),
2818        TokenKind::LessLess => (Binary(BinaryOperator::LeftShift), 11),
2819        TokenKind::GreaterGreater => (Binary(BinaryOperator::SignedRightShift), 11),
2820        TokenKind::GreaterGreaterGreater => (Binary(BinaryOperator::UnsignedRightShift), 11),
2821        TokenKind::Plus => (Binary(BinaryOperator::Add), 12),
2822        TokenKind::Minus => (Binary(BinaryOperator::Subtract), 12),
2823        TokenKind::Star => (Binary(BinaryOperator::Multiply), 13),
2824        TokenKind::Slash => (Binary(BinaryOperator::Divide), 13),
2825        TokenKind::Percent => (Binary(BinaryOperator::Remainder), 13),
2826        TokenKind::StarStar => (Binary(BinaryOperator::Exponentiate), 14),
2827        _ => return None,
2828    };
2829    Some(entry)
2830}
2831
2832#[derive(Clone, Copy)]
2833enum BinaryOrLogical {
2834    Binary(BinaryOperator),
2835    Logical(LogicalOperator),
2836}
2837
2838fn assignment_operator(kind: TokenKind) -> Option<AssignmentOperator> {
2839    let op = match kind {
2840        TokenKind::Eq => AssignmentOperator::Assign,
2841        TokenKind::PlusEq => AssignmentOperator::AddAssign,
2842        TokenKind::MinusEq => AssignmentOperator::SubtractAssign,
2843        TokenKind::StarEq => AssignmentOperator::MultiplyAssign,
2844        TokenKind::SlashEq => AssignmentOperator::DivideAssign,
2845        TokenKind::PercentEq => AssignmentOperator::RemainderAssign,
2846        TokenKind::StarStarEq => AssignmentOperator::ExponentiateAssign,
2847        TokenKind::LessLessEq => AssignmentOperator::LeftShiftAssign,
2848        TokenKind::GreaterGreaterEq => AssignmentOperator::SignedRightShiftAssign,
2849        TokenKind::GreaterGreaterGreaterEq => AssignmentOperator::UnsignedRightShiftAssign,
2850        TokenKind::AmpEq => AssignmentOperator::BitAndAssign,
2851        TokenKind::CaretEq => AssignmentOperator::BitXorAssign,
2852        TokenKind::PipeEq => AssignmentOperator::BitOrAssign,
2853        TokenKind::AmpAmpEq => AssignmentOperator::LogicalAndAssign,
2854        TokenKind::PipePipeEq => AssignmentOperator::LogicalOrAssign,
2855        TokenKind::QuestionQuestionEq => AssignmentOperator::NullishAssign,
2856        _ => return None,
2857    };
2858    Some(op)
2859}
2860
2861impl Parser {
2862    /// Parses a full expression, folding a top-level comma into a sequence.
2863    fn parse_expression(&mut self, no_in: bool) -> Expr {
2864        let start = self.cur_start();
2865        let first = self.parse_assignment_expression(no_in);
2866        if !self.at(TokenKind::Comma) {
2867            return first;
2868        }
2869        let mut expressions = vec![first];
2870        while self.eat(TokenKind::Comma).is_some() {
2871            expressions.push(self.parse_assignment_expression(no_in));
2872        }
2873        self.node(
2874            start,
2875            Expression::Sequence(SequenceExpression { expressions }),
2876        )
2877    }
2878
2879    fn parse_assignment_expression(&mut self, no_in: bool) -> Expr {
2880        if !self.enter() {
2881            return self.missing_expr();
2882        }
2883        let expr = self.parse_assignment_inner(no_in);
2884        self.leave();
2885        expr
2886    }
2887
2888    fn parse_assignment_inner(&mut self, no_in: bool) -> Expr {
2889        let start = self.cur_start();
2890
2891        if self.at(TokenKind::KwYield) {
2892            return self.parse_yield_expression(start, no_in);
2893        }
2894
2895        // Arrow fast paths and speculation.
2896        if let Some(arrow) = self.try_parse_arrow_function(no_in) {
2897            return arrow;
2898        }
2899
2900        let left = self.parse_conditional_expression(no_in);
2901        if let Some(op) = assignment_operator(self.kind()) {
2902            let simple = op == AssignmentOperator::Assign;
2903            let target = self.expression_to_target_for_assignment(left, simple);
2904            self.bump();
2905            let right = self.parse_assignment_expression(no_in);
2906            return self.node(
2907                start,
2908                Expression::Assignment(AssignmentExpression {
2909                    operator: op,
2910                    left: target,
2911                    right: Box::new(right),
2912                }),
2913            );
2914        }
2915        left
2916    }
2917
2918    fn parse_yield_expression(&mut self, start: Utf16Pos, no_in: bool) -> Expr {
2919        self.bump();
2920        let delegate = self.at(TokenKind::Star) && !self.has_newline_before();
2921        if delegate {
2922            self.bump();
2923        }
2924        let argument = if delegate || (self.can_start_expression() && !self.has_newline_before()) {
2925            Some(Box::new(self.parse_assignment_expression(no_in)))
2926        } else {
2927            None
2928        };
2929        self.node(
2930            start,
2931            Expression::Yield(YieldExpression { delegate, argument }),
2932        )
2933    }
2934
2935    fn can_start_expression(&self) -> bool {
2936        match self.kind() {
2937            TokenKind::Semicolon
2938            | TokenKind::RParen
2939            | TokenKind::RBrace
2940            | TokenKind::RBracket
2941            | TokenKind::Comma
2942            | TokenKind::Colon
2943            | TokenKind::EndOfFile => false,
2944            _ => !self.at_eof(),
2945        }
2946    }
2947
2948    fn parse_conditional_expression(&mut self, no_in: bool) -> Expr {
2949        if !self.enter() {
2950            return self.missing_expr();
2951        }
2952        let expr = self.parse_conditional_inner(no_in);
2953        self.leave();
2954        expr
2955    }
2956
2957    fn parse_conditional_inner(&mut self, no_in: bool) -> Expr {
2958        let start = self.cur_start();
2959        let test = self.parse_binary_expression(0, no_in);
2960        if !self.at(TokenKind::Question) {
2961            return test;
2962        }
2963        self.bump();
2964        let consequent = self.parse_assignment_expression(false);
2965        self.expect(TokenKind::Colon, "expected `:`");
2966        let alternate = self.parse_assignment_expression(no_in);
2967        self.node(
2968            start,
2969            Expression::Conditional(ConditionalExpression {
2970                test: Box::new(test),
2971                consequent: Box::new(consequent),
2972                alternate: Box::new(alternate),
2973            }),
2974        )
2975    }
2976
2977    fn parse_binary_expression(&mut self, min_precedence: u8, no_in: bool) -> Expr {
2978        if !self.enter() {
2979            return self.missing_expr();
2980        }
2981        let expr = self.parse_binary_inner(min_precedence, no_in);
2982        self.leave();
2983        expr
2984    }
2985
2986    fn parse_binary_inner(&mut self, min_precedence: u8, no_in: bool) -> Expr {
2987        let start = self.cur_start();
2988        let mut left = self.parse_unary_expression();
2989        loop {
2990            // TypeScript `as`/`satisfies` postfix type operators (precedence
2991            // just above relational). Disallowed across a newline.
2992            if matches!(self.kind(), TokenKind::KwAs | TokenKind::KwSatisfies)
2993                && !self.has_newline_before()
2994                && min_precedence <= 10
2995            {
2996                let is_satisfies = self.at(TokenKind::KwSatisfies);
2997                let range = self.cur().range();
2998                self.note_typescript_syntax(range);
2999                self.bump();
3000                if is_satisfies {
3001                    let type_node = self.parse_type();
3002                    left = self.node(
3003                        start,
3004                        Expression::Satisfies(SatisfiesExpression {
3005                            expression: Box::new(left),
3006                            type_node: Box::new(type_node),
3007                        }),
3008                    );
3009                } else {
3010                    let type_node = if self.at(TokenKind::KwConst) {
3011                        // `as const` is a language construct, not a type reference.
3012                        self.bump();
3013                        None
3014                    } else {
3015                        Some(Box::new(self.parse_type()))
3016                    };
3017                    left = self.node(
3018                        start,
3019                        Expression::As(AsExpression {
3020                            expression: Box::new(left),
3021                            type_node,
3022                        }),
3023                    );
3024                }
3025                continue;
3026            }
3027
3028            let Some((op, precedence)) = binary_precedence(self.kind()) else {
3029                break;
3030            };
3031            if precedence < min_precedence {
3032                break;
3033            }
3034            if no_in && self.at(TokenKind::KwIn) {
3035                break;
3036            }
3037            // `**` is right-associative, and ECMAScript forbids an
3038            // unparenthesized prefix-unary (or `await`) left operand. `self`
3039            // still points at the operator, so inspect it before consuming.
3040            let is_exponent = matches!(self.kind(), TokenKind::StarStar);
3041            if is_exponent && matches!(left.data(), Expression::Unary(_) | Expression::Await(_)) {
3042                let op_range = self.cur().range();
3043                self.error_at(
3044                    UNEXPECTED_TOKEN,
3045                    op_range,
3046                    "an unparenthesized unary expression cannot be the left operand of `**`",
3047                );
3048            }
3049            self.bump();
3050            let next_min = if is_exponent {
3051                precedence
3052            } else {
3053                precedence + 1
3054            };
3055            let right = self.parse_binary_expression(next_min, no_in);
3056            left = match op {
3057                BinaryOrLogical::Binary(operator) => self.node(
3058                    start,
3059                    Expression::Binary(BinaryExpression {
3060                        operator,
3061                        left: Box::new(left),
3062                        right: Box::new(right),
3063                    }),
3064                ),
3065                BinaryOrLogical::Logical(operator) => self.node(
3066                    start,
3067                    Expression::Logical(LogicalExpression {
3068                        operator,
3069                        left: Box::new(left),
3070                        right: Box::new(right),
3071                    }),
3072                ),
3073            };
3074        }
3075        left
3076    }
3077
3078    fn parse_unary_expression(&mut self) -> Expr {
3079        if !self.enter() {
3080            return self.missing_expr();
3081        }
3082        let expr = self.parse_unary_inner();
3083        self.leave();
3084        expr
3085    }
3086
3087    fn parse_unary_inner(&mut self) -> Expr {
3088        let start = self.cur_start();
3089        let unary = match self.kind() {
3090            TokenKind::Plus => Some(UnaryOperator::Plus),
3091            TokenKind::Minus => Some(UnaryOperator::Minus),
3092            TokenKind::Bang => Some(UnaryOperator::Not),
3093            TokenKind::Tilde => Some(UnaryOperator::BitNot),
3094            TokenKind::KwTypeof => Some(UnaryOperator::Typeof),
3095            TokenKind::KwVoid => Some(UnaryOperator::Void),
3096            TokenKind::KwDelete => Some(UnaryOperator::Delete),
3097            _ => None,
3098        };
3099        if let Some(operator) = unary {
3100            self.bump();
3101            let argument = self.parse_unary_expression();
3102            return self.node(
3103                start,
3104                Expression::Unary(UnaryExpression {
3105                    operator,
3106                    argument: Box::new(argument),
3107                }),
3108            );
3109        }
3110
3111        if matches!(self.kind(), TokenKind::PlusPlus | TokenKind::MinusMinus) {
3112            let operator = if self.at(TokenKind::PlusPlus) {
3113                UpdateOperator::Increment
3114            } else {
3115                UpdateOperator::Decrement
3116            };
3117            self.bump();
3118            let argument = self.parse_unary_expression();
3119            let target = self.expression_to_target(argument);
3120            return self.node(
3121                start,
3122                Expression::Update(UpdateExpression {
3123                    operator,
3124                    argument: Box::new(target),
3125                    prefix: true,
3126                }),
3127            );
3128        }
3129
3130        if self.at(TokenKind::KwAwait) && self.can_start_expression_after(1) {
3131            self.bump();
3132            let argument = self.parse_unary_expression();
3133            return self.node(
3134                start,
3135                Expression::Await(AwaitExpression {
3136                    argument: Box::new(argument),
3137                }),
3138            );
3139        }
3140
3141        // TypeScript `<Type>expr` assertion (never in a React source, where
3142        // `<` begins JSX).
3143        if self.at(TokenKind::LessThan)
3144            && self.is_typescript()
3145            && !matches!(self.script_kind, ScriptKind::TypeScriptReact)
3146        {
3147            return self.parse_type_assertion(start);
3148        }
3149
3150        self.parse_postfix_expression()
3151    }
3152
3153    /// Whether the `n`-th token can begin the operand of a prefix operator.
3154    fn can_start_expression_after(&self, n: usize) -> bool {
3155        !matches!(
3156            self.nth_kind(n),
3157            TokenKind::Semicolon
3158                | TokenKind::RParen
3159                | TokenKind::RBrace
3160                | TokenKind::RBracket
3161                | TokenKind::Comma
3162                | TokenKind::Colon
3163                | TokenKind::EndOfFile
3164                | TokenKind::Eq
3165        )
3166    }
3167
3168    fn parse_type_assertion(&mut self, start: Utf16Pos) -> Expr {
3169        let range = self.cur().range();
3170        self.note_typescript_syntax(range);
3171        self.expect_type_open("expected `<`");
3172        let type_node = self.parse_type();
3173        self.expect_type_close("expected `>`");
3174        let expression = self.parse_unary_expression();
3175        self.node(
3176            start,
3177            Expression::TypeAssertion(TypeAssertionExpression {
3178                expression: Box::new(expression),
3179                type_node: Box::new(type_node),
3180            }),
3181        )
3182    }
3183
3184    fn parse_postfix_expression(&mut self) -> Expr {
3185        let start = self.cur_start();
3186        let expr = self.parse_lhs_expression(false);
3187        if matches!(self.kind(), TokenKind::PlusPlus | TokenKind::MinusMinus)
3188            && !self.has_newline_before()
3189        {
3190            let operator = if self.at(TokenKind::PlusPlus) {
3191                UpdateOperator::Increment
3192            } else {
3193                UpdateOperator::Decrement
3194            };
3195            self.bump();
3196            let target = self.expression_to_target(expr);
3197            return self.node(
3198                start,
3199                Expression::Update(UpdateExpression {
3200                    operator,
3201                    argument: Box::new(target),
3202                    prefix: false,
3203                }),
3204            );
3205        }
3206        expr
3207    }
3208
3209    /// Parses a left-hand-side expression: a primary or `new` expression
3210    /// followed by member accesses, calls, non-null assertions, and template
3211    /// tags. `no_call` suppresses call parsing for a heritage/decorator head.
3212    fn parse_lhs_expression(&mut self, no_call: bool) -> Expr {
3213        let start = self.cur_start();
3214        let mut expr = if self.at(TokenKind::KwNew) {
3215            self.parse_new_expression()
3216        } else {
3217            self.parse_primary_expression()
3218        };
3219        expr = self.parse_call_and_member_tail(start, expr, no_call);
3220        expr
3221    }
3222
3223    fn parse_new_expression(&mut self) -> Expr {
3224        let start = self.cur_start();
3225        self.bump();
3226        if self.at(TokenKind::Dot) {
3227            self.bump();
3228            // `new.target`
3229            let _ = self.expect_identifier("expected `target`");
3230            return self.node(start, Expression::Meta(MetaProperty::NewTarget));
3231        }
3232        let callee = if self.at(TokenKind::KwNew) {
3233            self.parse_new_expression()
3234        } else {
3235            let primary = self.parse_primary_expression();
3236            self.parse_member_tail(start, primary)
3237        };
3238        let type_arguments = self.try_parse_type_arguments_speculative();
3239        let arguments = if self.at(TokenKind::LParen) {
3240            self.parse_arguments()
3241        } else {
3242            Vec::new()
3243        };
3244        self.node(
3245            start,
3246            Expression::New(NewExpression {
3247                callee: Box::new(callee),
3248                type_arguments,
3249                arguments,
3250            }),
3251        )
3252    }
3253
3254    /// Member-only tail (no calls): used for a `new` callee.
3255    fn parse_member_tail(&mut self, start: Utf16Pos, mut expr: Expr) -> Expr {
3256        loop {
3257            match self.kind() {
3258                TokenKind::Dot => {
3259                    self.bump();
3260                    let property = self.parse_member_property_name();
3261                    expr = self.node(
3262                        start,
3263                        Expression::Member(MemberExpression {
3264                            object: Box::new(expr),
3265                            property,
3266                            optional: false,
3267                        }),
3268                    );
3269                }
3270                TokenKind::LBracket => {
3271                    self.bump();
3272                    let index = self.parse_expression(false);
3273                    self.expect(TokenKind::RBracket, "expected `]`");
3274                    expr = self.node(
3275                        start,
3276                        Expression::Member(MemberExpression {
3277                            object: Box::new(expr),
3278                            property: MemberProperty::Computed(Box::new(index)),
3279                            optional: false,
3280                        }),
3281                    );
3282                }
3283                TokenKind::Bang if !self.has_newline_before() => {
3284                    self.bump();
3285                    expr = self.node(
3286                        start,
3287                        Expression::NonNull(NonNullExpression {
3288                            expression: Box::new(expr),
3289                        }),
3290                    );
3291                }
3292                _ => break,
3293            }
3294        }
3295        expr
3296    }
3297
3298    fn parse_call_and_member_tail(
3299        &mut self,
3300        start: Utf16Pos,
3301        mut expr: Expr,
3302        no_call: bool,
3303    ) -> Expr {
3304        loop {
3305            match self.kind() {
3306                TokenKind::Dot => {
3307                    self.bump();
3308                    let property = self.parse_member_property_name();
3309                    expr = self.node(
3310                        start,
3311                        Expression::Member(MemberExpression {
3312                            object: Box::new(expr),
3313                            property,
3314                            optional: false,
3315                        }),
3316                    );
3317                }
3318                TokenKind::QuestionDot => {
3319                    self.bump();
3320                    expr = self.parse_optional_chain_link(start, expr, no_call);
3321                }
3322                TokenKind::LBracket => {
3323                    self.bump();
3324                    let index = self.parse_expression(false);
3325                    self.expect(TokenKind::RBracket, "expected `]`");
3326                    expr = self.node(
3327                        start,
3328                        Expression::Member(MemberExpression {
3329                            object: Box::new(expr),
3330                            property: MemberProperty::Computed(Box::new(index)),
3331                            optional: false,
3332                        }),
3333                    );
3334                }
3335                TokenKind::LParen if !no_call => {
3336                    let arguments = self.parse_arguments();
3337                    expr = self.node(
3338                        start,
3339                        Expression::Call(CallExpression {
3340                            callee: Box::new(expr),
3341                            optional: false,
3342                            type_arguments: None,
3343                            arguments,
3344                        }),
3345                    );
3346                }
3347                TokenKind::Bang if !self.has_newline_before() => {
3348                    self.bump();
3349                    expr = self.node(
3350                        start,
3351                        Expression::NonNull(NonNullExpression {
3352                            expression: Box::new(expr),
3353                        }),
3354                    );
3355                }
3356                TokenKind::NoSubstitutionTemplate | TokenKind::TemplateHead => {
3357                    let template = self.parse_template_literal();
3358                    expr = self.node(
3359                        start,
3360                        Expression::TaggedTemplate(TaggedTemplateExpression {
3361                            tag: Box::new(expr),
3362                            template,
3363                        }),
3364                    );
3365                }
3366                _ if !no_call && self.at_less_like() => {
3367                    // `f<T>(...)` / `f<T>\`...\``: only a call/tagged-template
3368                    // if type arguments parse and are followed by `(` or a
3369                    // template. Otherwise this `<` is a comparison.
3370                    let Some(type_arguments) = self.try_parse_type_arguments_for_call() else {
3371                        break;
3372                    };
3373                    if self.at(TokenKind::LParen) {
3374                        let arguments = self.parse_arguments();
3375                        expr = self.node(
3376                            start,
3377                            Expression::Call(CallExpression {
3378                                callee: Box::new(expr),
3379                                optional: false,
3380                                type_arguments: Some(type_arguments),
3381                                arguments,
3382                            }),
3383                        );
3384                    } else if matches!(
3385                        self.kind(),
3386                        TokenKind::NoSubstitutionTemplate | TokenKind::TemplateHead
3387                    ) {
3388                        let template = self.parse_template_literal();
3389                        expr = self.node(
3390                            start,
3391                            Expression::TaggedTemplate(TaggedTemplateExpression {
3392                                tag: Box::new(expr),
3393                                template,
3394                            }),
3395                        );
3396                    } else {
3397                        break;
3398                    }
3399                }
3400                _ => break,
3401            }
3402        }
3403        expr
3404    }
3405
3406    fn parse_optional_chain_link(&mut self, start: Utf16Pos, expr: Expr, no_call: bool) -> Expr {
3407        match self.kind() {
3408            TokenKind::LParen if !no_call => {
3409                let arguments = self.parse_arguments();
3410                self.node(
3411                    start,
3412                    Expression::Call(CallExpression {
3413                        callee: Box::new(expr),
3414                        optional: true,
3415                        type_arguments: None,
3416                        arguments,
3417                    }),
3418                )
3419            }
3420            TokenKind::LBracket => {
3421                self.bump();
3422                let index = self.parse_expression(false);
3423                self.expect(TokenKind::RBracket, "expected `]`");
3424                self.node(
3425                    start,
3426                    Expression::Member(MemberExpression {
3427                        object: Box::new(expr),
3428                        property: MemberProperty::Computed(Box::new(index)),
3429                        optional: true,
3430                    }),
3431                )
3432            }
3433            _ if self.at_less_like() && !no_call => {
3434                if let Some(type_arguments) = self.try_parse_type_arguments_for_call() {
3435                    let arguments = self.parse_arguments();
3436                    self.node(
3437                        start,
3438                        Expression::Call(CallExpression {
3439                            callee: Box::new(expr),
3440                            optional: true,
3441                            type_arguments: Some(type_arguments),
3442                            arguments,
3443                        }),
3444                    )
3445                } else {
3446                    let property = self.parse_member_property_name();
3447                    self.node(
3448                        start,
3449                        Expression::Member(MemberExpression {
3450                            object: Box::new(expr),
3451                            property,
3452                            optional: true,
3453                        }),
3454                    )
3455                }
3456            }
3457            _ => {
3458                let property = self.parse_member_property_name();
3459                self.node(
3460                    start,
3461                    Expression::Member(MemberExpression {
3462                        object: Box::new(expr),
3463                        property,
3464                        optional: true,
3465                    }),
3466                )
3467            }
3468        }
3469    }
3470
3471    fn parse_member_property_name(&mut self) -> MemberProperty {
3472        if self.at(TokenKind::PrivateIdentifier) {
3473            let token = self.bump();
3474            let range = token.range();
3475            let node = self.node_at(range, PrivateIdentifier::new(token));
3476            return MemberProperty::Private(node);
3477        }
3478        if is_any_word(self.kind()) {
3479            let token = self.bump();
3480            return MemberProperty::Named(self.ident_from(token));
3481        }
3482        self.error_here(EXPECTED_IDENTIFIER, "expected a property name");
3483        MemberProperty::Named(self.missing_ident())
3484    }
3485
3486    fn parse_arguments(&mut self) -> Vec<CallArgument> {
3487        self.expect(TokenKind::LParen, "expected `(`");
3488        let mut arguments = Vec::new();
3489        while !self.at_eof() && !self.at(TokenKind::RParen) {
3490            let before = self.cursor;
3491            if self.at(TokenKind::DotDotDot) {
3492                let spread_start = self.cur_start();
3493                self.bump();
3494                let argument = self.parse_assignment_expression(false);
3495                arguments.push(CallArgument::Spread(SpreadElement {
3496                    argument: Box::new(argument),
3497                }));
3498                let _ = spread_start;
3499            } else {
3500                let argument = self.parse_assignment_expression(false);
3501                arguments.push(CallArgument::Expression(Box::new(argument)));
3502            }
3503            if self.eat(TokenKind::Comma).is_none() {
3504                break;
3505            }
3506            if self.cursor == before {
3507                let skipped = self.bump();
3508                self.error_at(
3509                    UNEXPECTED_TOKEN,
3510                    skipped.range(),
3511                    "this token was skipped inside an argument list",
3512                );
3513            }
3514        }
3515        self.expect(TokenKind::RParen, "expected `)`");
3516        arguments
3517    }
3518
3519    fn parse_primary_expression(&mut self) -> Expr {
3520        let start = self.cur_start();
3521        match self.kind() {
3522            TokenKind::Slash | TokenKind::SlashEq => {
3523                self.rescan_regex_here();
3524                let token = self.bump();
3525                let range = token.range();
3526                let node = self.node_at(range, RegexLiteral::new(token));
3527                self.node(start, Expression::Literal(Literal::Regex(node)))
3528            }
3529            TokenKind::KwThis => {
3530                self.bump();
3531                self.node(start, Expression::This)
3532            }
3533            TokenKind::KwSuper => {
3534                self.bump();
3535                self.node(start, Expression::Super)
3536            }
3537            TokenKind::KwTrue | TokenKind::KwFalse => {
3538                let token = self.bump();
3539                let range = token.range();
3540                let node = self.node_at(range, BooleanLiteral::new(token));
3541                self.node(start, Expression::Literal(Literal::Boolean(node)))
3542            }
3543            TokenKind::KwNull => {
3544                let token = self.bump();
3545                let range = token.range();
3546                let node = self.node_at(range, NullLiteral::new(token));
3547                self.node(start, Expression::Literal(Literal::Null(node)))
3548            }
3549            TokenKind::NumericLiteral => {
3550                let token = self.bump();
3551                let range = token.range();
3552                let node = self.node_at(range, NumericLiteral::new(token));
3553                self.node(start, Expression::Literal(Literal::Number(node)))
3554            }
3555            TokenKind::BigIntLiteral => {
3556                let token = self.bump();
3557                let range = token.range();
3558                let node = self.node_at(range, BigIntLiteral::new(token));
3559                self.node(start, Expression::Literal(Literal::BigInt(node)))
3560            }
3561            TokenKind::StringLiteral => {
3562                let node = self.parse_string_literal();
3563                self.node(start, Expression::Literal(Literal::String(node)))
3564            }
3565            TokenKind::NoSubstitutionTemplate | TokenKind::TemplateHead => {
3566                let template = self.parse_template_literal();
3567                self.node(start, Expression::Template(template))
3568            }
3569            TokenKind::LBracket => self.parse_array_literal(),
3570            TokenKind::LBrace => self.parse_object_literal(),
3571            TokenKind::LParen => {
3572                self.bump();
3573                let inner = self.parse_expression(false);
3574                self.expect(TokenKind::RParen, "expected `)`");
3575                self.node(start, Expression::Parenthesized(Box::new(inner)))
3576            }
3577            TokenKind::KwFunction => {
3578                let function = self.parse_function_like(Vec::new(), false, false);
3579                self.node(start, Expression::Function(FunctionExpression { function }))
3580            }
3581            TokenKind::KwAsync if self.nth_kind(1) == TokenKind::KwFunction => {
3582                self.bump();
3583                let function = self.parse_function_like(Vec::new(), true, false);
3584                self.node(start, Expression::Function(FunctionExpression { function }))
3585            }
3586            TokenKind::KwClass => {
3587                let class = self.parse_class(Vec::new(), DeclarationModifiers::default(), false);
3588                self.node(start, Expression::Class(ClassExpression { class }))
3589            }
3590            TokenKind::KwImport => self.parse_import_expression(start),
3591            TokenKind::PrivateIdentifier => {
3592                // `#field in obj`: represent the private name as an identifier
3593                // operand, the only expression form the node space provides.
3594                let token = self.bump();
3595                let node = self.ident_from(token);
3596                self.node(start, Expression::Identifier(node))
3597            }
3598            TokenKind::LessThan
3599                if matches!(self.script_kind, ScriptKind::TypeScriptReact)
3600                    || matches!(self.script_kind, ScriptKind::JavaScriptReact) =>
3601            {
3602                self.parse_jsx_placeholder(start)
3603            }
3604            kind if is_identifier_like(kind) => {
3605                let token = self.bump();
3606                let node = self.ident_from(token);
3607                self.node(start, Expression::Identifier(node))
3608            }
3609            _ => {
3610                self.error_here(EXPECTED_EXPRESSION, "expected an expression");
3611                self.missing_expr()
3612            }
3613        }
3614    }
3615
3616    fn parse_import_expression(&mut self, start: Utf16Pos) -> Expr {
3617        self.bump();
3618        if self.at(TokenKind::Dot) {
3619            self.bump();
3620            // `import.meta`
3621            let _ = self.expect_identifier("expected `meta`");
3622            return self.node(start, Expression::Meta(MetaProperty::ImportMeta));
3623        }
3624        self.expect(TokenKind::LParen, "expected `(`");
3625        let source = self.parse_assignment_expression(false);
3626        let options = if self.eat(TokenKind::Comma).is_some() && !self.at(TokenKind::RParen) {
3627            let opt = self.parse_assignment_expression(false);
3628            let _ = self.eat(TokenKind::Comma);
3629            Some(Box::new(opt))
3630        } else {
3631            None
3632        };
3633        self.expect(TokenKind::RParen, "expected `)`");
3634        self.node(
3635            start,
3636            Expression::Import(ImportExpression {
3637                source: Box::new(source),
3638                options,
3639            }),
3640        )
3641    }
3642
3643    /// The fixed node space has no JSX productions. A `<` opening JSX in a
3644    /// React source is diagnosed and its balanced element skipped so parsing
3645    /// makes forward progress.
3646    fn parse_jsx_placeholder(&mut self, start: Utf16Pos) -> Expr {
3647        self.error_here(
3648            UNSUPPORTED_SYNTAX,
3649            "JSX is not representable in this syntax tree",
3650        );
3651        let mut depth = 0i32;
3652        while !self.at_eof() {
3653            match self.kind() {
3654                TokenKind::LessThan => {
3655                    depth += 1;
3656                    self.bump();
3657                }
3658                TokenKind::GreaterThan | TokenKind::GreaterThanEq => {
3659                    self.bump();
3660                    depth -= 1;
3661                    if depth <= 0 {
3662                        break;
3663                    }
3664                }
3665                TokenKind::GreaterGreater | TokenKind::GreaterGreaterGreater => {
3666                    self.bump();
3667                    depth -= 2;
3668                    if depth <= 0 {
3669                        break;
3670                    }
3671                }
3672                _ => {
3673                    self.bump();
3674                }
3675            }
3676        }
3677        self.node(
3678            start,
3679            Expression::Missing(MissingNode::new(NodeKind::MissingExpression)),
3680        )
3681    }
3682
3683    fn parse_array_literal(&mut self) -> Expr {
3684        let start = self.cur_start();
3685        self.bump();
3686        let mut elements = Vec::new();
3687        while !self.at_eof() && !self.at(TokenKind::RBracket) {
3688            let before = self.cursor;
3689            if self.at(TokenKind::Comma) {
3690                self.bump();
3691                elements.push(ArrayElement::Elision);
3692                continue;
3693            }
3694            if self.at(TokenKind::DotDotDot) {
3695                let spread_start = self.cur_start();
3696                self.bump();
3697                let argument = self.parse_assignment_expression(false);
3698                elements.push(ArrayElement::Spread(SpreadElement {
3699                    argument: Box::new(argument),
3700                }));
3701                let _ = spread_start;
3702            } else {
3703                let expr = self.parse_assignment_expression(false);
3704                elements.push(ArrayElement::Expression(Box::new(expr)));
3705            }
3706            if self.eat(TokenKind::Comma).is_none() {
3707                break;
3708            }
3709            if self.cursor == before {
3710                let skipped = self.bump();
3711                self.error_at(
3712                    UNEXPECTED_TOKEN,
3713                    skipped.range(),
3714                    "this token was skipped inside an array literal",
3715                );
3716            }
3717        }
3718        self.expect(TokenKind::RBracket, "expected `]`");
3719        self.node(start, Expression::Array(ArrayLiteral { elements }))
3720    }
3721
3722    fn parse_object_literal(&mut self) -> Expr {
3723        let start = self.cur_start();
3724        self.bump();
3725        let mut members = Vec::new();
3726        while !self.at_eof() && !self.at(TokenKind::RBrace) {
3727            let before = self.cursor;
3728            let member = self.parse_object_member();
3729            members.push(member);
3730            if self.eat(TokenKind::Comma).is_none() && !self.at(TokenKind::RBrace) {
3731                self.error_here(EXPECTED_TOKEN, "expected `,`");
3732            }
3733            if self.cursor == before {
3734                let skipped = self.bump();
3735                self.error_at(
3736                    UNEXPECTED_TOKEN,
3737                    skipped.range(),
3738                    "this token was skipped inside an object literal",
3739                );
3740            }
3741        }
3742        self.expect(TokenKind::RBrace, "expected `}`");
3743        self.node(start, Expression::Object(ObjectLiteral { members }))
3744    }
3745
3746    fn parse_object_member(&mut self) -> ObjectMemberNode {
3747        let start = self.cur_start();
3748        if self.at(TokenKind::DotDotDot) {
3749            self.bump();
3750            let argument = self.parse_assignment_expression(false);
3751            return self.node(
3752                start,
3753                ObjectMember::Spread(SpreadElement {
3754                    argument: Box::new(argument),
3755                }),
3756            );
3757        }
3758
3759        let mut is_async = false;
3760        let mut is_generator = false;
3761        let mut modifier = PropertyModifier::None;
3762
3763        if self.at(TokenKind::KwAsync)
3764            && !self.has_newline_before_nth(1)
3765            && self.object_member_name_follows(1)
3766        {
3767            is_async = true;
3768            self.bump();
3769        }
3770        if self.at(TokenKind::Star) {
3771            is_generator = true;
3772            self.bump();
3773        }
3774        if matches!(self.kind(), TokenKind::KwGet | TokenKind::KwSet)
3775            && self.object_member_name_follows(1)
3776            && !is_async
3777            && !is_generator
3778        {
3779            modifier = if self.at(TokenKind::KwGet) {
3780                PropertyModifier::Get
3781            } else {
3782                PropertyModifier::Set
3783            };
3784            self.bump();
3785        }
3786
3787        let name = self.parse_property_name();
3788
3789        // Method.
3790        if self.at(TokenKind::LParen) || self.at_less_like() {
3791            let type_parameters = self.parse_optional_type_parameters();
3792            let parameters = self.parse_parameter_list();
3793            let return_type = self.parse_optional_type_annotation();
3794            let body = if self.at(TokenKind::LBrace) {
3795                Some(FunctionBody::Block(self.parse_block()))
3796            } else {
3797                self.error_here(EXPECTED_TOKEN, "expected a method body");
3798                None
3799            };
3800            return self.node(
3801                start,
3802                ObjectMember::Method(ObjectMethod {
3803                    name,
3804                    modifier,
3805                    function: FunctionLike {
3806                        decorators: Vec::new(),
3807                        name: None,
3808                        is_async,
3809                        is_generator,
3810                        type_parameters,
3811                        parameters,
3812                        return_type,
3813                        body,
3814                    },
3815                }),
3816            );
3817        }
3818
3819        // `name: value`
3820        if self.eat(TokenKind::Colon).is_some() {
3821            let value = self.parse_assignment_expression(false);
3822            return self.node(
3823                start,
3824                ObjectMember::Property(ObjectProperty {
3825                    name,
3826                    value: Box::new(value),
3827                    modifier: PropertyModifier::None,
3828                    shorthand: false,
3829                }),
3830            );
3831        }
3832
3833        // Shorthand `{ name }` or destructuring default `{ name = init }`.
3834        let value = self.shorthand_value(&name, start);
3835        self.node(
3836            start,
3837            ObjectMember::Property(ObjectProperty {
3838                name,
3839                value: Box::new(value),
3840                modifier: PropertyModifier::None,
3841                shorthand: true,
3842            }),
3843        )
3844    }
3845
3846    /// Builds the value expression of a shorthand property, folding a
3847    /// destructuring default (`{ a = 1 }`) into an assignment so a later
3848    /// conversion to a pattern can recover the initializer.
3849    fn shorthand_value(&mut self, name: &PropertyName, start: Utf16Pos) -> Expr {
3850        let ident = match name {
3851            PropertyName::Identifier(node) => {
3852                let token = *node.data().token();
3853                self.ident_from(token)
3854            }
3855            _ => self.missing_ident(),
3856        };
3857        let ident_range = ident.range();
3858        let ident_expr = self.node_at(ident_range, Expression::Identifier(ident));
3859        if self.eat(TokenKind::Eq).is_some() {
3860            let right = self.parse_assignment_expression(false);
3861            let target = self.expression_to_target(ident_expr);
3862            return self.node(
3863                start,
3864                Expression::Assignment(AssignmentExpression {
3865                    operator: AssignmentOperator::Assign,
3866                    left: target,
3867                    right: Box::new(right),
3868                }),
3869            );
3870        }
3871        ident_expr
3872    }
3873
3874    /// Whether a property name can start at the `n`-th token, used to tell an
3875    /// `async`/`get`/`set` modifier from a property literally so named.
3876    fn object_member_name_follows(&self, n: usize) -> bool {
3877        let kind = self.nth_kind(n);
3878        is_any_word(kind)
3879            || matches!(
3880                kind,
3881                TokenKind::StringLiteral
3882                    | TokenKind::NumericLiteral
3883                    | TokenKind::LBracket
3884                    | TokenKind::Star
3885            )
3886    }
3887
3888    fn parse_property_name(&mut self) -> PropertyName {
3889        match self.kind() {
3890            TokenKind::StringLiteral => PropertyName::String(self.parse_string_literal()),
3891            TokenKind::NumericLiteral => {
3892                let token = self.bump();
3893                let range = token.range();
3894                PropertyName::Number(self.node_at(range, NumericLiteral::new(token)))
3895            }
3896            TokenKind::PrivateIdentifier => {
3897                let token = self.bump();
3898                let range = token.range();
3899                PropertyName::Private(self.node_at(range, PrivateIdentifier::new(token)))
3900            }
3901            TokenKind::LBracket => {
3902                self.bump();
3903                let expr = self.parse_assignment_expression(false);
3904                self.expect(TokenKind::RBracket, "expected `]`");
3905                PropertyName::Computed(Box::new(expr))
3906            }
3907            kind if is_any_word(kind) => {
3908                let token = self.bump();
3909                PropertyName::Identifier(self.ident_from(token))
3910            }
3911            _ => {
3912                self.error_here(EXPECTED_PROPERTY_NAME, "expected a property name");
3913                PropertyName::Missing(MissingNode::new(NodeKind::Identifier))
3914            }
3915        }
3916    }
3917
3918    fn parse_template_literal(&mut self) -> TemplateLiteral {
3919        let mut elements = Vec::new();
3920        let mut expressions = Vec::new();
3921        if self.at(TokenKind::NoSubstitutionTemplate) {
3922            let token = self.bump();
3923            let range = token.range();
3924            elements.push(self.node_at(range, TemplateElement::new(token)));
3925            return TemplateLiteral {
3926                elements,
3927                expressions,
3928            };
3929        }
3930        // Head.
3931        let head = self.bump();
3932        let head_range = head.range();
3933        elements.push(self.node_at(head_range, TemplateElement::new(head)));
3934        loop {
3935            let expr = self.parse_expression(false);
3936            expressions.push(expr);
3937            match self.kind() {
3938                TokenKind::TemplateMiddle => {
3939                    let token = self.bump();
3940                    let range = token.range();
3941                    elements.push(self.node_at(range, TemplateElement::new(token)));
3942                }
3943                TokenKind::TemplateTail => {
3944                    let token = self.bump();
3945                    let range = token.range();
3946                    elements.push(self.node_at(range, TemplateElement::new(token)));
3947                    break;
3948                }
3949                TokenKind::RBrace => {
3950                    // Recovery: the scanner segmented differently (unbalanced
3951                    // braces in the substitution). Consume and continue.
3952                    let token = self.bump();
3953                    let range = token.range();
3954                    let tail = Token::new(TokenKind::TemplateTail, range);
3955                    elements.push(self.node_at(range, TemplateElement::new(tail)));
3956                    break;
3957                }
3958                _ => {
3959                    self.error_here(EXPECTED_TOKEN, "expected a template continuation");
3960                    let tail = self.missing_token(TokenKind::TemplateTail);
3961                    let range = tail.range();
3962                    elements.push(self.node_at(range, TemplateElement::new(tail)));
3963                    break;
3964                }
3965            }
3966        }
3967        TemplateLiteral {
3968            elements,
3969            expressions,
3970        }
3971    }
3972}
3973
3974// ---------------------------------------------------------------------------
3975// Bindings, functions, parameters, arrows
3976// ---------------------------------------------------------------------------
3977
3978impl Parser {
3979    fn parse_binding_pattern(&mut self) -> Pattern {
3980        let start = self.cur_start();
3981        match self.kind() {
3982            TokenKind::LBrace => self.parse_object_binding_pattern(),
3983            TokenKind::LBracket => self.parse_array_binding_pattern(),
3984            kind if is_identifier_like(kind) || kind == TokenKind::KwThis => {
3985                let token = self.bump();
3986                let name = self.ident_from(token);
3987                self.node(start, BindingPattern::Identifier(name))
3988            }
3989            _ => {
3990                self.error_here(EXPECTED_IDENTIFIER, "expected a binding");
3991                self.missing_pattern()
3992            }
3993        }
3994    }
3995
3996    fn parse_object_binding_pattern(&mut self) -> Pattern {
3997        let start = self.cur_start();
3998        self.bump();
3999        let mut properties = Vec::new();
4000        while !self.at_eof() && !self.at(TokenKind::RBrace) {
4001            let before = self.cursor;
4002            if self.at(TokenKind::DotDotDot) {
4003                self.bump();
4004                let arg_start = self.cur_start();
4005                let inner = self.parse_binding_pattern();
4006                let rest = self.node(
4007                    arg_start,
4008                    BindingPattern::Rest(RestBindingPattern {
4009                        argument: Box::new(inner),
4010                    }),
4011                );
4012                // The fixed object pattern has no rest slot; carry the rest as
4013                // a property whose name mirrors its binding for later lowering.
4014                let name = match rest.data() {
4015                    BindingPattern::Rest(rest) => match rest.argument.data() {
4016                        BindingPattern::Identifier(id) => PropertyName::Identifier(id.clone()),
4017                        _ => PropertyName::Missing(MissingNode::new(NodeKind::Identifier)),
4018                    },
4019                    _ => PropertyName::Missing(MissingNode::new(NodeKind::Identifier)),
4020                };
4021                properties.push(ObjectBindingProperty {
4022                    name,
4023                    binding: rest,
4024                    initializer: None,
4025                });
4026                let _ = self.eat(TokenKind::Comma);
4027                if self.cursor == before {
4028                    let skipped = self.bump();
4029                    self.error_at(
4030                        UNEXPECTED_TOKEN,
4031                        skipped.range(),
4032                        "this token was skipped inside a binding pattern",
4033                    );
4034                }
4035                continue;
4036            }
4037            let name = self.parse_property_name();
4038            let binding = if self.eat(TokenKind::Colon).is_some() {
4039                self.parse_binding_pattern()
4040            } else {
4041                match &name {
4042                    PropertyName::Identifier(id) => {
4043                        let range = id.range();
4044                        self.node_at(range, BindingPattern::Identifier(id.clone()))
4045                    }
4046                    _ => {
4047                        self.error_here(
4048                            EXPECTED_IDENTIFIER,
4049                            "a non-identifier binding property needs `:`",
4050                        );
4051                        self.missing_pattern()
4052                    }
4053                }
4054            };
4055            let initializer = if self.eat(TokenKind::Eq).is_some() {
4056                Some(Box::new(self.parse_assignment_expression(false)))
4057            } else {
4058                None
4059            };
4060            properties.push(ObjectBindingProperty {
4061                name,
4062                binding,
4063                initializer,
4064            });
4065            if self.eat(TokenKind::Comma).is_none() {
4066                break;
4067            }
4068            if self.cursor == before {
4069                let skipped = self.bump();
4070                self.error_at(
4071                    UNEXPECTED_TOKEN,
4072                    skipped.range(),
4073                    "this token was skipped inside a binding pattern",
4074                );
4075            }
4076        }
4077        self.expect(TokenKind::RBrace, "expected `}`");
4078        self.node(
4079            start,
4080            BindingPattern::Object(ObjectBindingPattern { properties }),
4081        )
4082    }
4083
4084    fn parse_array_binding_pattern(&mut self) -> Pattern {
4085        let start = self.cur_start();
4086        self.bump();
4087        let mut elements = Vec::new();
4088        while !self.at_eof() && !self.at(TokenKind::RBracket) {
4089            let before = self.cursor;
4090            if self.at(TokenKind::Comma) {
4091                self.bump();
4092                elements.push(ArrayBindingElement::Elision);
4093                continue;
4094            }
4095            if self.at(TokenKind::DotDotDot) {
4096                let rest_start = self.cur_start();
4097                self.bump();
4098                let inner = self.parse_binding_pattern();
4099                let rest = self.node(
4100                    rest_start,
4101                    BindingPattern::Rest(RestBindingPattern {
4102                        argument: Box::new(inner),
4103                    }),
4104                );
4105                elements.push(ArrayBindingElement::Binding(rest));
4106                let _ = self.eat(TokenKind::Comma);
4107                if self.cursor == before {
4108                    let skipped = self.bump();
4109                    self.error_at(
4110                        UNEXPECTED_TOKEN,
4111                        skipped.range(),
4112                        "this token was skipped inside a binding pattern",
4113                    );
4114                }
4115                continue;
4116            }
4117            let element_start = self.cur_start();
4118            let mut binding = self.parse_binding_pattern();
4119            if self.eat(TokenKind::Eq).is_some() {
4120                let right = self.parse_assignment_expression(false);
4121                binding = self.node(
4122                    element_start,
4123                    BindingPattern::Assignment(AssignmentBindingPattern {
4124                        left: Box::new(binding),
4125                        right: Box::new(right),
4126                    }),
4127                );
4128            }
4129            elements.push(ArrayBindingElement::Binding(binding));
4130            if self.eat(TokenKind::Comma).is_none() {
4131                break;
4132            }
4133            if self.cursor == before {
4134                let skipped = self.bump();
4135                self.error_at(
4136                    UNEXPECTED_TOKEN,
4137                    skipped.range(),
4138                    "this token was skipped inside a binding pattern",
4139                );
4140            }
4141        }
4142        self.expect(TokenKind::RBracket, "expected `]`");
4143        self.node(
4144            start,
4145            BindingPattern::Array(ArrayBindingPattern { elements }),
4146        )
4147    }
4148
4149    /// Parses a function or method: name (optional), type parameters,
4150    /// parameters, return type, and body.
4151    fn parse_function_like(
4152        &mut self,
4153        decorators: Vec<DecoratorNode>,
4154        is_async: bool,
4155        require_name: bool,
4156    ) -> FunctionLike {
4157        self.expect(TokenKind::KwFunction, "expected `function`");
4158        let is_generator = self.eat(TokenKind::Star).is_some();
4159        let name = if is_identifier_like(self.kind()) {
4160            let token = self.bump();
4161            Some(self.ident_from(token))
4162        } else {
4163            if require_name && !self.at(TokenKind::LParen) && !self.at_less_like() {
4164                self.error_here(EXPECTED_IDENTIFIER, "expected a function name");
4165            }
4166            None
4167        };
4168        let type_parameters = self.parse_optional_type_parameters();
4169        let parameters = self.parse_parameter_list();
4170        let return_type = self.parse_optional_type_annotation();
4171        let body = if self.at(TokenKind::LBrace) {
4172            Some(FunctionBody::Block(self.parse_block()))
4173        } else {
4174            self.expect_semicolon();
4175            None
4176        };
4177        FunctionLike {
4178            decorators,
4179            name,
4180            is_async,
4181            is_generator,
4182            type_parameters,
4183            parameters,
4184            return_type,
4185            body,
4186        }
4187    }
4188
4189    fn parse_parameter_list(&mut self) -> Vec<ParameterNode> {
4190        let open = if self.at(TokenKind::LBracket) {
4191            TokenKind::LBracket
4192        } else {
4193            TokenKind::LParen
4194        };
4195        let close = if open == TokenKind::LBracket {
4196            TokenKind::RBracket
4197        } else {
4198            TokenKind::RParen
4199        };
4200        self.expect(open, "expected `(`");
4201        let mut parameters = Vec::new();
4202        while !self.at_eof() && !self.at(close) {
4203            let before = self.cursor;
4204            let parameter = self.parse_parameter();
4205            parameters.push(parameter);
4206            if self.eat(TokenKind::Comma).is_none() {
4207                break;
4208            }
4209            if self.cursor == before {
4210                let skipped = self.bump();
4211                self.error_at(
4212                    UNEXPECTED_TOKEN,
4213                    skipped.range(),
4214                    "this token was skipped inside a parameter list",
4215                );
4216            }
4217        }
4218        self.expect(close, "expected `)`");
4219        parameters
4220    }
4221
4222    fn parse_parameter(&mut self) -> ParameterNode {
4223        let start = self.cur_start();
4224        let decorators = self.parse_decorators();
4225        let mut modifiers = ParameterModifiers::default();
4226        loop {
4227            if !self.parameter_modifier_follows() {
4228                break;
4229            }
4230            match self.kind() {
4231                TokenKind::KwPublic => modifiers.accessibility = Some(Accessibility::Public),
4232                TokenKind::KwProtected => modifiers.accessibility = Some(Accessibility::Protected),
4233                TokenKind::KwPrivate => modifiers.accessibility = Some(Accessibility::Private),
4234                TokenKind::KwReadonly => modifiers.is_readonly = true,
4235                TokenKind::KwOverride => modifiers.is_override = true,
4236                _ => break,
4237            }
4238            let range = self.cur().range();
4239            self.note_typescript_syntax(range);
4240            self.bump();
4241        }
4242
4243        if self.at(TokenKind::DotDotDot) {
4244            let rest_start = self.cur_start();
4245            self.bump();
4246            let inner = self.parse_binding_pattern();
4247            let optional = self.eat(TokenKind::Question).is_some();
4248            let type_annotation = self.parse_optional_type_annotation();
4249            let binding = self.node(
4250                rest_start,
4251                BindingPattern::Rest(RestBindingPattern {
4252                    argument: Box::new(inner),
4253                }),
4254            );
4255            return self.node(
4256                start,
4257                Parameter {
4258                    decorators,
4259                    modifiers,
4260                    binding,
4261                    optional,
4262                    type_annotation,
4263                    initializer: None,
4264                },
4265            );
4266        }
4267
4268        let binding = self.parse_binding_pattern();
4269        let optional = self.eat(TokenKind::Question).is_some();
4270        let type_annotation = self.parse_optional_type_annotation();
4271        let initializer = if self.eat(TokenKind::Eq).is_some() {
4272            Some(Box::new(self.parse_assignment_expression(false)))
4273        } else {
4274            None
4275        };
4276        self.node(
4277            start,
4278            Parameter {
4279                decorators,
4280                modifiers,
4281                binding,
4282                optional,
4283                type_annotation,
4284                initializer,
4285            },
4286        )
4287    }
4288
4289    fn parameter_modifier_follows(&self) -> bool {
4290        matches!(
4291            self.kind(),
4292            TokenKind::KwPublic
4293                | TokenKind::KwProtected
4294                | TokenKind::KwPrivate
4295                | TokenKind::KwReadonly
4296                | TokenKind::KwOverride
4297        ) && (is_identifier_like(self.nth_kind(1))
4298            || matches!(
4299                self.nth_kind(1),
4300                TokenKind::LBrace
4301                    | TokenKind::LBracket
4302                    | TokenKind::KwReadonly
4303                    | TokenKind::KwPublic
4304                    | TokenKind::KwProtected
4305                    | TokenKind::KwPrivate
4306                    | TokenKind::KwOverride
4307                    | TokenKind::DotDotDot
4308            ))
4309    }
4310
4311    // ------------------------------------------------------------------
4312    // Arrow functions
4313    // ------------------------------------------------------------------
4314
4315    /// Attempts every arrow-function form at an assignment start, returning
4316    /// `None` when the input is not an arrow so the caller parses a normal
4317    /// conditional expression.
4318    fn try_parse_arrow_function(&mut self, no_in: bool) -> Option<Expr> {
4319        let start = self.cur_start();
4320
4321        // `ident => body`
4322        if is_identifier_like(self.kind())
4323            && self.nth_kind(1) == TokenKind::Arrow
4324            && !self.has_newline_before_nth(1)
4325        {
4326            return Some(self.parse_simple_arrow(start, false, no_in));
4327        }
4328
4329        // `async ident => body`
4330        if self.at(TokenKind::KwAsync)
4331            && is_identifier_like(self.nth_kind(1))
4332            && self.nth_kind(2) == TokenKind::Arrow
4333            && !self.has_newline_before_nth(1)
4334            && !self.has_newline_before_nth(2)
4335        {
4336            self.bump();
4337            return Some(self.parse_simple_arrow(start, true, no_in));
4338        }
4339
4340        // `( ... ) => ...` and `( ... ): T => ...`
4341        if self.at(TokenKind::LParen) {
4342            match self.paren_arrow_follow(true) {
4343                ArrowFollow::Arrow => return Some(self.parse_paren_arrow(start, false, no_in)),
4344                ArrowFollow::Colon => {
4345                    if let Some(arrow) = self.speculate_paren_arrow(start, false, no_in) {
4346                        return Some(arrow);
4347                    }
4348                }
4349                ArrowFollow::No => {}
4350            }
4351        }
4352
4353        // `async ( ... ) => ...`
4354        if self.at(TokenKind::KwAsync)
4355            && self.nth_kind(1) == TokenKind::LParen
4356            && !self.has_newline_before_nth(1)
4357            && let Some(arrow) = self.speculate_async_paren_arrow(start, no_in)
4358        {
4359            return Some(arrow);
4360        }
4361
4362        // `<T>( ... ) => ...` generic arrow (non-React TypeScript only).
4363        if self.at_less_like()
4364            && self.is_typescript()
4365            && !matches!(self.script_kind, ScriptKind::TypeScriptReact)
4366            && let Some(arrow) = self.speculate_generic_arrow(start, false, no_in)
4367        {
4368            return Some(arrow);
4369        }
4370        if self.at(TokenKind::KwAsync)
4371            && self.nth(1).kind() == TokenKind::LessThan
4372            && self.is_typescript()
4373            && !matches!(self.script_kind, ScriptKind::TypeScriptReact)
4374            && !self.has_newline_before_nth(1)
4375            && let Some(arrow) = self.speculate_generic_arrow(start, true, no_in)
4376        {
4377            return Some(arrow);
4378        }
4379
4380        None
4381    }
4382
4383    fn parse_simple_arrow(&mut self, start: Utf16Pos, is_async: bool, no_in: bool) -> Expr {
4384        let param_start = self.cur_start();
4385        let token = self.bump();
4386        let name = self.ident_from(token);
4387        let binding = self.node(param_start, BindingPattern::Identifier(name));
4388        let parameter = self.node(
4389            param_start,
4390            Parameter {
4391                decorators: Vec::new(),
4392                modifiers: ParameterModifiers::default(),
4393                binding,
4394                optional: false,
4395                type_annotation: None,
4396                initializer: None,
4397            },
4398        );
4399        self.expect(TokenKind::Arrow, "expected `=>`");
4400        let body = self.parse_arrow_body(no_in);
4401        self.node(
4402            start,
4403            Expression::Arrow(ArrowFunction {
4404                is_async,
4405                type_parameters: None,
4406                parameters: vec![parameter],
4407                return_type: None,
4408                body,
4409            }),
4410        )
4411    }
4412
4413    fn parse_paren_arrow(&mut self, start: Utf16Pos, is_async: bool, no_in: bool) -> Expr {
4414        let parameters = self.parse_parameter_list();
4415        let return_type = self.parse_optional_type_annotation();
4416        self.expect(TokenKind::Arrow, "expected `=>`");
4417        let body = self.parse_arrow_body(no_in);
4418        self.node(
4419            start,
4420            Expression::Arrow(ArrowFunction {
4421                is_async,
4422                type_parameters: None,
4423                parameters,
4424                return_type,
4425                body,
4426            }),
4427        )
4428    }
4429
4430    fn parse_arrow_body(&mut self, no_in: bool) -> FunctionBody {
4431        if self.at(TokenKind::LBrace) {
4432            FunctionBody::Block(self.parse_block())
4433        } else {
4434            FunctionBody::Expression(Box::new(self.parse_assignment_expression(no_in)))
4435        }
4436    }
4437
4438    fn speculate_paren_arrow(
4439        &mut self,
4440        start: Utf16Pos,
4441        is_async: bool,
4442        no_in: bool,
4443    ) -> Option<Expr> {
4444        let checkpoint = self.checkpoint();
4445        let parameters = self.parse_parameter_list();
4446        let return_type = self.parse_optional_type_annotation();
4447        if !self.at(TokenKind::Arrow) || self.has_newline_before() {
4448            self.rollback(checkpoint);
4449            return None;
4450        }
4451        self.bump();
4452        let body = self.parse_arrow_body(no_in);
4453        Some(self.node(
4454            start,
4455            Expression::Arrow(ArrowFunction {
4456                is_async,
4457                type_parameters: None,
4458                parameters,
4459                return_type,
4460                body,
4461            }),
4462        ))
4463    }
4464
4465    fn speculate_async_paren_arrow(&mut self, start: Utf16Pos, no_in: bool) -> Option<Expr> {
4466        let checkpoint = self.checkpoint();
4467        self.bump(); // `async`
4468        let parameters = self.parse_parameter_list();
4469        let return_type = self.parse_optional_type_annotation();
4470        if !self.at(TokenKind::Arrow) || self.has_newline_before() {
4471            self.rollback(checkpoint);
4472            return None;
4473        }
4474        self.bump();
4475        let body = self.parse_arrow_body(no_in);
4476        Some(self.node(
4477            start,
4478            Expression::Arrow(ArrowFunction {
4479                is_async: true,
4480                type_parameters: None,
4481                parameters,
4482                return_type,
4483                body,
4484            }),
4485        ))
4486    }
4487
4488    fn speculate_generic_arrow(
4489        &mut self,
4490        start: Utf16Pos,
4491        is_async: bool,
4492        no_in: bool,
4493    ) -> Option<Expr> {
4494        let checkpoint = self.checkpoint();
4495        if is_async {
4496            self.bump();
4497        }
4498        let type_parameters = self.parse_optional_type_parameters();
4499        if !self.at(TokenKind::LParen) {
4500            self.rollback(checkpoint);
4501            return None;
4502        }
4503        let parameters = self.parse_parameter_list();
4504        let return_type = self.parse_optional_type_annotation();
4505        if !self.at(TokenKind::Arrow) || self.has_newline_before() {
4506            self.rollback(checkpoint);
4507            return None;
4508        }
4509        self.bump();
4510        let body = self.parse_arrow_body(no_in);
4511        Some(self.node(
4512            start,
4513            Expression::Arrow(ArrowFunction {
4514                is_async,
4515                type_parameters,
4516                parameters,
4517                return_type,
4518                body,
4519            }),
4520        ))
4521    }
4522
4523    /// Determines whether a `(` begins an arrow by scanning to its matching
4524    /// `)` at the token level and inspecting what follows.
4525    fn paren_arrow_follow(&self, restrict_newline: bool) -> ArrowFollow {
4526        let mut index = self.cursor;
4527        let mut depth = 0i32;
4528        loop {
4529            let token = self.tokens.get(index).copied().unwrap_or(self.eof);
4530            match token.kind() {
4531                TokenKind::LParen | TokenKind::LBracket | TokenKind::LBrace => depth += 1,
4532                TokenKind::RParen | TokenKind::RBracket | TokenKind::RBrace => {
4533                    depth -= 1;
4534                    if depth == 0 {
4535                        break;
4536                    }
4537                }
4538                TokenKind::EndOfFile => return ArrowFollow::No,
4539                _ => {}
4540            }
4541            index += 1;
4542            if index >= self.tokens.len() {
4543                return ArrowFollow::No;
4544            }
4545        }
4546        let close_end = self
4547            .tokens
4548            .get(index)
4549            .copied()
4550            .unwrap_or(self.eof)
4551            .range()
4552            .end()
4553            .get();
4554        let after = self.next_significant(index + 1);
4555        let after_token = self.tokens.get(after).copied().unwrap_or(self.eof);
4556        match after_token.kind() {
4557            TokenKind::Arrow => {
4558                // No LineTerminator may sit between an arrow's parameter list and
4559                // `=>` (a restricted production). Function types carry no such
4560                // restriction, so the type-position caller opts out.
4561                if restrict_newline
4562                    && self.newline_in_gap(close_end, after_token.range().start().get())
4563                {
4564                    ArrowFollow::No
4565                } else {
4566                    ArrowFollow::Arrow
4567                }
4568            }
4569            TokenKind::Colon => ArrowFollow::Colon,
4570            _ => ArrowFollow::No,
4571        }
4572    }
4573
4574    // ------------------------------------------------------------------
4575    // Expression-to-target conversion
4576    // ------------------------------------------------------------------
4577
4578    fn expression_to_target_for_assignment(
4579        &mut self,
4580        expr: Expr,
4581        simple: bool,
4582    ) -> AssignmentTargetNode {
4583        if simple {
4584            self.expression_to_target(expr)
4585        } else {
4586            // Compound assignment requires a simple (identifier/member) target.
4587            match expr.data() {
4588                Expression::Identifier(_) | Expression::Member(_) => {
4589                    self.expression_to_target(expr)
4590                }
4591                _ => {
4592                    let range = expr.range();
4593                    self.error_at(
4594                        INVALID_ASSIGNMENT_TARGET,
4595                        range,
4596                        "this expression is not a valid assignment target",
4597                    );
4598                    self.node_at(
4599                        range,
4600                        AssignmentTarget::Missing(MissingNode::new(
4601                            NodeKind::MissingAssignmentTarget,
4602                        )),
4603                    )
4604                }
4605            }
4606        }
4607    }
4608
4609    fn expression_to_target(&mut self, expr: Expr) -> AssignmentTargetNode {
4610        let range = expr.range();
4611        let id = expr.id();
4612        match expr.into_data() {
4613            Expression::Identifier(name) => {
4614                Node::new(id, range, AssignmentTarget::Identifier(name))
4615            }
4616            Expression::Member(member) => {
4617                if member.optional {
4618                    self.error_at(
4619                        INVALID_ASSIGNMENT_TARGET,
4620                        range,
4621                        "an optional chain is not a valid assignment target",
4622                    );
4623                    return Node::new(
4624                        id,
4625                        range,
4626                        AssignmentTarget::Missing(MissingNode::new(
4627                            NodeKind::MissingAssignmentTarget,
4628                        )),
4629                    );
4630                }
4631                Node::new(
4632                    id,
4633                    range,
4634                    AssignmentTarget::Member(AssignmentMemberTarget {
4635                        object: member.object,
4636                        property: member.property,
4637                    }),
4638                )
4639            }
4640            Expression::Parenthesized(inner) => self.expression_to_target(*inner),
4641            Expression::Array(array) => {
4642                let target = self.array_literal_to_target(array, range);
4643                Node::new(id, range, target)
4644            }
4645            Expression::Object(object) => {
4646                let target = self.object_literal_to_target(object, range);
4647                Node::new(id, range, target)
4648            }
4649            _ => {
4650                self.error_at(
4651                    INVALID_ASSIGNMENT_TARGET,
4652                    range,
4653                    "this expression is not a valid assignment target",
4654                );
4655                Node::new(
4656                    id,
4657                    range,
4658                    AssignmentTarget::Missing(MissingNode::new(NodeKind::MissingAssignmentTarget)),
4659                )
4660            }
4661        }
4662    }
4663
4664    fn array_literal_to_target(
4665        &mut self,
4666        array: ArrayLiteral,
4667        range: TextRange,
4668    ) -> AssignmentTarget {
4669        let mut elements = Vec::new();
4670        for element in array.elements {
4671            match element {
4672                ArrayElement::Elision => elements.push(AssignmentArrayElement::Elision),
4673                ArrayElement::Expression(expr) => {
4674                    let target = self.expression_to_target(*expr);
4675                    elements.push(AssignmentArrayElement::Target(target));
4676                }
4677                ArrayElement::Spread(_) => {
4678                    // A rest element has no array-target slot; diagnose and
4679                    // record a missing element rather than dropping it.
4680                    self.error_at(
4681                        INVALID_ASSIGNMENT_TARGET,
4682                        range,
4683                        "a rest element is not representable in this assignment target",
4684                    );
4685                    elements.push(AssignmentArrayElement::Missing(MissingNode::new(
4686                        NodeKind::MissingAssignmentTarget,
4687                    )));
4688                }
4689                ArrayElement::Missing(node) => {
4690                    elements.push(AssignmentArrayElement::Missing(node));
4691                }
4692            }
4693        }
4694        AssignmentTarget::Array(AssignmentArrayPattern { elements })
4695    }
4696
4697    fn object_literal_to_target(
4698        &mut self,
4699        object: ObjectLiteral,
4700        range: TextRange,
4701    ) -> AssignmentTarget {
4702        let mut properties = Vec::new();
4703        for member in object.members {
4704            let (member_range, data) = (member.range(), member.into_data());
4705            match data {
4706                ObjectMember::Property(property) => {
4707                    let (target, initializer) = self.property_value_to_target(*property.value);
4708                    properties.push(AssignmentObjectProperty {
4709                        name: property.name,
4710                        target,
4711                        initializer,
4712                    });
4713                }
4714                ObjectMember::Spread(_) | ObjectMember::Method(_) | ObjectMember::Missing(_) => {
4715                    self.error_at(
4716                        INVALID_ASSIGNMENT_TARGET,
4717                        member_range,
4718                        "this object member is not a valid assignment target",
4719                    );
4720                    properties.push(AssignmentObjectProperty {
4721                        name: PropertyName::Missing(MissingNode::new(NodeKind::Identifier)),
4722                        target: self.node_at(
4723                            member_range,
4724                            AssignmentTarget::Missing(MissingNode::new(
4725                                NodeKind::MissingAssignmentTarget,
4726                            )),
4727                        ),
4728                        initializer: None,
4729                    });
4730                }
4731            }
4732        }
4733        let _ = range;
4734        AssignmentTarget::Object(AssignmentObjectPattern { properties })
4735    }
4736
4737    /// Splits a property value into a target and an optional destructuring
4738    /// default, recovering the initializer folded into a shorthand assignment.
4739    fn property_value_to_target(
4740        &mut self,
4741        value: Expr,
4742    ) -> (AssignmentTargetNode, Option<Box<Expr>>) {
4743        if let Expression::Assignment(assignment) = value.data()
4744            && assignment.operator == AssignmentOperator::Assign
4745        {
4746            let id = value.id();
4747            let range = value.range();
4748            let Expression::Assignment(assignment) = value.into_data() else {
4749                unreachable!("assignment matched above");
4750            };
4751            let _ = (id, range);
4752            return (assignment.left, Some(assignment.right));
4753        }
4754        (self.expression_to_target(value), None)
4755    }
4756}
4757
4758/// What follows a parenthesized head, deciding arrow disambiguation.
4759#[derive(Clone, Copy)]
4760enum ArrowFollow {
4761    Arrow,
4762    Colon,
4763    No,
4764}
4765
4766// ---------------------------------------------------------------------------
4767// TypeScript types
4768// ---------------------------------------------------------------------------
4769
4770impl Parser {
4771    fn parse_type(&mut self) -> Ty {
4772        if !self.enter() {
4773            return self.missing_type();
4774        }
4775        let type_node = self.parse_conditional_type();
4776        self.leave();
4777        type_node
4778    }
4779
4780    fn parse_conditional_type(&mut self) -> Ty {
4781        let start = self.cur_start();
4782        let check_type = self.parse_union_type();
4783        if !self.at(TokenKind::KwExtends) {
4784            return check_type;
4785        }
4786        self.bump();
4787        let extends_type = self.parse_union_type();
4788        if self.eat(TokenKind::Question).is_none() {
4789            // A type parameter constraint in a malformed context: retain the
4790            // check type and leave recovery to the caller.
4791            self.error_here(EXPECTED_TOKEN, "expected `?` in a conditional type");
4792            return check_type;
4793        }
4794        let true_type = self.parse_type();
4795        self.expect(TokenKind::Colon, "expected `:`");
4796        let false_type = self.parse_type();
4797        self.node(
4798            start,
4799            TypeNode::Conditional(ConditionalType {
4800                check_type: Box::new(check_type),
4801                extends_type: Box::new(extends_type),
4802                true_type: Box::new(true_type),
4803                false_type: Box::new(false_type),
4804            }),
4805        )
4806    }
4807
4808    fn parse_union_type(&mut self) -> Ty {
4809        let start = self.cur_start();
4810        let leading = self.eat(TokenKind::Pipe).is_some();
4811        let first = self.parse_intersection_type();
4812        if !leading && !self.at(TokenKind::Pipe) {
4813            return first;
4814        }
4815        let mut types = vec![first];
4816        while self.eat(TokenKind::Pipe).is_some() {
4817            types.push(self.parse_intersection_type());
4818        }
4819        self.node(start, TypeNode::Union(types))
4820    }
4821
4822    fn parse_intersection_type(&mut self) -> Ty {
4823        let start = self.cur_start();
4824        let leading = self.eat(TokenKind::Amp).is_some();
4825        let first = self.parse_postfix_type();
4826        if !leading && !self.at(TokenKind::Amp) {
4827            return first;
4828        }
4829        let mut types = vec![first];
4830        while self.eat(TokenKind::Amp).is_some() {
4831            types.push(self.parse_postfix_type());
4832        }
4833        self.node(start, TypeNode::Intersection(types))
4834    }
4835
4836    fn parse_postfix_type(&mut self) -> Ty {
4837        let start = self.cur_start();
4838        let mut type_node = self.parse_primary_type();
4839        loop {
4840            if self.at(TokenKind::LBracket) && !self.has_newline_before() {
4841                self.bump();
4842                if self.eat(TokenKind::RBracket).is_some() {
4843                    type_node = self.node(start, TypeNode::Array(Box::new(type_node)));
4844                } else {
4845                    let index_type = self.parse_type();
4846                    self.expect(TokenKind::RBracket, "expected `]`");
4847                    type_node = self.node(
4848                        start,
4849                        TypeNode::IndexedAccess(IndexedAccessType {
4850                            object_type: Box::new(type_node),
4851                            index_type: Box::new(index_type),
4852                        }),
4853                    );
4854                }
4855            } else {
4856                break;
4857            }
4858        }
4859        type_node
4860    }
4861
4862    fn parse_primary_type(&mut self) -> Ty {
4863        let start = self.cur_start();
4864        let keyword = match self.kind() {
4865            TokenKind::KwAny => Some(KeywordType::Any),
4866            TokenKind::KwUnknown => Some(KeywordType::Unknown),
4867            TokenKind::KwNever => Some(KeywordType::Never),
4868            TokenKind::KwVoid => Some(KeywordType::Void),
4869            TokenKind::KwUndefined => Some(KeywordType::Undefined),
4870            TokenKind::KwNull => Some(KeywordType::Null),
4871            TokenKind::KwBoolean => Some(KeywordType::Boolean),
4872            TokenKind::KwNumber => Some(KeywordType::Number),
4873            TokenKind::KwBigint => Some(KeywordType::BigInt),
4874            TokenKind::KwString => Some(KeywordType::String),
4875            TokenKind::KwSymbol => Some(KeywordType::Symbol),
4876            TokenKind::KwObject => Some(KeywordType::Object),
4877            TokenKind::Identifier if self.cur_lexeme() == "intrinsic" => {
4878                Some(KeywordType::Intrinsic)
4879            }
4880            _ => None,
4881        };
4882        if let Some(keyword) = keyword {
4883            self.bump();
4884            return self.node(start, TypeNode::Keyword(keyword));
4885        }
4886
4887        match self.kind() {
4888            TokenKind::KwThis => {
4889                self.bump();
4890                self.node(start, TypeNode::This)
4891            }
4892            TokenKind::StringLiteral => {
4893                let literal = self.parse_string_literal();
4894                self.node(start, TypeNode::Literal(TypeLiteral::String(literal)))
4895            }
4896            TokenKind::NumericLiteral => {
4897                let token = self.bump();
4898                let range = token.range();
4899                let literal = self.node_at(range, NumericLiteral::new(token));
4900                self.node(start, TypeNode::Literal(TypeLiteral::Number(literal)))
4901            }
4902            TokenKind::BigIntLiteral => {
4903                let token = self.bump();
4904                let range = token.range();
4905                let literal = self.node_at(range, BigIntLiteral::new(token));
4906                self.node(start, TypeNode::Literal(TypeLiteral::BigInt(literal)))
4907            }
4908            TokenKind::KwTrue | TokenKind::KwFalse => {
4909                let token = self.bump();
4910                let range = token.range();
4911                let literal = self.node_at(range, BooleanLiteral::new(token));
4912                self.node(start, TypeNode::Literal(TypeLiteral::Boolean(literal)))
4913            }
4914            TokenKind::Minus | TokenKind::Plus => {
4915                let operator = if self.at(TokenKind::Minus) {
4916                    UnaryOperator::Minus
4917                } else {
4918                    UnaryOperator::Plus
4919                };
4920                self.bump();
4921                let operand = self.parse_primary_type();
4922                self.node(
4923                    start,
4924                    TypeNode::Literal(TypeLiteral::Unary {
4925                        operator,
4926                        operand: Box::new(operand),
4927                    }),
4928                )
4929            }
4930            TokenKind::LBracket => self.parse_tuple_type(),
4931            TokenKind::LBrace => self.parse_object_or_mapped_type(),
4932            TokenKind::LParen => self.parse_parenthesized_or_function_type(),
4933            TokenKind::LessThan | TokenKind::LessLess => self.parse_generic_function_type(),
4934            TokenKind::KwNew => self.parse_constructor_type(false),
4935            TokenKind::KwAbstract if self.nth_kind(1) == TokenKind::KwNew => {
4936                self.bump();
4937                self.parse_constructor_type(true)
4938            }
4939            TokenKind::KwTypeof => {
4940                self.bump();
4941                let name = self.parse_entity_name();
4942                let type_arguments = if self.at_less_like() {
4943                    Some(self.parse_type_arguments())
4944                } else {
4945                    None
4946                };
4947                self.node(
4948                    start,
4949                    TypeNode::Query(TypeQuery {
4950                        name,
4951                        type_arguments,
4952                    }),
4953                )
4954            }
4955            TokenKind::KwKeyof | TokenKind::KwUnique | TokenKind::KwReadonly => {
4956                let operator = match self.kind() {
4957                    TokenKind::KwKeyof => TypeOperator::Keyof,
4958                    TokenKind::KwUnique => TypeOperator::Unique,
4959                    _ => TypeOperator::Readonly,
4960                };
4961                self.bump();
4962                let operand = self.parse_primary_type();
4963                self.node(
4964                    start,
4965                    TypeNode::Operator {
4966                        operator,
4967                        operand: Box::new(operand),
4968                    },
4969                )
4970            }
4971            TokenKind::KwInfer => {
4972                self.bump();
4973                let parameter = self.parse_type_parameter();
4974                self.node(start, TypeNode::Infer(InferType { parameter }))
4975            }
4976            TokenKind::KwImport => self.parse_import_type(start),
4977            TokenKind::NoSubstitutionTemplate | TokenKind::TemplateHead => {
4978                self.parse_template_literal_type(start)
4979            }
4980            TokenKind::KwAsserts => self.parse_asserts_predicate(start),
4981            kind if is_identifier_like(kind) => {
4982                let name = self.parse_entity_name();
4983                // `x is T` predicate in a return type.
4984                if self.eat(TokenKind::KwIs).is_some() {
4985                    let type_node = self.parse_type();
4986                    return self.node(
4987                        start,
4988                        TypeNode::Predicate(TypePredicate {
4989                            asserts: false,
4990                            parameter_name: name,
4991                            type_node: Some(Box::new(type_node)),
4992                        }),
4993                    );
4994                }
4995                let type_arguments = if self.at_less_like() {
4996                    Some(self.parse_type_arguments())
4997                } else {
4998                    None
4999                };
5000                self.node(
5001                    start,
5002                    TypeNode::Reference(TypeReference {
5003                        name,
5004                        type_arguments,
5005                    }),
5006                )
5007            }
5008            _ => {
5009                self.error_here(EXPECTED_TYPE, "expected a type");
5010                self.missing_type()
5011            }
5012        }
5013    }
5014
5015    fn parse_tuple_type(&mut self) -> Ty {
5016        let start = self.cur_start();
5017        self.bump();
5018        let mut elements = Vec::new();
5019        while !self.at_eof() && !self.at(TokenKind::RBracket) {
5020            let before = self.cursor;
5021            let rest = self.eat(TokenKind::DotDotDot).is_some();
5022            // Named tuple element `name?: Type`.
5023            let (name, optional) = if is_identifier_like(self.kind())
5024                && matches!(self.nth_kind(1), TokenKind::Colon | TokenKind::Question)
5025            {
5026                let token = self.bump();
5027                let name = Some(self.ident_from(token));
5028                let optional = self.eat(TokenKind::Question).is_some();
5029                self.expect(TokenKind::Colon, "expected `:`");
5030                (name, optional)
5031            } else {
5032                (None, false)
5033            };
5034            let type_node = self.parse_type();
5035            let optional = optional || self.eat(TokenKind::Question).is_some();
5036            elements.push(TupleElement {
5037                name,
5038                optional,
5039                rest,
5040                type_node: Box::new(type_node),
5041            });
5042            if self.eat(TokenKind::Comma).is_none() {
5043                break;
5044            }
5045            if self.cursor == before {
5046                let skipped = self.bump();
5047                self.error_at(
5048                    UNEXPECTED_TOKEN,
5049                    skipped.range(),
5050                    "this token was skipped inside a tuple type",
5051                );
5052            }
5053        }
5054        self.expect(TokenKind::RBracket, "expected `]`");
5055        self.node(
5056            start,
5057            TypeNode::Tuple(TupleType {
5058                readonly: false,
5059                elements,
5060            }),
5061        )
5062    }
5063
5064    fn parse_object_or_mapped_type(&mut self) -> Ty {
5065        let start = self.cur_start();
5066        if self.looks_like_mapped_type() {
5067            return self.parse_mapped_type(start);
5068        }
5069        let members = self.parse_type_members();
5070        self.node(start, TypeNode::Object(ObjectType { members }))
5071    }
5072
5073    fn looks_like_mapped_type(&self) -> bool {
5074        if !self.at(TokenKind::LBrace) {
5075            return false;
5076        }
5077        let mut n = 1;
5078        if matches!(self.nth_kind(n), TokenKind::Plus | TokenKind::Minus) {
5079            n += 1;
5080        }
5081        if self.nth_kind(n) == TokenKind::KwReadonly {
5082            n += 1;
5083        }
5084        self.nth_kind(n) == TokenKind::LBracket
5085            && is_identifier_like(self.nth_kind(n + 1))
5086            && self.nth_kind(n + 2) == TokenKind::KwIn
5087    }
5088
5089    fn parse_mapped_type(&mut self, start: Utf16Pos) -> Ty {
5090        self.bump(); // `{`
5091        let readonly_modifier = self.parse_mapped_modifier(TokenKind::KwReadonly);
5092        self.expect(TokenKind::LBracket, "expected `[` in a mapped type");
5093        let parameter = self.parse_mapped_parameter();
5094        let name_type = if self.eat(TokenKind::KwAs).is_some() {
5095            Some(Box::new(self.parse_type()))
5096        } else {
5097            None
5098        };
5099        self.expect(TokenKind::RBracket, "expected `]`");
5100        let optional_modifier = self.parse_mapped_modifier(TokenKind::Question);
5101        let value_type = if self.eat(TokenKind::Colon).is_some() {
5102            Some(Box::new(self.parse_type()))
5103        } else {
5104            None
5105        };
5106        let _ = self.eat(TokenKind::Semicolon);
5107        self.expect(TokenKind::RBrace, "expected `}`");
5108        self.node(
5109            start,
5110            TypeNode::Mapped(MappedType {
5111                readonly_modifier,
5112                parameter,
5113                name_type,
5114                optional_modifier,
5115                value_type,
5116            }),
5117        )
5118    }
5119
5120    fn parse_mapped_modifier(&mut self, marker: TokenKind) -> MappedModifier {
5121        if self.at(marker) {
5122            self.bump();
5123            return MappedModifier::Add;
5124        }
5125        if self.at(TokenKind::Plus) && self.nth_kind(1) == marker {
5126            self.bump();
5127            self.bump();
5128            return MappedModifier::Add;
5129        }
5130        if self.at(TokenKind::Minus) && self.nth_kind(1) == marker {
5131            self.bump();
5132            self.bump();
5133            return MappedModifier::Remove;
5134        }
5135        MappedModifier::Preserve
5136    }
5137
5138    fn parse_mapped_parameter(&mut self) -> TypeParameterNode {
5139        let start = self.cur_start();
5140        let name = self.expect_identifier("expected a mapped type parameter");
5141        self.expect(TokenKind::KwIn, "expected `in`");
5142        let constraint = Some(Box::new(self.parse_type()));
5143        self.node(
5144            start,
5145            TypeParameter {
5146                name,
5147                variance: Variance::Invariant,
5148                constraint,
5149                default: None,
5150            },
5151        )
5152    }
5153
5154    fn parse_parenthesized_or_function_type(&mut self) -> Ty {
5155        let start = self.cur_start();
5156        if matches!(self.paren_arrow_follow(false), ArrowFollow::Arrow) {
5157            let parameters = self.parse_function_type_parameters();
5158            self.expect(TokenKind::Arrow, "expected `=>`");
5159            let return_type = self.parse_type();
5160            return self.node(
5161                start,
5162                TypeNode::Function(FunctionType {
5163                    type_parameters: None,
5164                    parameters,
5165                    return_type: Box::new(return_type),
5166                }),
5167            );
5168        }
5169        self.bump();
5170        let inner = self.parse_type();
5171        self.expect(TokenKind::RParen, "expected `)`");
5172        self.node(start, TypeNode::Parenthesized(Box::new(inner)))
5173    }
5174
5175    fn parse_generic_function_type(&mut self) -> Ty {
5176        let start = self.cur_start();
5177        let type_parameters = self.parse_optional_type_parameters();
5178        let parameters = self.parse_function_type_parameters();
5179        self.expect(TokenKind::Arrow, "expected `=>`");
5180        let return_type = self.parse_type();
5181        self.node(
5182            start,
5183            TypeNode::Function(FunctionType {
5184                type_parameters,
5185                parameters,
5186                return_type: Box::new(return_type),
5187            }),
5188        )
5189    }
5190
5191    fn parse_constructor_type(&mut self, is_abstract: bool) -> Ty {
5192        let start = self.cur_start();
5193        self.expect(TokenKind::KwNew, "expected `new`");
5194        let type_parameters = self.parse_optional_type_parameters();
5195        let parameters = self.parse_function_type_parameters();
5196        self.expect(TokenKind::Arrow, "expected `=>`");
5197        let return_type = self.parse_type();
5198        self.node(
5199            start,
5200            TypeNode::Constructor(ConstructorType {
5201                is_abstract,
5202                function: FunctionType {
5203                    type_parameters,
5204                    parameters,
5205                    return_type: Box::new(return_type),
5206                },
5207            }),
5208        )
5209    }
5210
5211    fn parse_function_type_parameters(&mut self) -> Vec<FunctionTypeParameter> {
5212        self.expect(TokenKind::LParen, "expected `(`");
5213        let mut parameters = Vec::new();
5214        while !self.at_eof() && !self.at(TokenKind::RParen) {
5215            let before = self.cursor;
5216            let rest = self.eat(TokenKind::DotDotDot).is_some();
5217            let name = if is_identifier_like(self.kind()) || self.at(TokenKind::KwThis) {
5218                let token = self.bump();
5219                self.ident_from(token)
5220            } else if matches!(self.kind(), TokenKind::LBrace | TokenKind::LBracket) {
5221                self.skip_balanced_pattern();
5222                self.missing_ident()
5223            } else {
5224                self.error_here(EXPECTED_IDENTIFIER, "expected a parameter name");
5225                self.missing_ident()
5226            };
5227            let optional = self.eat(TokenKind::Question).is_some();
5228            let type_annotation = if let Some(annotation) = self.parse_optional_type_annotation() {
5229                annotation
5230            } else {
5231                self.missing_type_annotation()
5232            };
5233            parameters.push(FunctionTypeParameter {
5234                name,
5235                optional,
5236                rest,
5237                type_annotation,
5238            });
5239            if self.eat(TokenKind::Comma).is_none() {
5240                break;
5241            }
5242            if self.cursor == before {
5243                let skipped = self.bump();
5244                self.error_at(
5245                    UNEXPECTED_TOKEN,
5246                    skipped.range(),
5247                    "this token was skipped inside a function type",
5248                );
5249            }
5250        }
5251        self.expect(TokenKind::RParen, "expected `)`");
5252        parameters
5253    }
5254
5255    fn skip_balanced_pattern(&mut self) {
5256        let open = self.kind();
5257        let close = if open == TokenKind::LBrace {
5258            TokenKind::RBrace
5259        } else {
5260            TokenKind::RBracket
5261        };
5262        let mut depth = 0i32;
5263        while !self.at_eof() {
5264            if self.kind() == open {
5265                depth += 1;
5266            } else if self.kind() == close {
5267                depth -= 1;
5268                self.bump();
5269                if depth <= 0 {
5270                    return;
5271                }
5272                continue;
5273            }
5274            self.bump();
5275        }
5276    }
5277
5278    fn parse_import_type(&mut self, start: Utf16Pos) -> Ty {
5279        self.bump();
5280        self.expect(TokenKind::LParen, "expected `(`");
5281        let argument = self.parse_string_literal();
5282        let attributes = if self.eat(TokenKind::Comma).is_some() {
5283            // `import("x", { with: {...} })`: the AST stores attributes only.
5284            if self.at(TokenKind::LBrace) {
5285                self.bump();
5286                let attrs = if self.at(TokenKind::KwWith)
5287                    || (is_identifier_like(self.kind()) && self.cur_lexeme() == "with")
5288                {
5289                    self.bump();
5290                    self.expect(TokenKind::Colon, "expected `:`");
5291                    self.parse_attribute_object()
5292                } else {
5293                    ImportAttributes::default()
5294                };
5295                while !self.at_eof() && !self.at(TokenKind::RBrace) {
5296                    self.bump();
5297                }
5298                self.expect(TokenKind::RBrace, "expected `}`");
5299                Some(attrs)
5300            } else {
5301                None
5302            }
5303        } else {
5304            None
5305        };
5306        self.expect(TokenKind::RParen, "expected `)`");
5307        let qualifier = if self.eat(TokenKind::Dot).is_some() {
5308            Some(self.parse_entity_name())
5309        } else {
5310            None
5311        };
5312        let type_arguments = if self.at_less_like() {
5313            Some(self.parse_type_arguments())
5314        } else {
5315            None
5316        };
5317        self.node(
5318            start,
5319            TypeNode::Import(ImportType {
5320                argument,
5321                qualifier,
5322                type_arguments,
5323                attributes,
5324            }),
5325        )
5326    }
5327
5328    fn parse_attribute_object(&mut self) -> ImportAttributes {
5329        self.expect(TokenKind::LBrace, "expected `{`");
5330        let mut entries = Vec::new();
5331        while !self.at_eof() && !self.at(TokenKind::RBrace) {
5332            let name = self.parse_module_export_name();
5333            self.expect(TokenKind::Colon, "expected `:`");
5334            let value = self.parse_string_literal();
5335            entries.push(ImportAttribute { name, value });
5336            if self.eat(TokenKind::Comma).is_none() {
5337                break;
5338            }
5339        }
5340        self.expect(TokenKind::RBrace, "expected `}`");
5341        ImportAttributes { entries }
5342    }
5343
5344    fn parse_template_literal_type(&mut self, start: Utf16Pos) -> Ty {
5345        let mut elements = Vec::new();
5346        let mut types = Vec::new();
5347        if self.at(TokenKind::NoSubstitutionTemplate) {
5348            let token = self.bump();
5349            let range = token.range();
5350            elements.push(self.node_at(range, TemplateElement::new(token)));
5351        } else {
5352            let head = self.bump();
5353            let range = head.range();
5354            elements.push(self.node_at(range, TemplateElement::new(head)));
5355            loop {
5356                types.push(self.parse_type());
5357                if self.at(TokenKind::TemplateMiddle) {
5358                    let token = self.bump();
5359                    let range = token.range();
5360                    elements.push(self.node_at(range, TemplateElement::new(token)));
5361                } else if self.at(TokenKind::TemplateTail) {
5362                    let token = self.bump();
5363                    let range = token.range();
5364                    elements.push(self.node_at(range, TemplateElement::new(token)));
5365                    break;
5366                } else {
5367                    self.error_here(EXPECTED_TOKEN, "expected a template continuation");
5368                    break;
5369                }
5370            }
5371        }
5372        self.node(
5373            start,
5374            TypeNode::TemplateLiteral(TemplateLiteralType { elements, types }),
5375        )
5376    }
5377
5378    fn parse_asserts_predicate(&mut self, start: Utf16Pos) -> Ty {
5379        self.bump();
5380        let parameter_name = if self.at(TokenKind::KwThis) {
5381            let token = self.bump();
5382            EntityName::Identifier(self.ident_from(token))
5383        } else {
5384            self.parse_entity_name()
5385        };
5386        let type_node = if self.eat(TokenKind::KwIs).is_some() {
5387            Some(Box::new(self.parse_type()))
5388        } else {
5389            None
5390        };
5391        self.node(
5392            start,
5393            TypeNode::Predicate(TypePredicate {
5394                asserts: true,
5395                parameter_name,
5396                type_node,
5397            }),
5398        )
5399    }
5400
5401    // ------------------------------------------------------------------
5402    // Type parameters, arguments, names, members
5403    // ------------------------------------------------------------------
5404
5405    fn parse_optional_type_parameters(&mut self) -> Option<TypeParameterList> {
5406        if !self.at_less_like() {
5407            return None;
5408        }
5409        let range = self.cur().range();
5410        self.note_typescript_syntax(range);
5411        self.expect_type_open("expected `<`");
5412        let mut parameters = Vec::new();
5413        while !self.at_eof() && !self.at_greater_like() {
5414            let before = self.cursor;
5415            parameters.push(self.parse_type_parameter());
5416            if self.eat(TokenKind::Comma).is_none() {
5417                break;
5418            }
5419            if self.cursor == before {
5420                let skipped = self.bump();
5421                self.error_at(
5422                    UNEXPECTED_TOKEN,
5423                    skipped.range(),
5424                    "this token was skipped inside type parameters",
5425                );
5426            }
5427        }
5428        self.expect_type_close("expected `>`");
5429        Some(TypeParameterList { parameters })
5430    }
5431
5432    fn parse_type_parameter(&mut self) -> TypeParameterNode {
5433        let start = self.cur_start();
5434        // `in`/`out` are variance modifiers only when a type-parameter name
5435        // still follows; `out` is a contextual identifier, not a keyword. The
5436        // combined `in out` form is accepted for recovery even though current
5437        // TypeScript rejects it.
5438        let variance = if self.at(TokenKind::KwIn)
5439            && self.nth(1).kind() == TokenKind::Identifier
5440            && self.lexeme(self.nth(1)) == "out"
5441            && is_identifier_like(self.nth_kind(2))
5442        {
5443            self.bump();
5444            self.bump();
5445            Variance::InOut
5446        } else if self.at(TokenKind::KwIn) && is_identifier_like(self.nth_kind(1)) {
5447            self.bump();
5448            Variance::In
5449        } else if self.at(TokenKind::Identifier)
5450            && self.cur_lexeme() == "out"
5451            && is_identifier_like(self.nth_kind(1))
5452        {
5453            self.bump();
5454            Variance::Out
5455        } else {
5456            Variance::Invariant
5457        };
5458        let name = self.expect_identifier("expected a type parameter name");
5459        let constraint = if self.eat(TokenKind::KwExtends).is_some() {
5460            Some(Box::new(self.parse_type()))
5461        } else {
5462            None
5463        };
5464        let default = if self.eat(TokenKind::Eq).is_some() {
5465            Some(Box::new(self.parse_type()))
5466        } else {
5467            None
5468        };
5469        self.node(
5470            start,
5471            TypeParameter {
5472                name,
5473                variance,
5474                constraint,
5475                default,
5476            },
5477        )
5478    }
5479
5480    fn parse_type_arguments(&mut self) -> TypeArgumentList {
5481        self.expect_type_open("expected `<`");
5482        let mut arguments = Vec::new();
5483        while !self.at_eof() && !self.at_greater_like() {
5484            let before = self.cursor;
5485            arguments.push(self.parse_type());
5486            if self.eat(TokenKind::Comma).is_none() {
5487                break;
5488            }
5489            if self.cursor == before {
5490                let skipped = self.bump();
5491                self.error_at(
5492                    UNEXPECTED_TOKEN,
5493                    skipped.range(),
5494                    "this token was skipped inside type arguments",
5495                );
5496            }
5497        }
5498        self.expect_type_close("expected `>`");
5499        TypeArgumentList { arguments }
5500    }
5501
5502    /// Speculative type arguments for `new`/heritage-like expression sites.
5503    fn try_parse_type_arguments_speculative(&mut self) -> Option<TypeArgumentList> {
5504        if !self.at_less_like() {
5505            return None;
5506        }
5507        let checkpoint = self.checkpoint();
5508        let diagnostics = self.diagnostics.len();
5509        let args = self.parse_type_arguments();
5510        if self.diagnostics.len() != diagnostics {
5511            self.rollback(checkpoint);
5512            return None;
5513        }
5514        Some(args)
5515    }
5516
5517    /// Speculative type arguments that must be followed by a call or tagged
5518    /// template to avoid stealing a relational `<` expression.
5519    fn try_parse_type_arguments_for_call(&mut self) -> Option<TypeArgumentList> {
5520        if !self.at_less_like() {
5521            return None;
5522        }
5523        let checkpoint = self.checkpoint();
5524        let diagnostics = self.diagnostics.len();
5525        let args = self.parse_type_arguments();
5526        let follows = matches!(
5527            self.kind(),
5528            TokenKind::LParen | TokenKind::NoSubstitutionTemplate | TokenKind::TemplateHead
5529        );
5530        if !follows || self.diagnostics.len() != diagnostics {
5531            self.rollback(checkpoint);
5532            return None;
5533        }
5534        Some(args)
5535    }
5536
5537    fn parse_entity_name(&mut self) -> EntityName {
5538        if !is_any_word(self.kind()) {
5539            self.error_here(EXPECTED_IDENTIFIER, "expected a type name");
5540            return EntityName::Missing(MissingNode::new(NodeKind::Identifier));
5541        }
5542        let token = self.bump();
5543        let mut name = EntityName::Identifier(self.ident_from(token));
5544        while self.eat(TokenKind::Dot).is_some() {
5545            let right = self.expect_identifier("expected a qualified name");
5546            name = EntityName::Qualified {
5547                left: Box::new(name),
5548                right,
5549            };
5550        }
5551        name
5552    }
5553
5554    fn parse_type_members(&mut self) -> Vec<TypeMemberNode> {
5555        self.expect(TokenKind::LBrace, "expected `{`");
5556        let mut members = Vec::new();
5557        while !self.at_eof() && !self.at(TokenKind::RBrace) {
5558            let before = self.cursor;
5559            members.push(self.parse_type_member());
5560            if self.eat(TokenKind::Semicolon).is_none()
5561                && self.eat(TokenKind::Comma).is_none()
5562                && !self.at(TokenKind::RBrace)
5563                && !self.has_newline_before()
5564            {
5565                self.error_here(EXPECTED_TOKEN, "expected `;` or `,`");
5566            }
5567            if self.cursor == before {
5568                let skipped = self.bump();
5569                self.error_at(
5570                    UNEXPECTED_TOKEN,
5571                    skipped.range(),
5572                    "this token was skipped inside a type body",
5573                );
5574            }
5575        }
5576        self.expect(TokenKind::RBrace, "expected `}`");
5577        members
5578    }
5579
5580    fn parse_type_member(&mut self) -> TypeMemberNode {
5581        let start = self.cur_start();
5582
5583        // Call signature `<T>(...): R` / `(...): R`.
5584        if self.at(TokenKind::LParen) || self.at_less_like() {
5585            let function = self.parse_function_type_signature(false);
5586            return self.node(start, TypeMember::Call(CallSignature { function }));
5587        }
5588
5589        // Construct signature `new (...): T`.
5590        if self.at(TokenKind::KwNew)
5591            && matches!(self.nth_kind(1), TokenKind::LParen | TokenKind::LessThan)
5592        {
5593            self.bump();
5594            let function = self.parse_function_type_signature(true);
5595            return self.node(
5596                start,
5597                TypeMember::Construct(ConstructSignature {
5598                    function: ConstructorType {
5599                        is_abstract: false,
5600                        function,
5601                    },
5602                }),
5603            );
5604        }
5605
5606        let readonly = self.eat(TokenKind::KwReadonly).is_some();
5607        if readonly {
5608            self.note_typescript_syntax(self.span_from(start));
5609        }
5610
5611        // Index signature.
5612        if self.at(TokenKind::LBracket) && self.at_index_signature() {
5613            let parameters = self.parse_function_type_parameters_bracketed();
5614            let type_annotation = self.parse_optional_type_annotation().unwrap_or_else(|| {
5615                self.error_here(EXPECTED_TOKEN, "an index signature requires a type");
5616                self.missing_type_annotation()
5617            });
5618            return self.node(
5619                start,
5620                TypeMember::Index(TypeIndexSignature {
5621                    readonly,
5622                    parameters,
5623                    type_annotation,
5624                }),
5625            );
5626        }
5627
5628        let name = self.parse_property_name();
5629        let optional = self.eat(TokenKind::Question).is_some();
5630        if self.at(TokenKind::LParen) || self.at_less_like() {
5631            let function = self.parse_function_type_signature(false);
5632            return self.node(
5633                start,
5634                TypeMember::Method(TypeMethodSignature {
5635                    name,
5636                    optional,
5637                    function,
5638                }),
5639            );
5640        }
5641        let type_annotation = self.parse_optional_type_annotation();
5642        self.node(
5643            start,
5644            TypeMember::Property(TypePropertySignature {
5645                readonly,
5646                name,
5647                optional,
5648                type_annotation,
5649            }),
5650        )
5651    }
5652
5653    fn parse_function_type_signature(&mut self, constructor: bool) -> FunctionType {
5654        let type_parameters = self.parse_optional_type_parameters();
5655        let parameters = self.parse_function_type_parameters();
5656        let return_type = if constructor {
5657            if self.eat(TokenKind::Colon).is_some() {
5658                self.parse_type()
5659            } else {
5660                self.error_here(EXPECTED_TOKEN, "expected `:`");
5661                self.missing_type()
5662            }
5663        } else if self.eat(TokenKind::Colon).is_some() || self.eat(TokenKind::Arrow).is_some() {
5664            self.parse_type()
5665        } else {
5666            self.error_here(EXPECTED_TOKEN, "expected a return type");
5667            self.missing_type()
5668        };
5669        FunctionType {
5670            type_parameters,
5671            parameters,
5672            return_type: Box::new(return_type),
5673        }
5674    }
5675
5676    fn parse_function_type_parameters_bracketed(&mut self) -> Vec<FunctionTypeParameter> {
5677        self.expect(TokenKind::LBracket, "expected `[` ");
5678        let mut parameters = Vec::new();
5679        while !self.at_eof() && !self.at(TokenKind::RBracket) {
5680            let rest = self.eat(TokenKind::DotDotDot).is_some();
5681            let name = self.expect_identifier("expected a parameter name");
5682            let optional = self.eat(TokenKind::Question).is_some();
5683            let type_annotation = self.parse_optional_type_annotation().unwrap_or_else(|| {
5684                self.error_here(EXPECTED_TOKEN, "expected a parameter type");
5685                self.missing_type_annotation()
5686            });
5687            parameters.push(FunctionTypeParameter {
5688                name,
5689                optional,
5690                rest,
5691                type_annotation,
5692            });
5693            if self.eat(TokenKind::Comma).is_none() {
5694                break;
5695            }
5696        }
5697        self.expect(TokenKind::RBracket, "expected `]`");
5698        parameters
5699    }
5700}
5701
5702#[cfg(test)]
5703mod tests {
5704    use super::*;
5705    use crate::diagnostic::DiagnosticSeverity;
5706    use crate::scanner::scan;
5707
5708    fn parse_text(text: &str, script_kind: ScriptKind) -> Recovered<SourceFile> {
5709        let source = Arc::new(SourceText::new(text));
5710        let scanned = scan(SourceId::new(0), script_kind, source);
5711        parse(scanned)
5712    }
5713
5714    fn parse_ts(text: &str) -> Recovered<SourceFile> {
5715        parse_text(text, ScriptKind::TypeScript)
5716    }
5717
5718    fn errors(recovered: &Recovered<SourceFile>) -> Vec<&Diagnostic> {
5719        recovered
5720            .diagnostics()
5721            .iter()
5722            .filter(|d| d.severity() == DiagnosticSeverity::Error)
5723            .collect()
5724    }
5725
5726    fn assert_clean(text: &str) -> Recovered<SourceFile> {
5727        let recovered = parse_ts(text);
5728        let errs = errors(&recovered);
5729        assert!(
5730            errs.is_empty(),
5731            "expected no errors for {text:?}, got: {:?}",
5732            errs.iter()
5733                .map(|d| (d.code().as_str(), d.message()))
5734                .collect::<Vec<_>>()
5735        );
5736        recovered
5737    }
5738
5739    fn stmt_kind(recovered: &Recovered<SourceFile>, index: usize) -> NodeKind {
5740        recovered.product().statements()[index].kind()
5741    }
5742
5743    /// Every significant (non-trivia) token in the file must tile the source
5744    /// contiguously, proving rescans preserved the covering property.
5745    fn assert_tokens_tile(recovered: &Recovered<SourceFile>) {
5746        let file = recovered.product();
5747        let mut pos = 0usize;
5748        for token in file.tokens() {
5749            let range = token.range();
5750            assert!(
5751                range.start().get() >= pos,
5752                "token overlaps or regresses at {}",
5753                range.start().get()
5754            );
5755            assert!(
5756                range.start().get() <= range.end().get(),
5757                "token range inverted"
5758            );
5759            pos = range.end().get();
5760        }
5761        assert!(
5762            pos <= file.source_text().len_utf16().get(),
5763            "tokens extend past the source"
5764        );
5765    }
5766
5767    #[test]
5768    fn parses_variable_declaration() {
5769        let recovered = assert_clean("const x: number = 1;");
5770        assert_eq!(stmt_kind(&recovered, 0), NodeKind::VariableDeclaration);
5771        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
5772            panic!("expected a variable declaration");
5773        };
5774        assert_eq!(decl.kind, VariableKind::Const);
5775        assert_eq!(decl.declarations.len(), 1);
5776        assert!(decl.declarations[0].data().type_annotation.is_some());
5777    }
5778
5779    #[test]
5780    fn preserves_all_scanner_tokens_and_eof() {
5781        let text = "let a = 1; // trailing\n";
5782        let source = Arc::new(SourceText::new(text));
5783        let scanned = scan(SourceId::new(0), ScriptKind::TypeScript, source);
5784        let scanned_token_count = scanned.product().tokens().len();
5785        let recovered = parse(scanned);
5786        // No rescans here, so the stored stream matches the scanner's exactly.
5787        assert_eq!(recovered.product().tokens().len(), scanned_token_count);
5788        assert_eq!(recovered.product().eof().kind(), TokenKind::EndOfFile);
5789        assert!(
5790            recovered
5791                .product()
5792                .tokens()
5793                .iter()
5794                .any(|t| t.kind() == TokenKind::LineComment)
5795        );
5796    }
5797
5798    #[test]
5799    fn diagnostics_are_ordered_and_shared() {
5800        let recovered = parse_ts("const = ;");
5801        let diagnostics = recovered.diagnostics();
5802        assert!(!diagnostics.is_empty());
5803        // The SourceFile carries the identical canonical diagnostic vector.
5804        assert_eq!(recovered.product().diagnostics(), diagnostics);
5805        let mut sorted = diagnostics.to_vec();
5806        sorted.sort();
5807        assert_eq!(sorted.as_slice(), diagnostics);
5808    }
5809
5810    #[test]
5811    fn unions_lexical_and_parse_diagnostics() {
5812        // Unterminated string is a lexical (L-code) diagnostic; the trailing
5813        // `+` with no operand is a parse (P-code) diagnostic.
5814        let recovered = parse_ts("const s = \"oops\n + ;");
5815        let codes: Vec<&str> = recovered
5816            .diagnostics()
5817            .iter()
5818            .map(|d| d.code().as_str())
5819            .collect();
5820        assert!(codes.iter().any(|c| c.starts_with("BAMTS-L")));
5821        assert!(codes.iter().any(|c| c.starts_with("BAMTS-P")));
5822    }
5823
5824    #[test]
5825    fn source_kind_identity_is_preserved() {
5826        for kind in [
5827            ScriptKind::JavaScript,
5828            ScriptKind::TypeScript,
5829            ScriptKind::TypeScriptReact,
5830            ScriptKind::Json,
5831        ] {
5832            let recovered = parse_text("const x = 1;", kind);
5833            assert_eq!(recovered.product().script_kind(), kind);
5834            assert_eq!(recovered.product().source_id(), SourceId::new(0));
5835        }
5836    }
5837
5838    #[test]
5839    fn regex_rescan_produces_literal() {
5840        let recovered = assert_clean("const r = /a[/]b/gi;");
5841        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
5842            panic!("expected a variable declaration");
5843        };
5844        let init = decl.declarations[0]
5845            .data()
5846            .initializer
5847            .as_ref()
5848            .expect("initializer");
5849        assert!(matches!(
5850            init.data(),
5851            Expression::Literal(Literal::Regex(_))
5852        ));
5853        // The rescan merged the covered tokens into one literal token.
5854        assert!(
5855            recovered
5856                .product()
5857                .tokens()
5858                .iter()
5859                .any(|t| t.kind() == TokenKind::RegularExpressionLiteral)
5860        );
5861        assert_tokens_tile(&recovered);
5862    }
5863
5864    #[test]
5865    fn division_is_not_a_regex() {
5866        let recovered = assert_clean("const q = a / b / c;");
5867        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
5868            panic!("expected a variable declaration");
5869        };
5870        let init = decl.declarations[0]
5871            .data()
5872            .initializer
5873            .as_ref()
5874            .expect("initializer");
5875        assert!(matches!(
5876            init.data(),
5877            Expression::Binary(b) if b.operator == BinaryOperator::Divide
5878        ));
5879    }
5880
5881    #[test]
5882    fn generic_call_versus_comparison() {
5883        let call = assert_clean("f<number>(1);");
5884        let Statement::Expression(stmt) = call.product().statements()[0].data() else {
5885            panic!("expected an expression statement");
5886        };
5887        let Expression::Call(c) = stmt.expression.data() else {
5888            panic!("expected a call, got {:?}", stmt.expression.kind());
5889        };
5890        assert!(c.type_arguments.is_some());
5891
5892        // `a < b > c` is two comparisons, never a call.
5893        let cmp = assert_clean("const t = a < b > c;");
5894        let Statement::Variable(decl) = cmp.product().statements()[0].data() else {
5895            panic!("expected a variable declaration");
5896        };
5897        let init = decl.declarations[0]
5898            .data()
5899            .initializer
5900            .as_ref()
5901            .expect("initializer");
5902        assert!(matches!(init.data(), Expression::Binary(_)));
5903    }
5904
5905    #[test]
5906    fn greater_than_split_closes_nested_generics() {
5907        let recovered = assert_clean("let m: Map<string, Array<number>> = x;");
5908        assert_eq!(stmt_kind(&recovered, 0), NodeKind::VariableDeclaration);
5909        assert_tokens_tile(&recovered);
5910    }
5911
5912    #[test]
5913    fn parses_arrow_functions() {
5914        assert_clean("const f = (a: number, b: number): number => a + b;");
5915        assert_clean("const g = x => x * 2;");
5916        assert_clean("const h = async (x) => { await x; };");
5917        let generic = assert_clean("const id = <T>(x: T): T => x;");
5918        let Statement::Variable(decl) = generic.product().statements()[0].data() else {
5919            panic!("expected a variable declaration");
5920        };
5921        let init = decl.declarations[0]
5922            .data()
5923            .initializer
5924            .as_ref()
5925            .expect("initializer");
5926        assert!(matches!(init.data(), Expression::Arrow(_)));
5927    }
5928
5929    #[test]
5930    fn conditional_versus_arrow_return_type() {
5931        // `(x): T => ...` here would fail arrow speculation because there is
5932        // no `=>`, so it stays a parenthesized conditional.
5933        let recovered = assert_clean("const v = cond ? (a) : (b);");
5934        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
5935            panic!("expected a variable declaration");
5936        };
5937        let init = decl.declarations[0]
5938            .data()
5939            .initializer
5940            .as_ref()
5941            .expect("initializer");
5942        assert!(matches!(init.data(), Expression::Conditional(_)));
5943    }
5944
5945    #[test]
5946    fn parses_template_and_tagged_template() {
5947        let recovered = assert_clean("const s = `a${1 + 2}b${x}c`;");
5948        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
5949            panic!("expected a variable declaration");
5950        };
5951        let init = decl.declarations[0]
5952            .data()
5953            .initializer
5954            .as_ref()
5955            .expect("initializer");
5956        let Expression::Template(template) = init.data() else {
5957            panic!("expected a template literal");
5958        };
5959        assert_eq!(template.elements.len(), 3);
5960        assert_eq!(template.expressions.len(), 2);
5961        assert_clean("tag`x${y}z`;");
5962    }
5963
5964    #[test]
5965    fn parses_class_with_members() {
5966        let recovered = assert_clean(
5967            "class C<T> extends B implements I {\n\
5968             #private = 1;\n\
5969             static count = 0;\n\
5970             readonly name: string = \"c\";\n\
5971             constructor(public x: number) { this.x = x; }\n\
5972             get value(): T { return this.#private as unknown as T; }\n\
5973             set value(v: T) {}\n\
5974             method<U>(a: U): void {}\n\
5975             static { count = 1; }\n\
5976             [key: string]: unknown;\n\
5977             }",
5978        );
5979        let Statement::Class(class) = recovered.product().statements()[0].data() else {
5980            panic!("expected a class declaration");
5981        };
5982        assert!(class.extends.is_some());
5983        assert_eq!(class.implements.len(), 1);
5984        assert!(
5985            class
5986                .members
5987                .iter()
5988                .any(|m| matches!(m.data(), ClassMember::Constructor(_)))
5989        );
5990        assert!(
5991            class
5992                .members
5993                .iter()
5994                .any(|m| matches!(m.data(), ClassMember::StaticBlock(_)))
5995        );
5996        assert!(
5997            class
5998                .members
5999                .iter()
6000                .any(|m| matches!(m.data(), ClassMember::IndexSignature(_)))
6001        );
6002    }
6003
6004    #[test]
6005    fn parses_decorated_class() {
6006        let recovered = assert_clean("@sealed class C {\n@log method(@inject p: string) {}\n}");
6007        let Statement::Class(class) = recovered.product().statements()[0].data() else {
6008            panic!("expected a class declaration");
6009        };
6010        assert_eq!(class.decorators.len(), 1);
6011    }
6012
6013    #[test]
6014    fn parses_interface_and_type_alias() {
6015        assert_clean(
6016            "interface Shape<T> extends Base {\n\
6017             readonly id: number;\n\
6018             name?: string;\n\
6019             (x: number): T;\n\
6020             new (x: number): T;\n\
6021             [key: string]: unknown;\n\
6022             method(a: T): void;\n\
6023             }",
6024        );
6025        assert_clean("type Alias<T> = { [K in keyof T]?: T[K] };");
6026        assert_clean("type Cond<T> = T extends string ? true : false;");
6027        assert_clean("type Tpl = `prefix-${string}`;");
6028        assert_clean("type U = A | B & C | D[];");
6029        assert_clean("type Fn = <T>(a: T, ...rest: number[]) => T;");
6030        assert_clean("type Ctor = abstract new (x: number) => object;");
6031        assert_clean("type Q = typeof globalThis;");
6032        assert_clean("type Idx = Array<string>[number];");
6033    }
6034
6035    #[test]
6036    fn parses_enum_and_namespace() {
6037        let recovered = assert_clean(
6038            "enum Color { Red, Green = 2, Blue }\nnamespace A.B { export const x = 1; }",
6039        );
6040        assert_eq!(stmt_kind(&recovered, 0), NodeKind::EnumDeclaration);
6041        assert_eq!(stmt_kind(&recovered, 1), NodeKind::NamespaceDeclaration);
6042        // The dotted namespace desugars into a nested single-name namespace.
6043        let Statement::Namespace(outer) = recovered.product().statements()[1].data() else {
6044            panic!("expected a namespace");
6045        };
6046        assert!(matches!(
6047            outer.body.data().statements[0].data(),
6048            Statement::Namespace(_)
6049        ));
6050        assert_clean("const enum E { A, B }");
6051    }
6052
6053    #[test]
6054    fn parses_imports_and_exports() {
6055        assert_clean("import defaultExport, { a, b as c, type T } from \"mod\";");
6056        assert_clean("import * as ns from \"mod\";");
6057        assert_clean("import type { Only } from \"mod\";");
6058        assert_clean("import \"side-effect\";");
6059        assert_clean("import json from \"./x.json\" with { type: \"json\" };");
6060        assert_clean("import lib = require(\"lib\");");
6061        assert_clean("export { a, b as c };");
6062        assert_clean("export * as ns from \"mod\";");
6063        assert_clean("export default function () {}");
6064        assert_clean("export const value = 1;");
6065        assert_clean("export type { T } from \"mod\";");
6066        assert_clean("export = someValue;");
6067    }
6068
6069    #[test]
6070    fn parses_control_flow_and_loops() {
6071        assert_clean(
6072            "for (let i = 0; i < 10; i++) {}\n\
6073             for (const x of xs) {}\n\
6074             for (const k in obj) {}\n\
6075             for await (const y of gen()) {}\n\
6076             while (a) {}\n\
6077             do {} while (b);\n\
6078             switch (n) { case 1: break; default: break; }\n\
6079             try { f(); } catch (e) { g(); } finally { h(); }\n\
6080             label: for (;;) { continue label; }",
6081        );
6082    }
6083
6084    #[test]
6085    fn parses_destructuring_and_assignment() {
6086        assert_clean("const { a, b: { c }, d = 1, ...rest } = obj;");
6087        assert_clean("const [x, , y = 2, ...zs] = arr;");
6088        assert_clean("({ a, b } = source);");
6089        assert_clean("[first, second] = pair;");
6090        assert_clean("obj.prop ??= fallback;");
6091    }
6092
6093    #[test]
6094    fn parses_optional_chaining_and_nonnull() {
6095        assert_clean("const v = a?.b?.[c]?.(d)!.e;");
6096        assert_clean("const w = obj!.field;");
6097    }
6098
6099    #[test]
6100    fn parses_as_const_and_satisfies() {
6101        assert_clean("const config = { a: 1 } as const;");
6102        assert_clean("const point = { x: 0 } satisfies Point;");
6103        assert_clean("const n = value as unknown as number;");
6104    }
6105
6106    #[test]
6107    fn parses_new_meta_and_import_expressions() {
6108        assert_clean("const a = new Foo<number>(1, 2);");
6109        assert_clean("function f() { return new.target; }");
6110        assert_clean("const m = import.meta.url;");
6111        assert_clean("const p = import(\"mod\");");
6112    }
6113
6114    #[test]
6115    fn asi_allows_missing_semicolons() {
6116        let recovered = assert_clean("const a = 1\nconst b = 2\nreturn\na");
6117        // `return` then `a` on the next line are two statements (ASI).
6118        assert!(recovered.product().statements().len() >= 3);
6119    }
6120
6121    #[test]
6122    fn typescript_syntax_in_javascript_is_diagnosed() {
6123        let recovered = parse_text("const x: number = 1;", ScriptKind::JavaScript);
6124        assert!(
6125            recovered
6126                .diagnostics()
6127                .iter()
6128                .any(|d| d.code() == TYPESCRIPT_SYNTAX_IN_JAVASCRIPT)
6129        );
6130        // Recovery still produced a variable declaration.
6131        assert_eq!(stmt_kind(&recovered, 0), NodeKind::VariableDeclaration);
6132    }
6133
6134    #[test]
6135    fn jsx_in_react_source_is_diagnosed_not_panicking() {
6136        let recovered = parse_text(
6137            "const el = <div className=\"x\">hi</div>;",
6138            ScriptKind::TypeScriptReact,
6139        );
6140        assert!(
6141            recovered
6142                .diagnostics()
6143                .iter()
6144                .any(|d| d.code() == UNSUPPORTED_SYNTAX)
6145        );
6146    }
6147
6148    #[test]
6149    fn recovers_from_garbage_with_progress() {
6150        // Pure garbage must terminate, emit diagnostics, and tile tokens.
6151        let recovered = parse_ts("@#$%^&");
6152        assert!(!errors(&recovered).is_empty());
6153        assert_tokens_tile(&recovered);
6154        // A missing close brace still yields a block statement.
6155        let unbalanced = parse_ts("function f() { if (a) {");
6156        assert!(!errors(&unbalanced).is_empty());
6157        assert_eq!(unbalanced.product().eof().kind(), TokenKind::EndOfFile);
6158    }
6159
6160    #[test]
6161    fn deeply_nested_input_does_not_overflow() {
6162        let text = format!("const x = {}1{};", "(".repeat(5000), ")".repeat(5000));
6163        let recovered = parse_ts(&text);
6164        // The depth guard converts excessive nesting into diagnostics rather
6165        // than a stack overflow, and the parser still terminates.
6166        assert!(
6167            recovered
6168                .diagnostics()
6169                .iter()
6170                .any(|d| d.code() == NESTING_TOO_DEEP)
6171        );
6172        assert_eq!(recovered.product().eof().kind(), TokenKind::EndOfFile);
6173    }
6174
6175    #[test]
6176    fn deeply_nested_list_is_iterative() {
6177        // A long flat argument list must not recurse per element.
6178        let args = "0,".repeat(20000);
6179        let text = format!("f({args}0);");
6180        let recovered = parse_ts(&text);
6181        assert!(
6182            errors(&recovered).is_empty(),
6183            "flat list should parse cleanly"
6184        );
6185    }
6186
6187    #[test]
6188    fn missing_binding_is_diagnosed() {
6189        let recovered = parse_ts("const = 1;");
6190        assert!(
6191            errors(&recovered)
6192                .iter()
6193                .any(|d| d.code() == EXPECTED_IDENTIFIER)
6194        );
6195        assert_eq!(stmt_kind(&recovered, 0), NodeKind::VariableDeclaration);
6196    }
6197
6198    #[test]
6199    fn empty_source_parses() {
6200        let recovered = parse_ts("");
6201        assert!(recovered.product().statements().is_empty());
6202        assert!(errors(&recovered).is_empty());
6203        assert_eq!(recovered.product().eof().kind(), TokenKind::EndOfFile);
6204    }
6205
6206    #[test]
6207    fn parses_using_declarations() {
6208        assert_clean("{ using handle = acquire(); }");
6209        assert_clean("async function f() { await using h = acquire(); }");
6210    }
6211
6212    #[test]
6213    fn full_range_spans_source() {
6214        let text = "const x = 1;\nconst y = 2;\n";
6215        let recovered = parse_ts(text);
6216        let range = recovered.product().range();
6217        assert_eq!(range.start(), Utf16Pos::ZERO);
6218        assert_eq!(range.end(), recovered.product().source_text().len_utf16());
6219    }
6220
6221    #[test]
6222    fn exponentiation_is_right_associative() {
6223        let recovered = assert_clean("const x = 2 ** 3 ** 2;");
6224        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
6225            panic!("expected a variable declaration");
6226        };
6227        let init = decl.declarations[0]
6228            .data()
6229            .initializer
6230            .as_ref()
6231            .expect("initializer");
6232        let Expression::Binary(outer) = init.data() else {
6233            panic!("expected a binary expression, got {:?}", init.kind());
6234        };
6235        assert_eq!(outer.operator, BinaryOperator::Exponentiate);
6236        // Right-associative: the right operand is itself `3 ** 2`, and the left
6237        // operand is the atom `2`, never a nested exponentiation.
6238        let Expression::Binary(right) = outer.right.data() else {
6239            panic!("expected the right operand to be `3 ** 2`");
6240        };
6241        assert_eq!(right.operator, BinaryOperator::Exponentiate);
6242        assert!(!matches!(outer.left.data(), Expression::Binary(_)));
6243    }
6244
6245    #[test]
6246    fn unary_left_operand_of_exponent_is_rejected() {
6247        // ECMAScript forbids an unparenthesized unary on the left of `**`.
6248        let neg = parse_ts("const x = -2 ** 2;");
6249        assert!(
6250            errors(&neg).iter().any(|d| d.code() == UNEXPECTED_TOKEN),
6251            "expected a diagnostic for `-2 ** 2`"
6252        );
6253        let awaited = parse_ts("async function f() { return await p ** 2; }");
6254        assert!(
6255            errors(&awaited)
6256                .iter()
6257                .any(|d| d.code() == UNEXPECTED_TOKEN),
6258            "expected a diagnostic for `await p ** 2`"
6259        );
6260        // Parenthesizing restores validity, and a unary on the right is allowed.
6261        assert_clean("const y = (-2) ** 2;");
6262        assert_clean("const z = 2 ** -3;");
6263    }
6264
6265    #[test]
6266    fn parses_typed_using_declaration() {
6267        let recovered = assert_clean("using handle: Disposable = acquire();");
6268        let Statement::Variable(decl) = recovered.product().statements()[0].data() else {
6269            panic!(
6270                "expected a using declaration, got {:?}",
6271                stmt_kind(&recovered, 0)
6272            );
6273        };
6274        assert_eq!(decl.kind, VariableKind::Using);
6275        assert!(decl.declarations[0].data().type_annotation.is_some());
6276        // `await using` with a type annotation, and an object/generic type whose
6277        // brackets contain a `;` that must not end the disambiguation scan early.
6278        assert_clean("async function f() { await using h: AsyncDisposable = acquire(); }");
6279        let nested = assert_clean("using o: { a: number; b: string } = make();");
6280        let Statement::Variable(decl) = nested.product().statements()[0].data() else {
6281            panic!("expected a using declaration");
6282        };
6283        assert_eq!(decl.kind, VariableKind::Using);
6284        assert!(decl.declarations[0].data().type_annotation.is_some());
6285    }
6286
6287    #[test]
6288    fn using_as_identifier_is_not_a_declaration() {
6289        // A non-binding after `using` keeps it an ordinary expression.
6290        let member = assert_clean("using.dispose = handle;");
6291        assert!(matches!(
6292            member.product().statements()[0].data(),
6293            Statement::Expression(_)
6294        ));
6295        let bare = assert_clean("using;");
6296        assert!(matches!(
6297            bare.product().statements()[0].data(),
6298            Statement::Expression(_)
6299        ));
6300        // A newline before the binding defeats the contextual keyword (ASI).
6301        let split = assert_clean("using\nx = 1;");
6302        assert!(matches!(
6303            split.product().statements()[0].data(),
6304            Statement::Expression(_)
6305        ));
6306        // A `:` with no top-level `=` is not a typed declaration either.
6307        let no_init = parse_ts("using x: number;");
6308        assert!(matches!(
6309            no_init.product().statements()[0].data(),
6310            Statement::Expression(_)
6311        ));
6312    }
6313
6314    #[test]
6315    fn arrow_requires_no_newline_before_fat_arrow() {
6316        // Same line is a valid arrow, including the typed and generic forms.
6317        assert_clean("const f = (a) => a;");
6318        assert_clean("const g = (a): number => a;");
6319        assert_clean("const gen = <T>(x: T) => x;");
6320        // A newline before `=>` breaks the restricted production: `(a)` is a
6321        // parenthesized expression, not an arrow, and the dangling `=>` errors.
6322        let broken = parse_ts("const f = (a)\n=> a;");
6323        assert!(
6324            !errors(&broken).is_empty(),
6325            "a newline before `=>` must not parse as an arrow"
6326        );
6327        let Statement::Variable(decl) = broken.product().statements()[0].data() else {
6328            panic!("expected a variable declaration");
6329        };
6330        let init = decl.declarations[0]
6331            .data()
6332            .initializer
6333            .as_ref()
6334            .expect("initializer");
6335        assert!(matches!(init.data(), Expression::Parenthesized(_)));
6336        // The typed and generic speculative paths reject a newline as well.
6337        assert!(!errors(&parse_ts("const h = (a: number)\n=> a;")).is_empty());
6338        assert!(!errors(&parse_ts("const i = <T>(x: T)\n=> x;")).is_empty());
6339        assert!(!errors(&parse_ts("const j = async (x)\n=> x;")).is_empty());
6340    }
6341
6342    #[test]
6343    fn deeply_nested_hostile_expression_recovers() {
6344        // A prefix-unary chain previously recursed once per operator and would
6345        // overflow the native stack; the depth budget now bounds it to a stable
6346        // diagnostic and the parse still terminates at end-of-file.
6347        let unary = format!("const a = {}1;", "-".repeat(20_000));
6348        let ru = parse_ts(&unary);
6349        assert!(
6350            ru.diagnostics()
6351                .iter()
6352                .any(|d| d.code() == NESTING_TOO_DEEP),
6353            "the depth budget must fire on a deep unary chain"
6354        );
6355        assert_eq!(ru.product().eof().kind(), TokenKind::EndOfFile);
6356
6357        // The right-recursive `**` operator likewise recurses per operator.
6358        let exp = format!("const b = {}2;", "2 ** ".repeat(20_000));
6359        let re = parse_ts(&exp);
6360        assert!(
6361            re.diagnostics()
6362                .iter()
6363                .any(|d| d.code() == NESTING_TOO_DEEP),
6364            "the depth budget must fire on a deep `**` chain"
6365        );
6366        assert_eq!(re.product().eof().kind(), TokenKind::EndOfFile);
6367
6368        // All guarded edges combined: unary, `**`, and parentheses at once.
6369        let combo = format!(
6370            "const c = {}{}{}1{};",
6371            "-".repeat(5_000),
6372            "2 ** ".repeat(5_000),
6373            "(".repeat(5_000),
6374            ")".repeat(5_000),
6375        );
6376        let rc = parse_ts(&combo);
6377        assert!(
6378            rc.diagnostics()
6379                .iter()
6380                .any(|d| d.code() == NESTING_TOO_DEEP),
6381            "the depth budget must fire on combined hostile nesting"
6382        );
6383        assert_eq!(rc.product().eof().kind(), TokenKind::EndOfFile);
6384    }
6385}