1use 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
86const EXPECTED_TOKEN: DiagnosticCode = DiagnosticCode::new("BAMTS-P001");
88const EXPECTED_EXPRESSION: DiagnosticCode = DiagnosticCode::new("BAMTS-P002");
90const EXPECTED_IDENTIFIER: DiagnosticCode = DiagnosticCode::new("BAMTS-P003");
92const EXPECTED_TYPE: DiagnosticCode = DiagnosticCode::new("BAMTS-P004");
94const UNEXPECTED_TOKEN: DiagnosticCode = DiagnosticCode::new("BAMTS-P005");
96const INVALID_ASSIGNMENT_TARGET: DiagnosticCode = DiagnosticCode::new("BAMTS-P006");
98const TYPESCRIPT_SYNTAX_IN_JAVASCRIPT: DiagnosticCode = DiagnosticCode::new("BAMTS-P007");
100const UNSUPPORTED_SYNTAX: DiagnosticCode = DiagnosticCode::new("BAMTS-P008");
102const EXPECTED_PROPERTY_NAME: DiagnosticCode = DiagnosticCode::new("BAMTS-P009");
104const NESTING_TOO_DEEP: DiagnosticCode = DiagnosticCode::new("BAMTS-P010");
106const UNTERMINATED_REGEX: DiagnosticCode = DiagnosticCode::new("BAMTS-L004");
108
109const MAX_DEPTH: u32 = 256;
121
122#[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 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
182struct RescanEdit {
185 index: usize,
186 removed: Vec<Token>,
187 inserted: usize,
188}
189
190#[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 cursor: usize,
208 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
239fn 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
290fn 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 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 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 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 fn has_newline_before(&self) -> bool {
466 self.newline_in_gap(self.prev_end, self.cur_start().get())
467 }
468
469 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 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 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 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 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 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 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 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 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 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 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 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 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 fn at_less_like(&self) -> bool {
862 matches!(
863 self.kind(),
864 TokenKind::LessThan | TokenKind::LessLess | TokenKind::LessLessEq
865 )
866 }
867
868 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 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
915impl Parser {
920 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 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 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 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 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 self.bump();
1207 VariableKind::AwaitUsing
1208 }
1209 _ => {
1210 self.bump();
1212 VariableKind::Using
1213 }
1214 }
1215 }
1216
1217 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 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 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 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 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 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 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 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 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
1753impl 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 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 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 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 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 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 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 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 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 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 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 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 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
2275impl Parser {
2280 fn parse_import_statement(&mut self, start: Utf16Pos) -> Stmt {
2281 self.bump();
2282
2283 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 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 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 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 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 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 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 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 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 if self.at(TokenKind::LBrace) {
2569 return self.parse_export_specifiers(start, false);
2570 }
2571
2572 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 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 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 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
2793fn 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
3974impl 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 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 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 fn try_parse_arrow_function(&mut self, no_in: bool) -> Option<Expr> {
4319 let start = self.cur_start();
4320
4321 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 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 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 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 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(); 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 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 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 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 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 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 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#[derive(Clone, Copy)]
4760enum ArrowFollow {
4761 Arrow,
4762 Colon,
4763 No,
4764}
4765
4766impl 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 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 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 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(); 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 let recovered = parse_ts("@#$%^&");
6152 assert!(!errors(&recovered).is_empty());
6153 assert_tokens_tile(&recovered);
6154 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 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 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 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 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 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 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 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 let split = assert_clean("using\nx = 1;");
6302 assert!(matches!(
6303 split.product().statements()[0].data(),
6304 Statement::Expression(_)
6305 ));
6306 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 assert_clean("const f = (a) => a;");
6318 assert_clean("const g = (a): number => a;");
6319 assert_clean("const gen = <T>(x: T) => x;");
6320 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 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 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 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 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}