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