• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "TSparser.h"
17 
18 #include "parser/parserStatusContext.h"
19 #include "macros.h"
20 #include "parserFlags.h"
21 #include "util/helpers.h"
22 #include "varbinder/privateBinding.h"
23 #include "varbinder/scope.h"
24 #include "varbinder/tsBinding.h"
25 #include "lexer/TSLexer.h"
26 #include "ir/base/spreadElement.h"
27 #include "ir/base/decorator.h"
28 #include "ir/base/classElement.h"
29 #include "ir/base/classDefinition.h"
30 #include "ir/base/methodDefinition.h"
31 #include "ir/base/scriptFunction.h"
32 #include "ir/module/importDefaultSpecifier.h"
33 #include "ir/module/exportDefaultDeclaration.h"
34 #include "ir/module/exportAllDeclaration.h"
35 #include "ir/module/exportNamedDeclaration.h"
36 #include "ir/module/importDeclaration.h"
37 #include "ir/expressions/memberExpression.h"
38 #include "ir/expressions/sequenceExpression.h"
39 #include "ir/expressions/templateLiteral.h"
40 #include "ir/expressions/taggedTemplateExpression.h"
41 #include "ir/expressions/callExpression.h"
42 #include "ir/expressions/functionExpression.h"
43 #include "ir/expressions/arrowFunctionExpression.h"
44 #include "ir/expressions/yieldExpression.h"
45 #include "ir/expressions/assignmentExpression.h"
46 #include "ir/expressions/identifier.h"
47 #include "ir/expressions/objectExpression.h"
48 #include "ir/expressions/arrayExpression.h"
49 #include "ir/expressions/literals/bigIntLiteral.h"
50 #include "ir/expressions/literals/booleanLiteral.h"
51 #include "ir/expressions/literals/nullLiteral.h"
52 #include "ir/expressions/literals/numberLiteral.h"
53 #include "ir/expressions/literals/stringLiteral.h"
54 #include "ir/statements/emptyStatement.h"
55 #include "ir/statements/blockStatement.h"
56 #include "ir/statements/ifStatement.h"
57 #include "ir/statements/doWhileStatement.h"
58 #include "ir/statements/whileStatement.h"
59 #include "ir/statements/tryStatement.h"
60 #include "ir/statements/breakStatement.h"
61 #include "ir/statements/continueStatement.h"
62 #include "ir/statements/throwStatement.h"
63 #include "ir/statements/switchStatement.h"
64 #include "ir/statements/returnStatement.h"
65 #include "ir/statements/debuggerStatement.h"
66 #include "ir/statements/classDeclaration.h"
67 #include "ir/statements/labelledStatement.h"
68 #include "ir/statements/variableDeclarator.h"
69 #include "ir/statements/functionDeclaration.h"
70 #include "ir/ts/tsLiteralType.h"
71 #include "ir/ts/tsMappedType.h"
72 #include "ir/ts/tsImportType.h"
73 #include "ir/ts/tsThisType.h"
74 #include "ir/ts/tsConditionalType.h"
75 #include "ir/ts/tsTypeOperator.h"
76 #include "ir/ts/tsInferType.h"
77 #include "ir/ts/tsTupleType.h"
78 #include "ir/ts/tsNamedTupleMember.h"
79 #include "ir/ts/tsQualifiedName.h"
80 #include "ir/ts/tsIndexedAccessType.h"
81 #include "ir/ts/tsTypeQuery.h"
82 #include "ir/ts/tsTypeReference.h"
83 #include "ir/ts/tsTypePredicate.h"
84 #include "ir/ts/tsTypeLiteral.h"
85 #include "ir/ts/tsArrayType.h"
86 #include "ir/ts/tsUnionType.h"
87 #include "ir/ts/tsIntersectionType.h"
88 #include "ir/ts/tsAnyKeyword.h"
89 #include "ir/ts/tsUndefinedKeyword.h"
90 #include "ir/ts/tsVoidKeyword.h"
91 #include "ir/ts/tsNumberKeyword.h"
92 #include "ir/ts/tsStringKeyword.h"
93 #include "ir/ts/tsBooleanKeyword.h"
94 #include "ir/ts/tsBigintKeyword.h"
95 #include "ir/ts/tsUnknownKeyword.h"
96 #include "ir/ts/tsNullKeyword.h"
97 #include "ir/ts/tsNeverKeyword.h"
98 #include "ir/ts/tsObjectKeyword.h"
99 #include "ir/ts/tsFunctionType.h"
100 #include "ir/ts/tsConstructorType.h"
101 #include "ir/ts/tsParenthesizedType.h"
102 #include "ir/ts/tsTypeAssertion.h"
103 #include "ir/ts/tsAsExpression.h"
104 #include "ir/ts/tsNonNullExpression.h"
105 #include "ir/ts/tsEnumDeclaration.h"
106 #include "ir/ts/tsInterfaceDeclaration.h"
107 #include "ir/ts/tsTypeAliasDeclaration.h"
108 #include "ir/ts/tsModuleDeclaration.h"
109 #include "ir/ts/tsTypeParameterInstantiation.h"
110 #include "ir/ts/tsInterfaceHeritage.h"
111 #include "ir/base/tsSignatureDeclaration.h"
112 #include "ir/base/tsIndexSignature.h"
113 #include "ir/base/tsMethodSignature.h"
114 #include "ir/base/tsPropertySignature.h"
115 #include "ir/ts/tsParameterProperty.h"
116 #include "ir/ts/tsClassImplements.h"
117 #include "ir/ts/tsImportEqualsDeclaration.h"
118 #include "ir/ts/tsExternalModuleReference.h"
119 
120 namespace ark::es2panda::parser {
InitLexer(const SourceFile & sourceFile)121 std::unique_ptr<lexer::Lexer> TSParser::InitLexer(const SourceFile &sourceFile)
122 {
123     GetProgram()->SetSource(sourceFile);
124     auto lexer = std::make_unique<lexer::TSLexer>(&GetContext(), ErrorLogger());
125     SetLexer(lexer.get());
126     return lexer;
127 }
128 
ParseDecorator()129 ir::Decorator *TSParser::ParseDecorator()
130 {
131     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
132 
133     lexer::SourcePosition start = Lexer()->GetToken().Start();
134     Lexer()->NextToken();  // eat '@'
135 
136     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
137         ThrowSyntaxError("Identifier expected");
138     }
139 
140     ir::Expression *expr = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
141     expr->SetRange(Lexer()->GetToken().Loc());
142     Lexer()->NextToken();
143 
144     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
145         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
146 
147         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
148             ThrowSyntaxError("Identifier expected");
149         }
150 
151         auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
152         identNode->SetRange(Lexer()->GetToken().Loc());
153 
154         expr =
155             AllocNode<ir::MemberExpression>(expr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false);
156         Lexer()->NextToken();
157     }
158 
159     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
160         expr = ParseCallExpression(expr);
161     }
162 
163     auto *result = AllocNode<ir::Decorator>(expr);
164     result->SetRange({start, expr->End()});
165 
166     return result;
167 }
168 
AddDecorators(ir::AstNode * node,ArenaVector<ir::Decorator * > & decorators)169 void TSParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
170 {
171     if (decorators.empty()) {
172         return;
173     }
174 
175     if (!node->CanHaveDecorator(true)) {
176         ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
177     }
178 
179     node->AddDecorators(std::move(decorators));
180 }
181 
ParseTypeAliasDeclaration()182 ir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration()
183 {
184     ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
185     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
186     Lexer()->NextToken();  // eat type keyword
187 
188     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
189         ThrowSyntaxError("Identifier expected");
190     }
191 
192     if (Lexer()->GetToken().IsReservedTypeName()) {
193         std::string errMsg("Type alias name cannot be '");
194         errMsg.append(TokenToString(Lexer()->GetToken().KeywordType()));
195         errMsg.append("'");
196         ThrowSyntaxError(errMsg.c_str());
197     }
198 
199     const util::StringView &ident = Lexer()->GetToken().Ident();
200 
201     auto *id = AllocNode<ir::Identifier>(ident, Allocator());
202     id->SetRange(Lexer()->GetToken().Loc());
203     Lexer()->NextToken();
204 
205     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
206     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
207         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
208         typeParamDecl = ParseTypeParameterDeclaration(&options);
209     }
210 
211     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
212         ThrowSyntaxError("'=' expected");
213     }
214 
215     Lexer()->NextToken();  // eat '='
216 
217     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
218     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
219 
220     auto *typeAliasDecl = AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation);
221     typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()});
222 
223     return typeAliasDecl;
224 }
225 
CurrentLiteralIsBasicType() const226 bool TSParser::CurrentLiteralIsBasicType() const
227 {
228     switch (Lexer()->GetToken().KeywordType()) {
229         case lexer::TokenType::KEYW_ANY:
230         case lexer::TokenType::KEYW_BOOLEAN:
231         case lexer::TokenType::KEYW_NUMBER:
232         case lexer::TokenType::KEYW_STRING:
233         case lexer::TokenType::KEYW_UNKNOWN:
234         case lexer::TokenType::KEYW_UNDEFINED:
235         case lexer::TokenType::KEYW_NEVER:
236         case lexer::TokenType::KEYW_OBJECT:
237         case lexer::TokenType::KEYW_BIGINT: {
238             return true;
239         }
240         default: {
241             break;
242         }
243     }
244 
245     return false;
246 }
247 
CurrentIsBasicType()248 bool TSParser::CurrentIsBasicType()
249 {
250     switch (Lexer()->GetToken().Type()) {
251         case lexer::TokenType::LITERAL_NUMBER:
252         case lexer::TokenType::LITERAL_STRING:
253         case lexer::TokenType::LITERAL_FALSE:
254         case lexer::TokenType::LITERAL_TRUE:
255         case lexer::TokenType::LITERAL_NULL:
256         case lexer::TokenType::KEYW_THIS:
257         case lexer::TokenType::KEYW_VOID: {
258             return true;
259         }
260         case lexer::TokenType::LITERAL_IDENT: {
261             return CurrentLiteralIsBasicType();
262         }
263         default: {
264             break;
265         }
266     }
267 
268     return false;
269 }
270 
ParseTypeAnnotation(TypeAnnotationParsingOptions * options)271 ir::TypeNode *TSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
272 {
273     ir::TypeNode *typeAnnotation = nullptr;
274 
275     while (true) {
276         ir::TypeNode *element = ParseTypeAnnotationElement(typeAnnotation, options);
277 
278         *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
279 
280         if (element == nullptr) {
281             break;
282         }
283 
284         typeAnnotation = element;
285 
286         if ((((*options) & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) != 0) && Lexer()->GetToken().NewLine()) {
287             break;
288         }
289     }
290 
291     return typeAnnotation;
292 }
293 
ParseIdentifierReference()294 ir::TypeNode *TSParser::ParseIdentifierReference()
295 {
296     if (CurrentLiteralIsBasicType() && Lexer()->Lookahead() != lexer::LEX_CHAR_DOT) {
297         return ParseBasicType();
298     }
299 
300     return ParseTypeReferenceOrQuery();
301 }
302 
IsStartOfMappedType() const303 bool TSParser::IsStartOfMappedType() const
304 {
305     auto pos = Lexer()->Save();
306     Lexer()->NextToken();
307     bool result = false;
308 
309     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
310         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
311         Lexer()->NextToken();
312         result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY;
313         Lexer()->Rewind(pos);
314         return result;
315     }
316 
317     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
318         Lexer()->NextToken();
319     }
320 
321     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
322         Lexer()->Rewind(pos);
323         return false;
324     }
325 
326     Lexer()->NextToken();
327 
328     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
329         Lexer()->Rewind(pos);
330         return false;
331     }
332 
333     Lexer()->NextToken();
334 
335     result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IN;
336 
337     Lexer()->Rewind(pos);
338     return result;
339 }
340 
IsStartOfTypePredicate() const341 bool TSParser::IsStartOfTypePredicate() const
342 {
343     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
344            Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS);
345 
346     auto pos = Lexer()->Save();
347     bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
348     if (isAsserts) {
349         Lexer()->NextToken();
350     }
351 
352     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT &&
353         Lexer()->GetToken().Type() != lexer::TokenType::KEYW_THIS) {
354         Lexer()->Rewind(pos);
355         return false;
356     }
357 
358     if (isAsserts) {
359         Lexer()->Rewind(pos);
360         return true;
361     }
362 
363     Lexer()->NextToken();
364 
365     bool result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS;
366     Lexer()->Rewind(pos);
367     return result;
368 }
369 
IsStartOfAbstractConstructorType() const370 bool TSParser::IsStartOfAbstractConstructorType() const
371 {
372     if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) {
373         return false;
374     }
375 
376     lexer::LexerPosition pos = Lexer()->Save();
377     Lexer()->NextToken();  // eat 'abstract'
378     bool result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW;
379 
380     Lexer()->Rewind(pos);
381 
382     return result;
383 }
384 
ParseImportType(const lexer::SourcePosition & startLoc,bool isTypeof)385 ir::TSImportType *TSParser::ParseImportType(const lexer::SourcePosition &startLoc, bool isTypeof)
386 {
387     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT);
388 
389     Lexer()->NextToken();
390 
391     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
392         ThrowSyntaxError("'(' expected");
393     }
394 
395     Lexer()->NextToken();
396 
397     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
398     ir::TypeNode *param = ParseTypeAnnotation(&options);
399 
400     if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) {
401         ThrowSyntaxError("String literal expected");
402     }
403 
404     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
405         ThrowSyntaxError("')' expected");
406     }
407 
408     Lexer()->NextToken();
409 
410     ir::Expression *qualifier = nullptr;
411     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
412         Lexer()->NextToken();
413         qualifier = ParseQualifiedName();
414     }
415 
416     ir::TSTypeParameterInstantiation *typeParams = nullptr;
417     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT ||
418         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
419         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
420             Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
421         }
422 
423         typeParams = ParseTypeParameterInstantiation(&options);
424     }
425 
426     auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof);
427 
428     importType->SetRange({startLoc, Lexer()->GetToken().End()});
429 
430     return importType;
431 }
432 
ParseThisType(bool throwError)433 ir::TypeNode *TSParser::ParseThisType(bool throwError)
434 {
435     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS);
436 
437     if (throwError && ((GetContext().Status() & ParserStatus::ALLOW_THIS_TYPE) == 0)) {
438         ThrowSyntaxError(
439             "A 'this' type is available only in a non-static member "
440             "of a class or interface.");
441     }
442 
443     auto *returnType = AllocNode<ir::TSThisType>();
444     returnType->SetRange(Lexer()->GetToken().Loc());
445 
446     Lexer()->NextToken();
447 
448     return returnType;
449 }
450 
ParseConditionalType(ir::Expression * checkType,bool restrictExtends)451 ir::TypeNode *TSParser::ParseConditionalType(ir::Expression *checkType, bool restrictExtends)
452 {
453     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
454     if (restrictExtends) {
455         ThrowSyntaxError("'?' expected.");
456     }
457 
458     lexer::SourcePosition startLoc = checkType->Start();
459 
460     Lexer()->NextToken();  // eat 'extends'
461 
462     ParserStatus savedStatus = GetContext().Status();
463     GetContext().Status() |= ParserStatus::IN_EXTENDS;
464 
465     TypeAnnotationParsingOptions options =
466         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
467     auto *extendsType = ParseTypeAnnotation(&options);
468 
469     GetContext().Status() = savedStatus;
470 
471     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
472         ThrowSyntaxError("'?' expected.");
473     }
474 
475     Lexer()->NextToken();  // eat '?'
476 
477     options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
478     auto *trueType = ParseTypeAnnotation(&options);
479 
480     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
481         ThrowSyntaxError("':' expected.");
482     }
483 
484     Lexer()->NextToken();  // eat ':'
485 
486     auto *falseType = ParseTypeAnnotation(&options);
487 
488     lexer::SourcePosition endLoc = falseType->End();
489 
490     auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType);
491 
492     conditionalType->SetRange({startLoc, endLoc});
493 
494     return conditionalType;
495 }
496 
ParseTypeOperatorOrTypeReference()497 ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference()
498 {
499     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
500 
501     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) {
502         lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start();
503         Lexer()->NextToken();
504 
505         ir::TypeNode *type = ParseTypeAnnotation(&options);
506 
507         if (!type->IsTSArrayType() && !type->IsTSTupleType()) {
508             ThrowSyntaxError(
509                 "'readonly' type modifier is only permitted on array "
510                 "and tuple literal types.");
511         }
512 
513         auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY);
514 
515         typeOperator->SetRange({typeOperatorStart, type->End()});
516 
517         return typeOperator;
518     }
519 
520     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) {
521         lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start();
522         Lexer()->NextToken();
523 
524         ir::TypeNode *type = ParseTypeAnnotation(&options);
525 
526         auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF);
527 
528         typeOperator->SetRange({typeOperatorStart, type->End()});
529 
530         return typeOperator;
531     }
532 
533     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) {
534         if ((GetContext().Status() & ParserStatus::IN_EXTENDS) == 0) {
535             ThrowSyntaxError(
536                 "'infer' declarations are only permitted in the "
537                 "'extends' clause of a conditional type.");
538         }
539 
540         lexer::SourcePosition inferStart = Lexer()->GetToken().Start();
541         Lexer()->NextToken();
542 
543         ir::TSTypeParameter *typeParam = ParseTypeParameter(&options);
544 
545         auto *inferType = AllocNode<ir::TSInferType>(typeParam);
546 
547         inferType->SetRange({inferStart, Lexer()->GetToken().End()});
548 
549         return inferType;
550     }
551 
552     return ParseIdentifierReference();
553 }
554 
ParseTupleElement(ir::TSTupleKind * kind,bool * seenOptional)555 ir::TypeNode *TSParser::ParseTupleElement(ir::TSTupleKind *kind, bool *seenOptional)
556 {
557     lexer::SourcePosition elementStart = Lexer()->GetToken().Start();
558     ir::TypeNode *element = nullptr;
559     bool isOptional = false;
560     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
561 
562     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !CurrentLiteralIsBasicType()) {
563         auto *elementIdent = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
564         elementIdent->SetRange(Lexer()->GetToken().Loc());
565 
566         if (Lexer()->Lookahead() == lexer::LEX_CHAR_COLON || Lexer()->Lookahead() == lexer::LEX_CHAR_QUESTION) {
567             if (*kind == ir::TSTupleKind::DEFAULT) {
568                 ThrowSyntaxError("Tuple members must all have names or all not have names");
569             }
570 
571             Lexer()->NextToken();  // eat ident
572 
573             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
574                 Lexer()->NextToken();  // eat '?'
575                 isOptional = true;
576                 *seenOptional = true;
577             } else if (*seenOptional) {
578                 ThrowSyntaxError("A required element cannot follow an optional element");
579             }
580 
581             if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
582                 ThrowSyntaxError("':' expected");
583             }
584 
585             Lexer()->NextToken();  // eat ':'
586             auto *elementType = ParseTypeAnnotation(&options);
587             *kind = ir::TSTupleKind::NAMED;
588 
589             element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional);
590         } else {
591             element = ParseTypeReferenceOrQuery();
592         }
593         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
594             Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
595             element = ParseTypeAnnotationElement(element, &options);
596         }
597     } else {
598         if (*kind == ir::TSTupleKind::NAMED) {
599             ThrowSyntaxError("Tuple members must all have names or all not have names");
600         }
601 
602         *kind = ir::TSTupleKind::DEFAULT;
603         element = ParseTypeAnnotation(&options);
604     }
605 
606     if (element != nullptr) {
607         element->SetRange({elementStart, Lexer()->GetToken().End()});
608     }
609     return element;
610 }
611 
ParseTupleType()612 ir::TSTupleType *TSParser::ParseTupleType()
613 {
614     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
615     lexer::SourcePosition tupleStart = Lexer()->GetToken().Start();
616     ArenaVector<ir::TypeNode *> elements(Allocator()->Adapter());
617     ir::TSTupleKind kind = ir::TSTupleKind::NONE;
618     bool seenOptional = false;
619 
620     Lexer()->NextToken();  // eat '['
621 
622     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
623         ir::TypeNode *element = ParseTupleElement(&kind, &seenOptional);
624         elements.push_back(element);
625 
626         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
627             break;
628         }
629 
630         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
631             ThrowSyntaxError("',' expected.");
632         }
633 
634         Lexer()->NextToken();  // eat ','
635     }
636 
637     lexer::SourcePosition tupleEnd = Lexer()->GetToken().End();
638     Lexer()->NextToken();  // eat ']'
639 
640     auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements));
641     tupleType->SetRange({tupleStart, tupleEnd});
642     return tupleType;
643 }
644 
ParseIndexAccessType(ir::TypeNode * typeName)645 ir::TypeNode *TSParser::ParseIndexAccessType(ir::TypeNode *typeName)
646 {
647     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
648 
649     do {
650         Lexer()->NextToken();  // eat '['
651 
652         ir::TypeNode *indexType = ParseTypeAnnotation(&options);
653 
654         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
655             ThrowSyntaxError("']' expected");
656         }
657 
658         Lexer()->NextToken();  // eat ']'
659 
660         typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType);
661         typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), Lexer()->GetToken().End()});
662     } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
663              Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE);
664 
665     return typeName;
666 }
667 
ParseTypeReferenceOrQuery(bool parseQuery)668 ir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery)
669 {
670     lexer::SourcePosition referenceStartLoc = Lexer()->GetToken().Start();
671 
672     if (parseQuery) {
673         ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF);
674         Lexer()->NextToken();  // eat 'typeof'
675 
676         if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) {
677             lexer::SourcePosition &startLoc = referenceStartLoc;
678             return ParseImportType(startLoc, true);
679         }
680 
681         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
682             ThrowSyntaxError("Identifier expected.");
683         }
684     }
685 
686     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT ||
687            Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS);
688 
689     ir::Expression *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
690     typeName->SetRange(Lexer()->GetToken().Loc());
691 
692     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
693         Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
694     } else {
695         Lexer()->NextToken();
696     }
697 
698     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
699         typeName = ParseQualifiedReference(typeName);
700     }
701 
702     ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
703     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
704         if (parseQuery) {
705             ThrowSyntaxError("Unexpected token.");
706         }
707 
708         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
709         typeParamInst = ParseTypeParameterInstantiation(&options);
710     }
711 
712     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
713         Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE) {
714         ir::TypeNode *typeRef = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode()
715                                            : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode();
716 
717         typeRef->SetRange({referenceStartLoc, Lexer()->GetToken().End()});
718 
719         return ParseIndexAccessType(typeRef);
720     }
721 
722     ir::TypeNode *returnNode = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode()
723                                           : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode();
724 
725     returnNode->SetRange({referenceStartLoc, typeName->End()});
726 
727     return returnNode;
728 }
729 
ParseMappedTypeParameter()730 ir::TSTypeParameter *TSParser::ParseMappedTypeParameter()
731 {
732     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
733 
734     auto *paramName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
735     paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()});
736 
737     Lexer()->NextToken();
738 
739     Lexer()->NextToken();  // eat 'in'
740 
741     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
742     ir::TypeNode *constraint = ParseTypeAnnotation(&options);
743 
744     lexer::SourcePosition endLoc = constraint->End();
745 
746     auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr);
747 
748     typeParameter->SetRange({startLoc, endLoc});
749 
750     return typeParameter;
751 }
752 
ParseMappedOption(lexer::TokenType tokenType)753 ir::MappedOption TSParser::ParseMappedOption(lexer::TokenType tokenType)
754 {
755     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS &&
756         Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS &&
757         Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) {
758         return ir::MappedOption::NO_OPTS;
759     }
760 
761     auto result = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS
762                                                                                    : ir::MappedOption::PLUS;
763 
764     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ||
765         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) {
766         Lexer()->NextToken();
767     }
768 
769     if (Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) {
770         ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."});
771     }
772 
773     Lexer()->NextToken();
774 
775     return result;
776 }
777 
ParseMappedType()778 ir::TSMappedType *TSParser::ParseMappedType()
779 {
780     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
781 
782     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
783     Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
784 
785     ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY);
786 
787     Lexer()->NextToken();  // eat '['
788 
789     ir::TSTypeParameter *typeParameter = ParseMappedTypeParameter();
790 
791     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
792         ThrowSyntaxError("']' expected");
793     }
794 
795     Lexer()->NextToken();  // eat ']'
796 
797     ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK);
798 
799     ir::TypeNode *typeAnnotation = nullptr;
800     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
801         Lexer()->NextToken();  // eat ':'
802         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
803         typeAnnotation = ParseTypeAnnotation(&options);
804     }
805 
806     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
807         Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
808         ThrowSyntaxError("';' expected");
809     }
810 
811     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
812         Lexer()->NextToken();  // eat ';'
813     }
814 
815     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
816         ThrowSyntaxError("'}' expected");
817     }
818 
819     auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, typeAnnotation, readonly, optional);
820 
821     mappedType->SetRange({startLoc, Lexer()->GetToken().End()});
822 
823     Lexer()->NextToken();  // eat '}'
824 
825     return mappedType;
826 }
827 
ParseTypePredicate()828 ir::TSTypePredicate *TSParser::ParseTypePredicate()
829 {
830     auto pos = Lexer()->Save();
831     lexer::SourcePosition startPos = Lexer()->GetToken().Start();
832     bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS;
833     if (isAsserts) {
834         Lexer()->NextToken();  // eat 'asserts'
835         if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) {
836             isAsserts = false;
837             Lexer()->Rewind(pos);
838         }
839     }
840 
841     ir::Expression *parameterName = nullptr;
842     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
843         parameterName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
844     } else {
845         parameterName = AllocNode<ir::TSThisType>();
846     }
847 
848     parameterName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()});
849 
850     Lexer()->NextToken();
851 
852     ir::TypeNode *typeAnnotation = nullptr;
853     lexer::SourcePosition endPos;
854     ir::TSTypePredicate *result = nullptr;
855 
856     if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) {
857         endPos = parameterName->End();
858         result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
859         result->SetRange({startPos, endPos});
860         return result;
861     }
862 
863     Lexer()->NextToken();  // eat 'is'
864 
865     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
866     typeAnnotation = ParseTypeAnnotation(&options);
867     endPos = typeAnnotation->End();
868 
869     result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts);
870 
871     result->SetRange({startPos, endPos});
872 
873     return result;
874 }
875 
ParseTypeLiteralOrMappedType(ir::TypeNode * typeAnnotation)876 ir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotation)
877 {
878     if (typeAnnotation != nullptr) {
879         return nullptr;
880     }
881 
882     if (IsStartOfMappedType()) {
883         return ParseMappedType();
884     }
885 
886     lexer::SourcePosition bodyStart = Lexer()->GetToken().Start();
887     auto members = ParseTypeLiteralOrInterface();
888     lexer::SourcePosition bodyEnd = Lexer()->GetToken().End();
889     Lexer()->NextToken();
890 
891     auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members));
892     auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType);
893     literalType->SetVariable(typeVar);
894     literalType->SetRange({bodyStart, bodyEnd});
895     return literalType;
896 }
897 
ParseTypeReferenceOrTypePredicate(ir::TypeNode * typeAnnotation,bool canBeTsTypePredicate)898 ir::TypeNode *TSParser::ParseTypeReferenceOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate)
899 {
900     if (typeAnnotation != nullptr) {
901         return nullptr;
902     }
903 
904     if (canBeTsTypePredicate && IsStartOfTypePredicate()) {
905         return ParseTypePredicate();
906     }
907 
908     return ParseTypeOperatorOrTypeReference();
909 }
910 
ParseThisTypeOrTypePredicate(ir::TypeNode * typeAnnotation,bool canBeTsTypePredicate,bool throwError)911 ir::TypeNode *TSParser::ParseThisTypeOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate,
912                                                      bool throwError)
913 {
914     if (typeAnnotation != nullptr) {
915         return nullptr;
916     }
917 
918     if (canBeTsTypePredicate && IsStartOfTypePredicate()) {
919         return ParseTypePredicate();
920     }
921 
922     return ParseThisType(throwError);
923 }
924 
ParseArrayType(ir::TypeNode * elementType)925 ir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType)
926 {
927     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
928     Lexer()->NextToken();  // eat '['
929 
930     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
931         ThrowSyntaxError("']' expected");
932     }
933 
934     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
935     Lexer()->NextToken();  // eat ']'
936 
937     lexer::SourcePosition startLoc = elementType->Start();
938     auto *arrayType = AllocNode<ir::TSArrayType>(elementType);
939     arrayType->SetRange({startLoc, endLoc});
940 
941     return arrayType;
942 }
943 
ParseUnionType(ir::TypeNode * type,bool restrictExtends)944 ir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExtends)
945 {
946     ArenaVector<ir::TypeNode *> types(Allocator()->Adapter());
947     lexer::SourcePosition startLoc;
948 
949     TypeAnnotationParsingOptions options =
950         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_UNION;
951 
952     if (restrictExtends) {
953         options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
954     }
955 
956     if (type != nullptr) {
957         startLoc = type->Start();
958         types.push_back(type);
959     } else {
960         startLoc = Lexer()->GetToken().Start();
961     }
962 
963     while (true) {
964         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
965             break;
966         }
967 
968         Lexer()->NextToken();  // eat '|'
969 
970         types.push_back(ParseTypeAnnotation(&options));
971     }
972 
973     lexer::SourcePosition endLoc = types.back()->End();
974 
975     auto *unionType = AllocNode<ir::TSUnionType>(std::move(types));
976     auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType);
977     unionType->SetVariable(typeVar);
978     unionType->SetRange({startLoc, endLoc});
979 
980     return unionType;
981 }
982 
ParseIntersectionType(ir::Expression * type,bool inUnion,bool restrictExtends)983 ir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends)
984 {
985     ArenaVector<ir::Expression *> types(Allocator()->Adapter());
986     lexer::SourcePosition startLoc;
987 
988     TypeAnnotationParsingOptions options =
989         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION;
990 
991     if (restrictExtends) {
992         options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS;
993     }
994 
995     if (inUnion) {
996         options |= TypeAnnotationParsingOptions::IN_UNION;
997     }
998 
999     if (type != nullptr) {
1000         startLoc = type->Start();
1001         types.push_back(type);
1002     } else {
1003         startLoc = Lexer()->GetToken().Start();
1004     }
1005 
1006     while (true) {
1007         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) {
1008             break;
1009         }
1010 
1011         Lexer()->NextToken();  // eat '&'
1012 
1013         types.push_back(ParseTypeAnnotation(&options));
1014     }
1015 
1016     lexer::SourcePosition endLoc = types.back()->End();
1017 
1018     auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types));
1019     auto *typeVar =
1020         varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType);
1021     intersectionType->SetVariable(typeVar);
1022     intersectionType->SetRange({startLoc, endLoc});
1023 
1024     return intersectionType;
1025 }
1026 
1027 class TSParser::ParseBasicTypeHelper {
1028     friend ir::TypeNode *TSParser::ParseBasicType();
1029 
1030 private:
GetTypeAnnotationFromLiteral(TSParser * parser,lexer::Lexer * lexer)1031     static ir::TypeNode *GetTypeAnnotationFromLiteral(TSParser *parser, lexer::Lexer *lexer)
1032     {
1033         switch (lexer->GetToken().KeywordType()) {
1034             case lexer::TokenType::LITERAL_NUMBER: {
1035                 if ((lexer->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1036                     auto *bigintNode = parser->AllocNode<ir::BigIntLiteral>(lexer->GetToken().BigInt());
1037                     bigintNode->SetRange(lexer->GetToken().Loc());
1038 
1039                     return parser->AllocNode<ir::TSLiteralType>(bigintNode);
1040                 }
1041                 auto *numberNode = parser->AllocNode<ir::NumberLiteral>(lexer->GetToken().GetNumber());
1042                 numberNode->SetRange(lexer->GetToken().Loc());
1043 
1044                 return parser->AllocNode<ir::TSLiteralType>(numberNode);
1045             }
1046             case lexer::TokenType::LITERAL_STRING: {
1047                 auto *stringNode = parser->AllocNode<ir::StringLiteral>(lexer->GetToken().String());
1048                 stringNode->SetRange(lexer->GetToken().Loc());
1049 
1050                 return parser->AllocNode<ir::TSLiteralType>(stringNode);
1051             }
1052             case lexer::TokenType::LITERAL_TRUE: {
1053                 auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(true);
1054                 booleanLiteral->SetRange(lexer->GetToken().Loc());
1055 
1056                 return parser->AllocNode<ir::TSLiteralType>(booleanLiteral);
1057             }
1058             case lexer::TokenType::LITERAL_FALSE: {
1059                 auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(false);
1060                 booleanLiteral->SetRange(lexer->GetToken().Loc());
1061 
1062                 return parser->AllocNode<ir::TSLiteralType>(booleanLiteral);
1063             }
1064             case lexer::TokenType::LITERAL_NULL: {
1065                 return parser->AllocNode<ir::TSNullKeyword>();
1066             }
1067             default: {
1068                 return nullptr;
1069             }
1070         }
1071     }
1072 
GetTypeAnnotation(TSParser * parser,lexer::Lexer * lexer)1073     static ir::TypeNode *GetTypeAnnotation(TSParser *parser, lexer::Lexer *lexer)
1074     {
1075         switch (lexer->GetToken().KeywordType()) {
1076             case lexer::TokenType::LITERAL_NUMBER:
1077             case lexer::TokenType::LITERAL_STRING:
1078             case lexer::TokenType::LITERAL_TRUE:
1079             case lexer::TokenType::LITERAL_FALSE:
1080             case lexer::TokenType::LITERAL_NULL: {
1081                 return GetTypeAnnotationFromLiteral(parser, lexer);
1082             }
1083             case lexer::TokenType::KEYW_ANY: {
1084                 return parser->AllocNode<ir::TSAnyKeyword>();
1085             }
1086             case lexer::TokenType::KEYW_BOOLEAN: {
1087                 return parser->AllocNode<ir::TSBooleanKeyword>();
1088             }
1089             case lexer::TokenType::KEYW_NUMBER: {
1090                 return parser->AllocNode<ir::TSNumberKeyword>();
1091             }
1092             case lexer::TokenType::KEYW_STRING: {
1093                 return parser->AllocNode<ir::TSStringKeyword>();
1094             }
1095             case lexer::TokenType::KEYW_UNKNOWN: {
1096                 return parser->AllocNode<ir::TSUnknownKeyword>();
1097             }
1098             case lexer::TokenType::KEYW_VOID: {
1099                 return parser->AllocNode<ir::TSVoidKeyword>();
1100             }
1101             case lexer::TokenType::KEYW_UNDEFINED: {
1102                 return parser->AllocNode<ir::TSUndefinedKeyword>();
1103             }
1104             case lexer::TokenType::KEYW_NEVER: {
1105                 return parser->AllocNode<ir::TSNeverKeyword>();
1106             }
1107             case lexer::TokenType::KEYW_OBJECT: {
1108                 return parser->AllocNode<ir::TSObjectKeyword>();
1109             }
1110             case lexer::TokenType::KEYW_BIGINT: {
1111                 return parser->AllocNode<ir::TSBigintKeyword>();
1112             }
1113             default: {
1114                 parser->ThrowSyntaxError("Unexpected type");
1115             }
1116         }
1117     }
1118 };
ParseBasicType()1119 ir::TypeNode *TSParser::ParseBasicType()
1120 {
1121     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) {
1122         Lexer()->NextToken();
1123 
1124         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) {
1125             ThrowSyntaxError("Type expected");
1126         }
1127     }
1128 
1129     ir::TypeNode *typeAnnotation = ParseBasicTypeHelper::GetTypeAnnotation(this, Lexer());
1130 
1131     typeAnnotation->SetRange(Lexer()->GetToken().Loc());
1132 
1133     Lexer()->NextToken();
1134     return typeAnnotation;
1135 }
1136 
ParseParenthesizedOrFunctionType(ir::TypeNode * typeAnnotation,bool throwError)1137 ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError)
1138 {
1139     if (typeAnnotation != nullptr) {
1140         return nullptr;
1141     }
1142 
1143     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
1144 
1145     bool abstractConstructor = false;
1146 
1147     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1148         abstractConstructor = true;
1149         Lexer()->NextToken();  // eat 'abstract'
1150     }
1151 
1152     bool isConstructionType = false;
1153 
1154     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW) {
1155         Lexer()->NextToken();  // eat 'new'
1156         isConstructionType = true;
1157 
1158         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1159             Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1160             ThrowSyntaxError("'(' expected");
1161         }
1162     }
1163 
1164     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) {
1165         return ParseFunctionType(typeStart, isConstructionType, throwError, abstractConstructor);
1166     }
1167 
1168     const auto startPos = Lexer()->Save();
1169     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1170     Lexer()->NextToken();  // eat '('
1171 
1172     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
1173     ir::TypeNode *type = ParseTypeAnnotation(&options);
1174 
1175     if (type == nullptr) {
1176         Lexer()->Rewind(startPos);
1177         return ParseFunctionType(typeStart, false, throwError);
1178     }
1179 
1180     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
1181         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
1182         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1183         Lexer()->Rewind(startPos);
1184         return ParseFunctionType(typeStart, false, throwError);
1185     }
1186 
1187     if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1188         ThrowSyntaxError("')' expected");
1189     }
1190 
1191     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1192     Lexer()->NextToken();  // eat ')'
1193 
1194     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1195         Lexer()->Rewind(startPos);
1196 
1197         return ParseFunctionType(typeStart, false, throwError);
1198     }
1199 
1200     auto *result = AllocNode<ir::TSParenthesizedType>(type);
1201     result->SetRange({typeStart, endLoc});
1202 
1203     return result;
1204 }
1205 
ParseFunctionType(lexer::SourcePosition startLoc,bool isConstructionType,bool throwError,bool abstractConstructor)1206 ir::TypeNode *TSParser::ParseFunctionType(lexer::SourcePosition startLoc, bool isConstructionType, bool throwError,
1207                                           bool abstractConstructor)
1208 {
1209     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1210     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1211         auto options = throwError ? TypeAnnotationParsingOptions::REPORT_ERROR : TypeAnnotationParsingOptions::NO_OPTS;
1212         typeParamDecl = ParseTypeParameterDeclaration(&options);
1213 
1214         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1215             if (!throwError) {
1216                 return nullptr;
1217             }
1218 
1219             ThrowSyntaxError("'(' expected");
1220         }
1221     }
1222 
1223     auto params = ParseFunctionParams();
1224 
1225     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1226         ThrowSyntaxError("'=>' expected");
1227     }
1228 
1229     Lexer()->NextToken();  // eat '=>'
1230 
1231     TypeAnnotationParsingOptions options =
1232         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1233     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1234 
1235     ir::TypeNode *funcType = nullptr;
1236 
1237     ir::FunctionSignature signature(typeParamDecl, std::move(params), returnTypeAnnotation);
1238 
1239     if (isConstructionType) {
1240         funcType = AllocNode<ir::TSConstructorType>(std::move(signature), abstractConstructor);
1241     } else {
1242         funcType = AllocNode<ir::TSFunctionType>(std::move(signature));
1243     }
1244 
1245     funcType->SetRange({startLoc, returnTypeAnnotation->End()});
1246 
1247     return funcType;
1248 }
1249 
1250 class TSParser::ParseTypeAnnotationElementHelper {
1251     friend ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation,
1252                                                               TypeAnnotationParsingOptions *options);
1253 
1254 private:
ParseKeywordTokens(TSParser * parser,lexer::Lexer * lexer,ir::TypeNode * typeAnnotation,TypeAnnotationParsingOptions * options)1255     static ir::TypeNode *ParseKeywordTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation,
1256                                             TypeAnnotationParsingOptions *options)
1257     {
1258         switch (lexer->GetToken().Type()) {
1259             case lexer::TokenType::KEYW_NEW: {
1260                 return parser->ParseParenthesizedOrFunctionType(
1261                     typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
1262             }
1263             case lexer::TokenType::KEYW_TYPEOF: {
1264                 if (typeAnnotation != nullptr) {
1265                     break;
1266                 }
1267 
1268                 return parser->ParseTypeReferenceOrQuery(true);
1269             }
1270             case lexer::TokenType::KEYW_IMPORT: {
1271                 if (typeAnnotation != nullptr) {
1272                     break;
1273                 }
1274                 return parser->ParseImportType(lexer->GetToken().Start());
1275             }
1276             case lexer::TokenType::KEYW_CONST: {
1277                 if (((*options) & TypeAnnotationParsingOptions::ALLOW_CONST) == 0) {
1278                     break;
1279                 }
1280 
1281                 (*options) &= ~TypeAnnotationParsingOptions::ALLOW_CONST;
1282                 return parser->ParseConstExpression();
1283             }
1284             case lexer::TokenType::KEYW_EXTENDS: {
1285                 if (((*options) &
1286                      (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) {
1287                     break;
1288                 }
1289 
1290                 if (typeAnnotation == nullptr) {
1291                     return parser->ParseIdentifierReference();
1292                 }
1293 
1294                 return parser->ParseConditionalType(typeAnnotation,
1295                                                     ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
1296             }
1297             case lexer::TokenType::KEYW_THIS: {
1298                 return parser->ParseThisTypeOrTypePredicate(
1299                     typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0,
1300                     ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
1301             }
1302             default: {
1303                 break;
1304             }
1305         }
1306         return nullptr;
1307     }
1308 
ParsePunctuatorTokens(TSParser * parser,lexer::Lexer * lexer,ir::TypeNode * typeAnnotation,TypeAnnotationParsingOptions * options)1309     static ir::TypeNode *ParsePunctuatorTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation,
1310                                                TypeAnnotationParsingOptions *options)
1311     {
1312         switch (lexer->GetToken().Type()) {
1313             case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
1314                 if (((*options) &
1315                      (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) {
1316                     break;
1317                 }
1318 
1319                 return parser->ParseUnionType(typeAnnotation,
1320                                               ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
1321             }
1322             case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
1323                 if (((*options) & TypeAnnotationParsingOptions::IN_INTERSECTION) != 0) {
1324                     break;
1325                 }
1326 
1327                 return parser->ParseIntersectionType(
1328                     typeAnnotation, ((*options) & TypeAnnotationParsingOptions::IN_UNION) != 0,
1329                     ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0);
1330             }
1331             case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1332             case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1333                 return parser->ParseParenthesizedOrFunctionType(
1334                     typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
1335             }
1336             case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1337                 if (typeAnnotation != nullptr) {
1338                     if (lexer->Lookahead() == lexer::LEX_CHAR_RIGHT_SQUARE) {
1339                         return parser->ParseArrayType(typeAnnotation);
1340                     }
1341 
1342                     return parser->ParseIndexAccessType(typeAnnotation);
1343                 }
1344 
1345                 return parser->ParseTupleType();
1346             }
1347             case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1348                 return parser->ParseTypeLiteralOrMappedType(typeAnnotation);
1349             }
1350             default: {
1351                 break;
1352             }
1353         }
1354 
1355         return nullptr;
1356     }
1357 };
1358 
ParseTypeAnnotationElement(ir::TypeNode * typeAnnotation,TypeAnnotationParsingOptions * options)1359 ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, TypeAnnotationParsingOptions *options)
1360 {
1361     switch (Lexer()->GetToken().Type()) {
1362         case lexer::TokenType::PUNCTUATOR_MINUS:
1363         case lexer::TokenType::LITERAL_NUMBER:
1364         case lexer::TokenType::LITERAL_STRING:
1365         case lexer::TokenType::LITERAL_FALSE:
1366         case lexer::TokenType::LITERAL_TRUE:
1367         case lexer::TokenType::LITERAL_NULL:
1368         case lexer::TokenType::KEYW_VOID: {
1369             if (typeAnnotation != nullptr) {
1370                 break;
1371             }
1372 
1373             return ParseBasicType();
1374         }
1375         case lexer::TokenType::LITERAL_IDENT: {
1376             if (IsStartOfAbstractConstructorType()) {
1377                 return ParseParenthesizedOrFunctionType(typeAnnotation,
1378                                                         ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
1379             }
1380 
1381             return ParseTypeReferenceOrTypePredicate(
1382                 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0);
1383         }
1384         default: {
1385             ir::TypeNode *parsedValue =
1386                 ParseTypeAnnotationElementHelper::ParseKeywordTokens(this, Lexer(), typeAnnotation, options);
1387             if (parsedValue != nullptr) {
1388                 return parsedValue;
1389             }
1390 
1391             parsedValue =
1392                 ParseTypeAnnotationElementHelper::ParsePunctuatorTokens(this, Lexer(), typeAnnotation, options);
1393             if (parsedValue != nullptr) {
1394                 return parsedValue;
1395             }
1396 
1397             break;
1398         }
1399     }
1400 
1401     if (typeAnnotation == nullptr && (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0)) {
1402         ThrowSyntaxError("Type expected");
1403     }
1404 
1405     return nullptr;
1406 }
1407 
ParsePotentialGenericFunctionCall(ir::Expression * primaryExpr,ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1408 bool TSParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
1409                                                  const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
1410 {
1411     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
1412         (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
1413         return true;
1414     }
1415 
1416     const auto savedPos = Lexer()->Save();
1417 
1418     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1419         Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1420     }
1421 
1422     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
1423     ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
1424 
1425     if (typeParams == nullptr) {
1426         Lexer()->Rewind(savedPos);
1427         return true;
1428     }
1429 
1430     if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
1431         ThrowSyntaxError("'(' or '`' expected");
1432     }
1433 
1434     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1435         if (!ignoreCallExpression) {
1436             *returnExpression = ParseCallExpression(*returnExpression, false);
1437             (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
1438             return false;
1439         }
1440 
1441         return true;
1442     }
1443 
1444     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1445         ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
1446         lexer::SourcePosition endLoc = propertyNode->End();
1447 
1448         *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
1449         (*returnExpression)->SetRange({startLoc, endLoc});
1450         return false;
1451     }
1452 
1453     Lexer()->Rewind(savedPos);
1454     return true;
1455 }
1456 
IsNamedFunctionExpression()1457 bool TSParser::IsNamedFunctionExpression()
1458 {
1459     return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1460            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
1461 }
1462 
ParsePrimaryExpressionIdent(ExpressionParseFlags flags)1463 ir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
1464 {
1465     auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1466     identNode->SetRange(Lexer()->GetToken().Loc());
1467 
1468     Lexer()->NextToken();
1469 
1470     ParsePotentialOptionalFunctionParameter(identNode);
1471 
1472     return identNode;
1473 }
1474 
ParseSignatureMember(bool isCallSignature)1475 ir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature)
1476 {
1477     lexer::SourcePosition memberStartLoc = Lexer()->GetToken().Start();
1478 
1479     if (!isCallSignature) {
1480         Lexer()->NextToken();  // eat 'new' keyword
1481     }
1482 
1483     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1484     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1485         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1486         typeParamDecl = ParseTypeParameterDeclaration(&options);
1487 
1488         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1489             ThrowSyntaxError("'(' expected");
1490         }
1491     }
1492 
1493     FunctionParameterContext funcParamContext(&GetContext());
1494     auto params = ParseFunctionParams();
1495 
1496     ir::TypeNode *typeAnnotation = nullptr;
1497     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1498         Lexer()->NextToken();  // eat ':'
1499         TypeAnnotationParsingOptions options =
1500             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1501         typeAnnotation = ParseTypeAnnotation(&options);
1502     }
1503 
1504     auto kind = isCallSignature ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE
1505                                 : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE;
1506     auto *signatureMember = AllocNode<ir::TSSignatureDeclaration>(
1507         kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation));
1508     signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()});
1509 
1510     return signatureMember;
1511 }
1512 
IsPotentiallyIndexSignature()1513 bool TSParser::IsPotentiallyIndexSignature()
1514 {
1515     const auto savedPos = Lexer()->Save();
1516 
1517     Lexer()->NextToken();  // eat '['
1518 
1519     bool isIndexSignature =
1520         Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON;
1521 
1522     Lexer()->Rewind(savedPos);
1523 
1524     return isIndexSignature;
1525 }
1526 
1527 // NOLINTNEXTLINE(google-default-arguments)
ParseIndexSignature(const lexer::SourcePosition & startLoc,bool isReadonly)1528 ir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1529 {
1530     Lexer()->NextToken();  // eat '['
1531 
1532     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT);
1533     auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1534     key->SetRange(Lexer()->GetToken().Loc());
1535 
1536     Lexer()->NextToken();  // eat key
1537 
1538     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON);
1539 
1540     Lexer()->NextToken();  // eat ':'
1541 
1542     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1543     ir::TypeNode *keyType = ParseTypeAnnotation(&options);
1544 
1545     if (!keyType->IsTSNumberKeyword() && !keyType->IsTSStringKeyword()) {
1546         ThrowSyntaxError(
1547             "An index signature parameter type must be either "
1548             "'string' or 'number'");
1549     }
1550 
1551     key->SetTsTypeAnnotation(keyType);
1552 
1553     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1554         ThrowSyntaxError("']' expected.");
1555     }
1556 
1557     Lexer()->NextToken();  // eat ']'
1558 
1559     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1560         ThrowSyntaxError("An index signature must have a type annotation.");
1561     }
1562 
1563     Lexer()->NextToken();  // eat ':'
1564 
1565     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1566 
1567     auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
1568     indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1569     return indexSignature;
1570 }
1571 
ParseInterfacePropertyKey()1572 std::tuple<ir::Expression *, bool> TSParser::ParseInterfacePropertyKey()
1573 {
1574     ir::Expression *key = nullptr;
1575     bool isComputed = false;
1576 
1577     switch (Lexer()->GetToken().Type()) {
1578         case lexer::TokenType::LITERAL_IDENT: {
1579             const util::StringView &ident = Lexer()->GetToken().Ident();
1580             key = AllocNode<ir::Identifier>(ident, Allocator());
1581             key->SetRange(Lexer()->GetToken().Loc());
1582             break;
1583         }
1584         case lexer::TokenType::LITERAL_STRING: {
1585             const util::StringView &string = Lexer()->GetToken().String();
1586             key = AllocNode<ir::StringLiteral>(string);
1587             key->SetRange(Lexer()->GetToken().Loc());
1588             break;
1589         }
1590         case lexer::TokenType::LITERAL_NUMBER: {
1591             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1592                 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1593             } else {
1594                 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1595             }
1596 
1597             key->SetRange(Lexer()->GetToken().Loc());
1598             break;
1599         }
1600         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1601             Lexer()->NextToken();  // eat left square bracket
1602 
1603             key = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1604             isComputed = true;
1605 
1606             if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1607                 ThrowSyntaxError("Unexpected token, expected ']'");
1608             }
1609             break;
1610         }
1611         default: {
1612             ThrowSyntaxError("Unexpected token in property key");
1613         }
1614     }
1615 
1616     Lexer()->NextToken();
1617     return {key, isComputed};
1618 }
1619 
CreateTSVariableForProperty(ir::AstNode * node,const ir::Expression * key,varbinder::VariableFlags flags)1620 void TSParser::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, varbinder::VariableFlags flags)
1621 {
1622     varbinder::Variable *propVar = nullptr;
1623     bool isMethod = (flags & varbinder::VariableFlags::METHOD) != 0;
1624     util::StringView propName = "__computed";
1625 
1626     switch (key->Type()) {
1627         case ir::AstNodeType::IDENTIFIER: {
1628             propName = key->AsIdentifier()->Name();
1629             break;
1630         }
1631         case ir::AstNodeType::NUMBER_LITERAL: {
1632             propName = key->AsNumberLiteral()->Str();
1633             flags |= varbinder::VariableFlags::NUMERIC_NAME;
1634             break;
1635         }
1636         case ir::AstNodeType::STRING_LITERAL: {
1637             propName = key->AsStringLiteral()->Str();
1638             break;
1639         }
1640         default: {
1641             flags |= varbinder::VariableFlags::COMPUTED;
1642             break;
1643         }
1644     }
1645 
1646     propVar = isMethod ? varbinder::Scope::CreateVar<varbinder::MethodDecl>(Allocator(), propName, flags, node)
1647                        : varbinder::Scope::CreateVar<varbinder::PropertyDecl>(Allocator(), propName, flags, node);
1648 
1649     node->SetVariable(propVar);
1650 }
1651 
ParsePropertyOrMethodSignature(const lexer::SourcePosition & startLoc,bool isReadonly)1652 ir::AstNode *TSParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1653 {
1654     auto [key, isComputed] = ParseInterfacePropertyKey();
1655     varbinder::VariableFlags flags = isReadonly ? varbinder::VariableFlags::READONLY : varbinder::VariableFlags::NONE;
1656 
1657     bool isOptional = false;
1658     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1659         isOptional = true;
1660         flags |= varbinder::VariableFlags::OPTIONAL;
1661         Lexer()->NextToken();  // eat '?'
1662     }
1663 
1664     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1665         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1666         if (isReadonly) {
1667             ThrowSyntaxError("'readonly' modifier can only appear on a property declaration or index signature.",
1668                              startLoc);
1669         }
1670 
1671         ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1672         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1673             auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1674             typeParamDecl = ParseTypeParameterDeclaration(&options);
1675         }
1676 
1677         ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, false);
1678 
1679         FunctionParameterContext funcParamContext(&GetContext());
1680         auto params = ParseFunctionParams();
1681 
1682         ir::TypeNode *returnType = nullptr;
1683         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1684             Lexer()->NextToken();  // eat ':'
1685             TypeAnnotationParsingOptions options =
1686                 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1687             returnType = ParseTypeAnnotation(&options);
1688         }
1689 
1690         auto *methodSignature = AllocNode<ir::TSMethodSignature>(
1691             key, ir::FunctionSignature(typeParamDecl, std::move(params), returnType), isComputed, isOptional);
1692         CreateTSVariableForProperty(methodSignature, key, flags | varbinder::VariableFlags::METHOD);
1693         methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1694         return methodSignature;
1695     }
1696 
1697     ir::TypeNode *typeAnnotation = nullptr;
1698     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1699         Lexer()->NextToken();  // eat ':'
1700         TypeAnnotationParsingOptions options =
1701             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1702         typeAnnotation = ParseTypeAnnotation(&options);
1703     }
1704 
1705     auto *propertySignature =
1706         AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, isOptional, isReadonly);
1707     CreateTSVariableForProperty(propertySignature, key, flags | varbinder::VariableFlags::PROPERTY);
1708     propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1709     return propertySignature;
1710 }
1711 
ParseTypeLiteralOrInterfaceMember()1712 ir::AstNode *TSParser::ParseTypeLiteralOrInterfaceMember()
1713 {
1714     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1715         ThrowSyntaxError("Decorators are not allowed here");
1716     }
1717 
1718     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1719         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1720         return ParseSignatureMember(true);
1721     }
1722 
1723     char32_t nextCp = Lexer()->Lookahead();
1724     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW &&
1725         (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN)) {
1726         return ParseSignatureMember(false);
1727     }
1728 
1729     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1730     bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1731                       nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON &&
1732                       nextCp != lexer::LEX_CHAR_COMMA;
1733     if (isReadonly) {
1734         Lexer()->NextToken();  // eat 'readonly"
1735     }
1736 
1737     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET &&
1738         IsPotentiallyIndexSignature()) {
1739         return ParseIndexSignature(startLoc, isReadonly);
1740     }
1741 
1742     return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1743 }
1744 
ValidateFunctionParam(const ArenaVector<ir::Expression * > & params,const ir::Expression * parameter,bool * seenOptional)1745 void TSParser::ValidateFunctionParam(const ArenaVector<ir::Expression *> &params, const ir::Expression *parameter,
1746                                      bool *seenOptional)
1747 {
1748     if (!parameter->IsIdentifier()) {
1749         GetContext().Status() |= ParserStatus::HAS_COMPLEX_PARAM;
1750         if (!parameter->IsRestElement()) {
1751             return;
1752         }
1753 
1754         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1755             ThrowSyntaxError("A rest parameter must be last in parameter list");
1756         }
1757         return;
1758     }
1759 
1760     bool currentIsOptional = parameter->AsIdentifier()->IsOptional();
1761     if (*seenOptional && !currentIsOptional) {
1762         ThrowSyntaxError("A required parameter cannot follow an optional parameter");
1763     }
1764 
1765     *seenOptional |= currentIsOptional;
1766     const util::StringView &paramName = parameter->AsIdentifier()->Name();
1767 
1768     if (paramName.Is("this")) {
1769         if (!params.empty()) {
1770             ThrowSyntaxError("A 'this' parameter must be the first parameter");
1771         }
1772 
1773         if ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0) {
1774             ThrowSyntaxError("A constructor cannot have a 'this' parameter");
1775         }
1776 
1777         if ((GetContext().Status() & ParserStatus::ARROW_FUNCTION) != 0) {
1778             ThrowSyntaxError("An arrow function cannot have a 'this' parameter");
1779         }
1780 
1781         if ((GetContext().Status() & ParserStatus::ACCESSOR_FUNCTION) != 0) {
1782             ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters");
1783         }
1784     }
1785 
1786     if (paramName.Is("constructor") && ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0)) {
1787         ThrowSyntaxError("'constructor' cannot be used as a parameter property name");
1788     }
1789 }
1790 
ParseFunctionParams()1791 ArenaVector<ir::Expression *> TSParser::ParseFunctionParams()
1792 {
1793     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1794     Lexer()->NextToken();
1795 
1796     ArenaVector<ir::Expression *> params(Allocator()->Adapter());
1797     bool seenOptional = false;
1798 
1799     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1800         ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter());
1801 
1802         ParseDecorators(decorators);
1803 
1804         if (!decorators.empty() && ((GetContext().Status() & ParserStatus::IN_CLASS_BODY) == 0)) {
1805             ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
1806         }
1807 
1808         ir::Expression *parameter = ParseFunctionParameter();
1809         ValidateFunctionParam(params, parameter, &seenOptional);
1810 
1811         if (!decorators.empty()) {
1812             parameter->AddDecorators(std::move(decorators));
1813         }
1814 
1815         params.push_back(parameter);
1816 
1817         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1818             Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1819             ThrowSyntaxError(", expected");
1820         }
1821 
1822         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1823             Lexer()->NextToken();
1824         }
1825     }
1826 
1827     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1828     Lexer()->NextToken();
1829 
1830     return params;
1831 }
1832 
ParseClassKeyAnnotation()1833 ir::TypeNode *TSParser::ParseClassKeyAnnotation()
1834 {
1835     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1836         Lexer()->NextToken();  // eat ':'
1837         TypeAnnotationParsingOptions options =
1838             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1839         return ParseTypeAnnotation(&options);
1840     }
1841 
1842     return nullptr;
1843 }
1844 
ValidateClassMethodStart(ClassElementDescriptor * desc,ir::TypeNode * typeAnnotation)1845 void TSParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1846 {
1847     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) {
1848         ThrowSyntaxError("A method cannot be named with a private identifier");
1849     }
1850 
1851     if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1852                                       Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1853         if (((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY)) != 0)) {
1854             ThrowSyntaxError("Class method can not be declare nor readonly");
1855         }
1856         desc->classMethod = true;
1857     } else {
1858         if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1859             ThrowSyntaxError("Expected '('");
1860         }
1861         desc->classField = true;
1862 
1863         if (desc->invalidComputedProperty) {
1864             ThrowSyntaxError(
1865                 "Computed property name must refer to a symbol or "
1866                 "literal expression whose value is "
1867                 "number or string");
1868         }
1869     }
1870 
1871     if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1872         desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1873     }
1874 
1875     if (desc->isGenerator) {
1876         desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1877     }
1878 }
1879 
ParseClassMethod(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,lexer::SourcePosition * propEnd)1880 ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc,
1881                                                  const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName,
1882                                                  lexer::SourcePosition *propEnd)
1883 {
1884     if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) {
1885         desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION;
1886     }
1887 
1888     desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION;
1889 
1890     if (InAmbientContext() && (desc->newStatus & ParserStatus::ASYNC_FUNCTION) != 0) {
1891         ThrowSyntaxError("'async' modifier cannot be used in an ambient context.");
1892     }
1893 
1894     if (InAmbientContext() && desc->isGenerator) {
1895         ThrowSyntaxError("Generators are not allowed in an ambient context.");
1896     }
1897 
1898     if (desc->methodKind != ir::MethodDefinitionKind::SET &&
1899         ((desc->newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) == 0)) {
1900         desc->newStatus |= ParserStatus::NEED_RETURN_TYPE;
1901     }
1902 
1903     ir::ScriptFunction *func = ParseFunction(desc->newStatus);
1904 
1905     if (func->IsOverload() && !desc->decorators.empty()) {
1906         ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.",
1907                          desc->decorators.front()->Start());
1908     }
1909 
1910     auto *funcExpr = AllocNode<ir::FunctionExpression>(func);
1911     funcExpr->SetRange(func->Range());
1912 
1913     if (desc->methodKind == ir::MethodDefinitionKind::SET) {
1914         ValidateClassSetter(desc, properties, propName, func);
1915     } else if (desc->methodKind == ir::MethodDefinitionKind::GET) {
1916         ValidateClassGetter(desc, properties, propName, func);
1917     }
1918 
1919     *propEnd = func->End();
1920     func->AddFlag(ir::ScriptFunctionFlags::METHOD);
1921     auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(),
1922                                                    desc->isComputed);
1923     method->SetRange(funcExpr->Range());
1924 
1925     return method;
1926 }
1927 
ValidateClassSetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1928 void TSParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1929                                    ir::Expression *propName, ir::ScriptFunction *func)
1930 {
1931     ValidateGetterSetter(ir::MethodDefinitionKind::SET, func->Params().size());
1932 
1933     if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1934         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1935         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1936     }
1937 }
1938 
ValidateClassGetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1939 void TSParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1940                                    ir::Expression *propName, ir::ScriptFunction *func)
1941 {
1942     ValidateGetterSetter(ir::MethodDefinitionKind::GET, func->Params().size());
1943 
1944     if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1945         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1946 
1947         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1948     }
1949 }
1950 
ValidateIndexSignatureTypeAnnotation(ir::TypeNode * typeAnnotation)1951 void TSParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1952 {
1953     if (typeAnnotation == nullptr) {
1954         ThrowSyntaxError("An index signature must have a type annotation");
1955     }
1956 }
1957 
IsModifierKind(const lexer::Token & token)1958 bool TSParser::IsModifierKind(const lexer::Token &token)
1959 {
1960     switch (token.KeywordType()) {
1961         case lexer::TokenType::KEYW_PUBLIC:
1962         case lexer::TokenType::KEYW_PRIVATE:
1963         case lexer::TokenType::KEYW_PROTECTED:
1964         case lexer::TokenType::KEYW_STATIC:
1965         case lexer::TokenType::KEYW_ASYNC:
1966         case lexer::TokenType::KEYW_ABSTRACT:
1967         case lexer::TokenType::KEYW_DECLARE:
1968         case lexer::TokenType::KEYW_READONLY:
1969             return true;
1970         default:
1971             break;
1972     }
1973 
1974     return false;
1975 }
1976 
CheckIfTypeParameterNameIsReserved()1977 void TSParser::CheckIfTypeParameterNameIsReserved()
1978 {
1979     if (Lexer()->GetToken().IsReservedTypeName()) {
1980         ThrowSyntaxError("Invalid type parameter name");
1981     }
1982 }
1983 
CheckIfStaticConstructor(ir::ModifierFlags flags)1984 void TSParser::CheckIfStaticConstructor(ir::ModifierFlags flags)
1985 {
1986     if ((flags & ir::ModifierFlags::STATIC) != 0) {
1987         ThrowSyntaxError("Static modifier can not appear on a constructor");
1988     }
1989 }
1990 
ParseComputedClassFieldOrIndexSignature(ir::Expression ** propName)1991 std::tuple<bool, bool, bool> TSParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1992 {
1993     Lexer()->NextToken();  // eat left square bracket
1994 
1995     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1996         Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1997         auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1998         id->SetRange(Lexer()->GetToken().Loc());
1999 
2000         Lexer()->NextToken();  // eat param
2001 
2002         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2003             ThrowSyntaxError("':' expected");
2004         }
2005 
2006         Lexer()->NextToken();  // eat ':'
2007         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
2008         ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
2009 
2010         if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) {
2011             ThrowSyntaxError(
2012                 "An index signature parameter type must be either "
2013                 "'string' or 'number'");
2014         }
2015 
2016         id->SetTsTypeAnnotation(typeAnnotation);
2017 
2018         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2019             ThrowSyntaxError("']' expected");
2020         }
2021 
2022         *propName = id;
2023         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2024 
2025         return {false, false, true};
2026     }
2027 
2028     *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
2029 
2030     bool invalidComputedProperty =
2031         !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
2032         !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
2033           (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
2034 
2035     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2036         ThrowSyntaxError("Unexpected token, expected ']'");
2037     }
2038 
2039     return {true, invalidComputedProperty, false};
2040 }
2041 
ParseFunctionReturnType(ParserStatus status)2042 ir::TypeNode *TSParser::ParseFunctionReturnType([[maybe_unused]] ParserStatus status)
2043 {
2044     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
2045         Lexer()->NextToken();  // eat ':'
2046         TypeAnnotationParsingOptions options =
2047             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
2048         return ParseTypeAnnotation(&options);
2049     }
2050 
2051     return nullptr;
2052 }
2053 
ValidateFunctionOverloadParams(const ArenaVector<ir::Expression * > & params)2054 void TSParser::ValidateFunctionOverloadParams(const ArenaVector<ir::Expression *> &params)
2055 {
2056     for (auto *it : params) {
2057         if (it->IsAssignmentPattern()) {
2058             ThrowSyntaxError(
2059                 "A parameter initializer is only allowed in a function "
2060                 "or constructor implementation.",
2061                 it->Start());
2062         }
2063     }
2064 }
2065 
ParseFunctionBody(const ArenaVector<ir::Expression * > & params,ParserStatus newStatus,ParserStatus contextStatus)2066 std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> TSParser::ParseFunctionBody(
2067     const ArenaVector<ir::Expression *> &params, ParserStatus newStatus, ParserStatus contextStatus)
2068 {
2069     bool isDeclare = InAmbientContext();
2070     bool isOverload = false;
2071     bool letDeclare = true;
2072     ir::BlockStatement *body = nullptr;
2073     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
2074 
2075     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
2076         if ((newStatus & ParserStatus::FUNCTION_DECLARATION) != 0) {
2077             ValidateFunctionOverloadParams(params);
2078         } else if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
2079             ThrowSyntaxError("Unexpected token, expected '{'");
2080         } else {
2081             letDeclare = false;
2082         }
2083 
2084         isOverload = true;
2085     } else if (isDeclare) {
2086         ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
2087     } else {
2088         body = ParseBlockStatement();
2089         endLoc = body->End();
2090     }
2091 
2092     return {letDeclare, body, endLoc, isOverload};
2093 }
2094 
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode * > * specifiers)2095 ir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
2096 {
2097     ir::Identifier *local = ParseNamedImport(&Lexer()->GetToken());
2098     Lexer()->NextToken();  // eat local name
2099 
2100     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2101         Lexer()->NextToken();  // eat substitution
2102         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2103             ThrowSyntaxError("identifier expected");
2104         }
2105 
2106         auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(local, ParseModuleReference(), false);
2107 
2108         return importEqualsDecl;
2109     }
2110 
2111     auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
2112     specifier->SetRange(specifier->Local()->Range());
2113     specifiers->push_back(specifier);
2114 
2115     Lexer()->NextToken();  // eat specifier name
2116 
2117     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2118         Lexer()->NextToken();  // eat comma
2119     }
2120 
2121     return nullptr;
2122 }
2123 
ParseCatchParamTypeAnnotation(ir::AnnotatedExpression * param)2124 void TSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param)
2125 {
2126     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
2127         Lexer()->NextToken();  // eat ':'
2128 
2129         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
2130         param->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
2131     }
2132 
2133     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2134         ThrowSyntaxError("Catch clause variable cannot have an initializer");
2135     }
2136 }
2137 
ReportPossibleOutOfBoundaryJumpError(bool allowBreak)2138 void TSParser::ReportPossibleOutOfBoundaryJumpError(bool allowBreak)
2139 {
2140     if (((GetContext().Status() & ParserStatus::FUNCTION) != 0) && !allowBreak) {
2141         ThrowSyntaxError("Jump target cannot cross function boundary");
2142     }
2143 }
2144 
ReportIllegalBreakError(const lexer::SourcePosition & pos)2145 void TSParser::ReportIllegalBreakError(const lexer::SourcePosition &pos)
2146 {
2147     ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement", pos);
2148 }
2149 
ReportIllegalContinueError()2150 void TSParser::ReportIllegalContinueError()
2151 {
2152     ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
2153 }
2154 
ReportMultipleDefaultError()2155 void TSParser::ReportMultipleDefaultError()
2156 {
2157     ThrowSyntaxError("A 'default' clause cannot appear more than once in a 'switch' statement");
2158 }
2159 
ReportIllegalNewLineErrorAfterThrow()2160 void TSParser::ReportIllegalNewLineErrorAfterThrow()
2161 {
2162     ThrowSyntaxError("Line break not permitted here");
2163 }
2164 
ReportIfBodyEmptyError(ir::Statement * consequent)2165 void TSParser::ReportIfBodyEmptyError(ir::Statement *consequent)
2166 {
2167     if (consequent->IsEmptyStatement()) {
2168         ThrowSyntaxError("The body of an if statement cannot be the empty statement");
2169     }
2170 }
2171 
2172 }  // namespace ark::es2panda::parser
2173