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 "ASparser.h"
17 
18 #include "parser/parserStatusContext.h"
19 #include "parserFlags.h"
20 #include "util/helpers.h"
21 #include "varbinder/privateBinding.h"
22 #include "varbinder/scope.h"
23 #include "varbinder/tsBinding.h"
24 #include "lexer/ASLexer.h"
25 #include "ir/base/decorator.h"
26 #include "ir/base/property.h"
27 #include "ir/base/spreadElement.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/exportNamedDeclaration.h"
35 #include "ir/module/importDeclaration.h"
36 #include "ir/expressions/arrowFunctionExpression.h"
37 #include "ir/expressions/templateLiteral.h"
38 #include "ir/expressions/callExpression.h"
39 #include "ir/expressions/taggedTemplateExpression.h"
40 #include "ir/expressions/assignmentExpression.h"
41 #include "ir/expressions/identifier.h"
42 #include "ir/expressions/memberExpression.h"
43 #include "ir/expressions/functionExpression.h"
44 #include "ir/expressions/sequenceExpression.h"
45 #include "ir/expressions/literals/stringLiteral.h"
46 #include "ir/expressions/literals/numberLiteral.h"
47 #include "ir/expressions/literals/bigIntLiteral.h"
48 #include "ir/statements/emptyStatement.h"
49 #include "ir/statements/blockStatement.h"
50 #include "ir/statements/ifStatement.h"
51 #include "ir/statements/doWhileStatement.h"
52 #include "ir/statements/whileStatement.h"
53 #include "ir/statements/tryStatement.h"
54 #include "ir/statements/breakStatement.h"
55 #include "ir/statements/continueStatement.h"
56 #include "ir/statements/throwStatement.h"
57 #include "ir/statements/switchStatement.h"
58 #include "ir/statements/returnStatement.h"
59 #include "ir/statements/debuggerStatement.h"
60 #include "ir/statements/classDeclaration.h"
61 #include "ir/statements/labelledStatement.h"
62 #include "ir/statements/variableDeclarator.h"
63 #include "ir/statements/functionDeclaration.h"
64 #include "ir/as/namedType.h"
65 #include "ir/as/prefixAssertionExpression.h"
66 #include "ir/ts/tsFunctionType.h"
67 #include "ir/ts/tsNonNullExpression.h"
68 #include "ir/ts/tsAsExpression.h"
69 #include "ir/ts/tsEnumDeclaration.h"
70 #include "ir/ts/tsInterfaceDeclaration.h"
71 #include "ir/ts/tsTypeAliasDeclaration.h"
72 #include "ir/ts/tsModuleDeclaration.h"
73 #include "ir/ts/tsInterfaceHeritage.h"
74 #include "ir/base/tsIndexSignature.h"
75 #include "ir/base/tsMethodSignature.h"
76 #include "ir/base/tsPropertySignature.h"
77 #include "ir/ts/tsClassImplements.h"
78 #include "ir/ts/tsTypeParameterInstantiation.h"
79 
80 namespace ark::es2panda::parser {
InitLexer(const SourceFile &sourceFile)81 std::unique_ptr<lexer::Lexer> ASParser::InitLexer(const SourceFile &sourceFile)
82 {
83     GetProgram()->SetSource(sourceFile);
84     auto lexer = std::make_unique<lexer::ASLexer>(&GetContext());
85     SetLexer(lexer.get());
86     return lexer;
87 }
88 
ParseDecorator()89 ir::Decorator *ASParser::ParseDecorator()
90 {
91     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT);
92 
93     lexer::SourcePosition start = Lexer()->GetToken().Start();
94     Lexer()->NextToken();  // eat '@'
95 
96     auto *expr = ParseLeftHandSideExpression();
97     auto *decorator = AllocNode<ir::Decorator>(expr);
98     decorator->SetRange({start, expr->End()});
99     return decorator;
100 }
101 
AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)102 void ASParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
103 {
104     if (decorators.empty()) {
105         return;
106     }
107 
108     if (!node->CanHaveDecorator(false)) {
109         ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
110     }
111 
112     node->AddDecorators(std::move(decorators));
113 }
114 
ParseTypeAliasDeclaration()115 ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration()
116 {
117     ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
118     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
119     Lexer()->NextToken();  // eat type keyword
120 
121     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
122         ThrowSyntaxError("Identifier expected");
123     }
124 
125     const util::StringView &ident = Lexer()->GetToken().Ident();
126 
127     auto *id = AllocNode<ir::Identifier>(ident, Allocator());
128     id->SetRange(Lexer()->GetToken().Loc());
129     Lexer()->NextToken();
130 
131     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
132     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
133         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
134         typeParamDecl = ParseTypeParameterDeclaration(&options);
135     }
136 
137     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
138         ThrowSyntaxError("'=' expected");
139     }
140 
141     Lexer()->NextToken();  // eat '='
142 
143     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
144         Lexer()->NextToken();  // eat '|'
145     }
146 
147     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
148     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
149 
150     auto *typeAliasDecl =
151         AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext());
152     typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()});
153 
154     return typeAliasDecl;
155 }
156 
157 // NOLINTNEXTLINE(google-default-arguments)
ParseStatement(StatementParsingFlags flags)158 ir::Statement *ASParser::ParseStatement(StatementParsingFlags flags)
159 {
160     return ParseDeclareAndDecorators(flags);
161 }
162 
ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool inRest)163 void ASParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool inRest)
164 {
165     bool isOptional = false;
166 
167     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
168         if (inRest) {
169             ThrowSyntaxError("A rest parameter cannot be optional");
170         }
171 
172         ASSERT(returnNode->IsIdentifier());
173         returnNode->AsIdentifier()->SetOptional(true);
174 
175         isOptional = true;
176         Lexer()->NextToken();  // eat '?'
177     }
178 
179     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
180         Lexer()->NextToken();  // eat ':'
181         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
182         returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
183     } else if (!isOptional) {
184         ThrowSyntaxError("':' expected");
185     }
186 
187     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
188         return;
189     }
190 
191     if (inRest) {
192         ThrowSyntaxError("A rest parameter cannot have an initializer");
193     }
194 
195     if (returnNode->IsIdentifier() && isOptional) {
196         ThrowSyntaxError("Parameter cannot have question mark and initializer");
197     }
198 }
199 
ValidateArrowExprIdentifier(ir::Expression *expr, bool *seenOptional)200 ParserStatus ASParser::ValidateArrowExprIdentifier(ir::Expression *expr, bool *seenOptional)
201 {
202     const util::StringView &identifier = expr->AsIdentifier()->Name();
203     bool isOptional = expr->AsIdentifier()->IsOptional();
204     if ((*seenOptional) != isOptional) {
205         ThrowSyntaxError("A required parameter cannot follow an optional parameter.", expr->Start());
206     }
207 
208     (*seenOptional) |= isOptional;
209 
210     if (expr->AsIdentifier()->TypeAnnotation() == nullptr) {
211         ThrowSyntaxError("':' expected", expr->End());
212     }
213 
214     if (identifier.Is("arguments")) {
215         ThrowSyntaxError("Binding 'arguments' in strict mode is invalid");
216     } else if (identifier.Is("eval")) {
217         ThrowSyntaxError("Binding 'eval' in strict mode is invalid");
218     }
219 
220     ValidateArrowParameterBindings(expr);
221     return ParserStatus::NO_OPTS;
222 }
223 
ValidateArrowAssignmentExpr(ir::Expression *expr)224 ParserStatus ASParser::ValidateArrowAssignmentExpr(ir::Expression *expr)
225 {
226     auto *assignmentExpr = expr->AsAssignmentExpression();
227     if (assignmentExpr->Right()->IsYieldExpression()) {
228         ThrowSyntaxError("yield is not allowed in arrow function parameters");
229     }
230 
231     if (assignmentExpr->Right()->IsAwaitExpression()) {
232         ThrowSyntaxError("await is not allowed in arrow function parameters");
233     }
234 
235     if (!assignmentExpr->ConvertibleToAssignmentPattern()) {
236         ThrowSyntaxError("Invalid destructuring assignment target");
237     }
238 
239     if (assignmentExpr->Left()->IsIdentifier() && assignmentExpr->Left()->AsIdentifier()->IsOptional()) {
240         ThrowSyntaxError("Parameter cannot have question mark and initializer.", expr->Start());
241     }
242 
243     ValidateArrowParameterBindings(expr);
244     return ParserStatus::HAS_COMPLEX_PARAM;
245 }
246 
ValidateArrowParameter(ir::Expression *expr, bool *seenOptional)247 ParserStatus ASParser::ValidateArrowParameter(ir::Expression *expr, bool *seenOptional)
248 {
249     switch (expr->Type()) {
250         case ir::AstNodeType::SPREAD_ELEMENT: {
251             if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
252                 ThrowSyntaxError("Invalid rest element.");
253             }
254 
255             [[fallthrough]];
256         }
257         case ir::AstNodeType::REST_ELEMENT: {
258             if (expr->AsRestElement()->IsOptional()) {
259                 ThrowSyntaxError("A rest parameter cannot be optional.", expr->Start());
260             }
261 
262             ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
263             return ParserStatus::HAS_COMPLEX_PARAM;
264         }
265         case ir::AstNodeType::IDENTIFIER: {
266             return ValidateArrowExprIdentifier(expr, seenOptional);
267         }
268         case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
269             return ValidateArrowAssignmentExpr(expr);
270         }
271         default: {
272             break;
273         }
274     }
275     ThrowSyntaxError("Insufficient formal parameter in arrow function.");
276     return ParserStatus::NO_OPTS;
277 }
278 
ConvertToArrowParameter(ir::Expression *expr, bool isAsync)279 ArrowFunctionDescriptor ASParser::ConvertToArrowParameter(ir::Expression *expr, bool isAsync)
280 {
281     auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
282     ArenaVector<ir::Expression *> params(Allocator()->Adapter());
283 
284     if (expr == nullptr) {
285         return ArrowFunctionDescriptor {std::move(params), Lexer()->GetToken().Start(), arrowStatus};
286     }
287 
288     bool seenOptional = false;
289 
290     switch (expr->Type()) {
291         case ir::AstNodeType::REST_ELEMENT:
292         case ir::AstNodeType::IDENTIFIER:
293         case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
294             arrowStatus |= ValidateArrowParameter(expr, &seenOptional);
295 
296             params.push_back(expr);
297             break;
298         }
299         case ir::AstNodeType::SEQUENCE_EXPRESSION: {
300             auto &sequence = expr->AsSequenceExpression()->Sequence();
301 
302             for (auto *it : sequence) {
303                 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
304             }
305 
306             params.swap(sequence);
307             break;
308         }
309         case ir::AstNodeType::CALL_EXPRESSION: {
310             if (isAsync) {
311                 auto &arguments = expr->AsCallExpression()->Arguments();
312 
313                 for (auto *it : arguments) {
314                     arrowStatus |= ValidateArrowParameter(it, &seenOptional);
315                 }
316 
317                 params.swap(arguments);
318                 break;
319             }
320 
321             [[fallthrough]];
322         }
323         default: {
324             ThrowSyntaxError("Unexpected token, arrow (=>)");
325         }
326     }
327 
328     return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus};
329 }
330 
331 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElementToken(ExpressionParseFlags flags)332 std::tuple<ir::AnnotatedExpression *, bool> ASParser::ParsePatternElementToken(ExpressionParseFlags flags)
333 {
334     ir::AnnotatedExpression *returnNode = nullptr;
335     bool isOptional = false;
336 
337     switch (Lexer()->GetToken().Type()) {
338         case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
339             if ((flags & ExpressionParseFlags::IN_REST) != 0) {
340                 ThrowSyntaxError("Unexpected token");
341             }
342 
343             returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
344             break;
345         }
346         case lexer::TokenType::LITERAL_IDENT: {
347             returnNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
348             returnNode->AsIdentifier()->SetReference();
349             returnNode->SetRange(Lexer()->GetToken().Loc());
350             Lexer()->NextToken();
351 
352             bool questionMark = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK;
353             if (questionMark && ((flags & ExpressionParseFlags::IN_REST) != 0)) {
354                 ThrowSyntaxError("A rest parameter cannot be optional");
355             }
356 
357             if (questionMark) {
358                 isOptional = true;
359 
360                 returnNode->AsIdentifier()->SetOptional(true);
361                 Lexer()->NextToken();
362             }
363 
364             if (!isOptional && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
365                 ThrowSyntaxError("':' expected");
366             } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
367                 Lexer()->NextToken();  // eat ':'
368                 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
369                 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
370             }
371 
372             break;
373         }
374         default: {
375             ThrowSyntaxError("Identifier expected");
376         }
377     }
378     return {returnNode, isOptional};
379 }
380 
ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)381 ir::Expression *ASParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
382 {
383     ir::AnnotatedExpression *returnNode = nullptr;
384     bool isOptional = false;
385     std::tie(returnNode, isOptional) = ParsePatternElementToken(flags);
386 
387     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
388         return returnNode;
389     }
390 
391     if ((flags & ExpressionParseFlags::IN_REST) != 0) {
392         ThrowSyntaxError("A rest parameter cannot have an initializer.");
393     }
394 
395     if (!allowDefault) {
396         ThrowSyntaxError("Invalid destructuring assignment target");
397     }
398 
399     if (isOptional) {
400         ThrowSyntaxError("Parameter cannot have question mark and initializer");
401     }
402 
403     Lexer()->NextToken();
404 
405     if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) &&
406         Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
407         ThrowSyntaxError("Yield is not allowed in generator parameters");
408     }
409 
410     ir::Expression *rightNode = ParseExpression();
411 
412     auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
413         ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
414     assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
415 
416     return assignmentExpression;
417 }
418 
419 // NOLINTNEXTLINE(google-default-arguments)
ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)420 ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)
421 {
422     Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
423 
424     ir::Expression *key = nullptr;
425 
426     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
427         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
428             ThrowSyntaxError("Identifier expected");
429         }
430 
431         key = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
432     } else {
433         key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
434     }
435 
436     key->SetRange(Lexer()->GetToken().Loc());
437 
438     Lexer()->NextToken();
439 
440     ir::Expression *value = nullptr;
441 
442     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
443         Lexer()->NextToken();
444         value = ParseExpression();
445     } else if (!key->IsStringLiteral()) {
446         value = key;
447     } else {
448         ThrowSyntaxError("':' expected");
449     }
450 
451     auto *property = AllocNode<ir::Property>(key, value);
452     property->SetRange({key->Start(), value->End()});
453     return property;
454 }
455 
CurrentIsBasicType()456 bool ASParser::CurrentIsBasicType()
457 {
458     switch (Lexer()->GetToken().Type()) {
459         case lexer::TokenType::LITERAL_STRING:
460         case lexer::TokenType::LITERAL_FALSE:
461         case lexer::TokenType::LITERAL_TRUE:
462         case lexer::TokenType::LITERAL_NULL:
463         case lexer::TokenType::KEYW_VOID: {
464             return true;
465         }
466         case lexer::TokenType::LITERAL_IDENT: {
467             switch (Lexer()->GetToken().KeywordType()) {
468                 case lexer::TokenType::KEYW_I8:
469                 case lexer::TokenType::KEYW_I16:
470                 case lexer::TokenType::KEYW_I32:
471                 case lexer::TokenType::KEYW_I64:
472                 case lexer::TokenType::KEYW_ISIZE:
473                 case lexer::TokenType::KEYW_U8:
474                 case lexer::TokenType::KEYW_U16:
475                 case lexer::TokenType::KEYW_U32:
476                 case lexer::TokenType::KEYW_U64:
477                 case lexer::TokenType::KEYW_USIZE:
478                 case lexer::TokenType::KEYW_F32:
479                 case lexer::TokenType::KEYW_F64:
480                 case lexer::TokenType::KEYW_V128:
481                 case lexer::TokenType::KEYW_FUNCREF:
482                 case lexer::TokenType::KEYW_EXTERNREF:
483                 case lexer::TokenType::KEYW_ANYREF:
484                 case lexer::TokenType::KEYW_EQREF:
485                 case lexer::TokenType::KEYW_I31REF:
486                 case lexer::TokenType::KEYW_DATAREF: {
487                     return true;
488                 }
489                 default: {
490                     break;
491                 }
492             }
493 
494             break;
495         }
496         default: {
497             break;
498         }
499     }
500     return false;
501 }
502 
ParseFunctionType(lexer::SourcePosition startLoc)503 ir::TypeNode *ASParser::ParseFunctionType(lexer::SourcePosition startLoc)
504 {
505     auto params = ParseFunctionParams();
506 
507     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
508         ThrowSyntaxError("'=>' expected");
509     }
510 
511     Lexer()->NextToken();  // eat '=>'
512 
513     TypeAnnotationParsingOptions options =
514         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
515     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
516 
517     auto signature = ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation);
518     auto funcType = AllocNode<ir::TSFunctionType>(std::move(signature));
519 
520     funcType->SetRange({startLoc, returnTypeAnnotation->End()});
521 
522     return funcType;
523 }
524 
ParseParenthesizedOrFunctionType(bool throwError)525 ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError)
526 {
527     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
528     const auto startPos = Lexer()->Save();
529     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
530     Lexer()->NextToken();  // eat '('
531 
532     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
533     ir::TypeNode *type = ParseTypeAnnotation(&options);
534 
535     if (type == nullptr) {
536         Lexer()->Rewind(startPos);
537 
538         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
539             if (throwError) {
540                 ThrowSyntaxError("Identifier expected");
541             }
542 
543             return nullptr;
544         }
545 
546         return ParseFunctionType(typeStart);
547     }
548 
549     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
550         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
551         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
552         Lexer()->Rewind(startPos);
553         return ParseFunctionType(typeStart);
554     }
555 
556     if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
557         ThrowSyntaxError("')' expected");
558     }
559 
560     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
561     Lexer()->NextToken();  // eat ')'
562 
563     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
564         Lexer()->Rewind(startPos);
565 
566         return ParseFunctionType(typeStart);
567     }
568 
569     type->SetRange({typeStart, endLoc});
570     return type;
571 }
572 
ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)573 ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)
574 {
575     auto *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
576     typeName->SetRange(Lexer()->GetToken().Loc());
577     type = AllocNode<ir::NamedType>(typeName);
578     type->SetRange(Lexer()->GetToken().Loc());
579     Lexer()->NextToken();
580 
581     ir::NamedType *current = type->AsNamedType();
582     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
583         Lexer()->NextToken();
584 
585         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
586             ThrowSyntaxError("Identifier expected");
587         }
588 
589         typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
590         typeName->SetRange(Lexer()->GetToken().Loc());
591         auto *next = AllocNode<ir::NamedType>(typeName);
592         current->SetRange(Lexer()->GetToken().Loc());
593         current->SetNext(next);
594         current = next;
595         Lexer()->NextToken();
596     }
597 
598     ir::TSTypeParameterInstantiation *typeParams = nullptr;
599     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
600         typeParams = ParseTypeParameterInstantiation(options);
601         if (typeParams == nullptr) {
602             return nullptr;
603         }
604 
605         type->AsNamedType()->SetTypeParams(typeParams);
606     }
607     return type;
608 }
609 
ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError, TypeAnnotationParsingOptions *options)610 ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError,
611                                                   TypeAnnotationParsingOptions *options)
612 {
613     util::StringView name = "";
614     switch (Lexer()->GetToken().Type()) {
615         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
616             return ParseParenthesizedOrFunctionType(throwError);
617         }
618         case lexer::TokenType::KEYW_VOID: {
619             name = "void";
620             break;
621         }
622         case lexer::TokenType::KEYW_THIS: {
623             name = "this";
624             break;
625         }
626         case lexer::TokenType::LITERAL_FALSE:
627         case lexer::TokenType::LITERAL_TRUE: {
628             name = "bool";
629             break;
630         }
631         case lexer::TokenType::LITERAL_NULL: {
632             name = "null";
633             break;
634         }
635         case lexer::TokenType::LITERAL_STRING: {
636             name = "string";
637             break;
638         }
639         case lexer::TokenType::LITERAL_IDENT: {
640             return ParseTypeAnnotationLiteralIdentHelper(type, options);
641         }
642         default: {
643             if (throwError) {
644                 ThrowSyntaxError("Type expected");
645             }
646 
647             return nullptr;
648         }
649     }
650 
651     auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
652     typeName->SetRange(Lexer()->GetToken().Loc());
653     type = AllocNode<ir::NamedType>(typeName);
654     type->SetRange(Lexer()->GetToken().Loc());
655     Lexer()->NextToken();
656     return type;
657 }
658 
ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)659 ir::TypeNode *ASParser::ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)
660 {
661     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
662         Lexer()->NextToken();
663 
664         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL) {
665             if (throwError) {
666                 ThrowSyntaxError("'null' expected");
667             }
668 
669             return nullptr;
670         }
671 
672         if (!isNullable) {
673             isNullable = true;
674             if (type->IsTSFunctionType()) {
675                 type->AsTSFunctionType()->SetNullable(isNullable);
676             } else {
677                 ASSERT(type->IsNamedType());
678                 type->AsNamedType()->SetNullable(isNullable);
679             }
680         }
681 
682         type->SetEnd(Lexer()->GetToken().End());
683         Lexer()->NextToken();
684     }
685     return type;
686 }
687 
ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)688 ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)
689 {
690     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
691         Lexer()->NextToken();
692 
693         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
694             if (throwError) {
695                 ThrowSyntaxError("']' expected");
696             }
697 
698             return nullptr;
699         }
700 
701         Lexer()->NextToken();
702 
703         isNullable = false;
704 
705         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
706             Lexer()->NextToken();
707 
708             bool isLiteralNull = Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL;
709             if (isLiteralNull && throwError) {
710                 ThrowSyntaxError("'null' expected");
711             }
712             if (isLiteralNull) {
713                 return nullptr;
714             }
715 
716             isNullable = true;
717         }
718 
719         const lexer::SourcePosition &startPos = type->Start();
720 
721         util::StringView name = "Array";
722         auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
723         typeName->SetRange(Lexer()->GetToken().Loc());
724 
725         ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
726         params.push_back(type);
727         auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
728 
729         type = AllocNode<ir::NamedType>(typeName);
730         type->AsNamedType()->SetTypeParams(typeParamInst);
731         type->AsNamedType()->SetNullable(isNullable);
732         type->SetRange({startPos, Lexer()->GetToken().End()});
733 
734         if (isNullable) {
735             Lexer()->NextToken();
736             break;
737         }
738     }
739     return type;
740 }
741 
ParseTypeAnnotation(TypeAnnotationParsingOptions *options)742 ir::TypeNode *ASParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
743 {
744     bool reportError = (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
745     ir::TypeNode *type = ParseTypeAnnotationTokens(nullptr, reportError, options);
746     if (type == nullptr) {
747         return nullptr;
748     }
749 
750     bool isNullable = false;
751     type = ParseTypeAnnotationTokensBitwiseOr(type, reportError, isNullable);
752     if (type == nullptr) {
753         return nullptr;
754     }
755 
756     type = ParseTypeAnnotationTokenLeftSquareBracket(type, reportError, isNullable);
757     return type;
758 }
759 
ParsePotentialArrowExpression( [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)760 ir::ArrowFunctionExpression *ASParser::ParsePotentialArrowExpression(
761     [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)
762 {
763     return nullptr;
764 }
765 
ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)766 bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
767 {
768     if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
769         return true;
770     }
771 
772     *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
773     (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
774     Lexer()->NextToken();
775     return false;
776 }
777 
ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression, const lexer::SourcePosition &startLoc, bool ignoreCallExpression)778 bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
779                                                  const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
780 {
781     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
782         (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
783         return true;
784     }
785 
786     const auto savedPos = Lexer()->Save();
787 
788     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
789         Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
790     }
791 
792     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
793     ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
794 
795     if (typeParams == nullptr) {
796         Lexer()->Rewind(savedPos);
797         return true;
798     }
799 
800     if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
801         ThrowSyntaxError("'(' or '`' expected");
802     }
803 
804     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
805         if (!ignoreCallExpression) {
806             *returnExpression = ParseCallExpression(*returnExpression, false);
807             (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
808             return false;
809         }
810 
811         return true;
812     }
813 
814     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
815         ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
816         lexer::SourcePosition endLoc = propertyNode->End();
817 
818         *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
819         (*returnExpression)->SetRange({startLoc, endLoc});
820         return false;
821     }
822 
823     Lexer()->Rewind(savedPos);
824     return true;
825 }
826 
IsNamedFunctionExpression()827 bool ASParser::IsNamedFunctionExpression()
828 {
829     return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
830            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
831 }
832 
ParsePotentialAsExpression(ir::Expression *primaryExpression)833 ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpression)
834 {
835     if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
836         return nullptr;
837     }
838 
839     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
840     Lexer()->NextToken();
841     ir::TypeNode *type = ParseTypeAnnotation(&options);
842     auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpression, type, false);
843     return asExpression;
844 }
845 
ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)846 ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
847 {
848     auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
849     identNode->SetReference();
850     identNode->SetRange(Lexer()->GetToken().Loc());
851 
852     Lexer()->NextToken();
853 
854     ParsePotentialOptionalFunctionParameter(identNode);
855 
856     return identNode;
857 }
858 
ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)859 void ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
860 {
861     ParseOptionalFunctionParameter(restElement, true);
862 
863     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
864         ThrowSyntaxError("')' expected");
865     }
866 }
867 
ParseInterfaceExtendsClause()868 ArenaVector<ir::TSInterfaceHeritage *> ASParser::ParseInterfaceExtendsClause()
869 {
870     Lexer()->NextToken();  // eat extends keyword
871 
872     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
873         ThrowSyntaxError("Identifier expected");
874     }
875 
876     const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
877     lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
878     auto *extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
879     extendsName->SetRange(Lexer()->GetToken().Loc());
880     auto *extendsClause = AllocNode<ir::NamedType>(extendsName);
881     extendsClause->SetRange(Lexer()->GetToken().Loc());
882     Lexer()->NextToken();
883 
884     ir::NamedType *current = extendsClause->AsNamedType();
885     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
886         Lexer()->NextToken();
887 
888         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
889             ThrowSyntaxError("Identifier expected");
890         }
891 
892         extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
893         extendsName->SetRange(Lexer()->GetToken().Loc());
894         auto *next = AllocNode<ir::NamedType>(extendsName);
895         current->SetRange(Lexer()->GetToken().Loc());
896         current->SetNext(next);
897         current = next;
898         heritageEnd = Lexer()->GetToken().End();
899         Lexer()->NextToken();
900     }
901 
902     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
903         Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
904     } else {
905         Lexer()->NextToken();
906     }
907 
908     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
909         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
910         extendsClause->AsNamedType()->SetTypeParams(ParseTypeParameterInstantiation(&options));
911         heritageEnd = Lexer()->GetToken().End();
912     }
913 
914     extendsClause->SetRange({heritageStart, heritageEnd});
915 
916     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
917         ThrowSyntaxError("Interface declaration cannot have 'implements' clause");
918     }
919 
920     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
921         ThrowSyntaxError("'{' expected");
922     }
923 
924     ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
925     auto *heritage = AllocNode<ir::TSInterfaceHeritage>(extendsClause);
926     heritage->SetRange(extendsClause->Range());
927     extends.push_back(heritage);
928     return extends;
929 }
930 
931 // NOLINTNEXTLINE(google-default-arguments)
ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)932 ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
933 {
934     Lexer()->NextToken();  // eat '['
935 
936     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
937         ThrowSyntaxError("Identifier expected.");
938     }
939 
940     if (!Lexer()->GetToken().Ident().Is("key")) {
941         ThrowSyntaxError("'key' expected.");
942     }
943 
944     auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
945     key->SetRange(Lexer()->GetToken().Loc());
946 
947     Lexer()->NextToken();  // eat key
948 
949     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
950         ThrowSyntaxError("':' expected.");
951     }
952 
953     Lexer()->NextToken();  // eat ':'
954 
955     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
956     ir::TypeNode *keyType = ParseTypeAnnotation(&options);
957     key->SetTsTypeAnnotation(keyType);
958 
959     if (!keyType->IsNamedType()) {
960         ThrowSyntaxError("Type expected.");
961     }
962 
963     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
964         ThrowSyntaxError("']' expected.");
965     }
966 
967     Lexer()->NextToken();  // eat ']'
968 
969     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
970         ThrowSyntaxError("':' expected.");
971     }
972 
973     Lexer()->NextToken();  // eat ':'
974 
975     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
976 
977     if (!typeAnnotation->IsNamedType()) {
978         ThrowSyntaxError("Identifier expected.");
979     }
980 
981     auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
982     indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
983     return indexSignature;
984 }
985 
ParseInterfacePropertyKey()986 std::tuple<ir::Expression *, bool> ASParser::ParseInterfacePropertyKey()
987 {
988     ir::Expression *key = nullptr;
989 
990     switch (Lexer()->GetToken().Type()) {
991         case lexer::TokenType::LITERAL_IDENT: {
992             const util::StringView &ident = Lexer()->GetToken().Ident();
993             key = AllocNode<ir::Identifier>(ident, Allocator());
994             key->SetRange(Lexer()->GetToken().Loc());
995             break;
996         }
997         case lexer::TokenType::LITERAL_STRING: {
998             const util::StringView &string = Lexer()->GetToken().String();
999             key = AllocNode<ir::StringLiteral>(string);
1000             key->SetRange(Lexer()->GetToken().Loc());
1001             break;
1002         }
1003         case lexer::TokenType::LITERAL_NUMBER: {
1004             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1005                 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1006             } else {
1007                 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1008             }
1009 
1010             key->SetRange(Lexer()->GetToken().Loc());
1011             break;
1012         }
1013         default: {
1014             ThrowSyntaxError("Unexpected token in property key");
1015         }
1016     }
1017 
1018     Lexer()->NextToken();
1019     return {key, false};
1020 }
1021 
ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)1022 ir::AstNode *ASParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1023 {
1024     auto [key, isComputed] = ParseInterfacePropertyKey();
1025 
1026     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1027         ThrowSyntaxError("Optional properties are not supported.");
1028     }
1029 
1030     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1031         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1032         ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1033 
1034         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1035             auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1036             typeParamDecl = ParseTypeParameterDeclaration(&options);
1037         }
1038 
1039         FunctionParameterContext funcParamContext(&GetContext());
1040         auto params = ParseFunctionParams();
1041 
1042         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1043             ThrowSyntaxError("Type expected.");
1044         }
1045 
1046         Lexer()->NextToken();  // eat ':'
1047         TypeAnnotationParsingOptions options =
1048             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1049         ir::TypeNode *returnType = ParseTypeAnnotation(&options);
1050 
1051         auto signature = ir::FunctionSignature(typeParamDecl, std::move(params), returnType);
1052         auto *methodSignature = AllocNode<ir::TSMethodSignature>(key, std::move(signature), isComputed, false);
1053         methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1054         return methodSignature;
1055     }
1056 
1057     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1058         ThrowSyntaxError("Type expected.");
1059     }
1060 
1061     Lexer()->NextToken();  // eat ':'
1062     TypeAnnotationParsingOptions options =
1063         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1064     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1065 
1066     auto *propertySignature = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, false, isReadonly);
1067     propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1068     return propertySignature;
1069 }
1070 
ParseTypeLiteralOrInterfaceMember()1071 ir::AstNode *ASParser::ParseTypeLiteralOrInterfaceMember()
1072 {
1073     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1074         ThrowSyntaxError("Decorators are not allowed here");
1075     }
1076 
1077     char32_t nextCp = Lexer()->Lookahead();
1078     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1079     bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1080                       nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON;
1081     if (isReadonly) {
1082         Lexer()->NextToken();  // eat 'readonly"
1083     }
1084 
1085     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1086         return ParseIndexSignature(startLoc, isReadonly);
1087     }
1088 
1089     return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1090 }
1091 
ParseClassImplementClause()1092 ArenaVector<ir::TSClassImplements *> ASParser::ParseClassImplementClause()
1093 {
1094     ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
1095 
1096     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1097         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1098             ThrowSyntaxError("Identifier expected");
1099         }
1100 
1101         const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start();
1102         auto *implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1103         implementsName->SetRange(Lexer()->GetToken().Loc());
1104         auto *implementsClause = AllocNode<ir::NamedType>(implementsName);
1105         implementsClause->SetRange(Lexer()->GetToken().Loc());
1106         Lexer()->NextToken();
1107 
1108         ir::NamedType *current = implementsClause->AsNamedType();
1109         while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1110             Lexer()->NextToken();
1111 
1112             if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1113                 ThrowSyntaxError("Identifier expected");
1114             }
1115 
1116             implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1117             implementsName->SetRange(Lexer()->GetToken().Loc());
1118             auto *next = AllocNode<ir::NamedType>(implementsName);
1119             current->SetRange(Lexer()->GetToken().Loc());
1120             current->SetNext(next);
1121             current = next;
1122             Lexer()->NextToken();
1123         }
1124 
1125         ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
1126         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1127             Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1128         }
1129 
1130         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
1131             Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1132             TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1133             implTypeParams = ParseTypeParameterInstantiation(&options);
1134         }
1135 
1136         auto *impl = AllocNode<ir::TSClassImplements>(current, implTypeParams);
1137         impl->SetRange({implementStart, Lexer()->GetToken().End()});
1138         implements.push_back(impl);
1139 
1140         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1141             Lexer()->NextToken();
1142             continue;
1143         }
1144         ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
1145     }
1146 
1147     if (implements.empty()) {
1148         ThrowSyntaxError("Implements clause can not be empty");
1149     }
1150 
1151     return implements;
1152 }
1153 
ParseClassKeyAnnotation()1154 ir::TypeNode *ASParser::ParseClassKeyAnnotation()
1155 {
1156     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1157         Lexer()->NextToken();  // eat ':'
1158         TypeAnnotationParsingOptions options =
1159             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1160         return ParseTypeAnnotation(&options);
1161     }
1162 
1163     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1164         Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1165         ThrowSyntaxError("Type expected");
1166     }
1167 
1168     return nullptr;
1169 }
1170 
ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)1171 void ASParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1172 {
1173     if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1174                                       Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1175         if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) {
1176             ThrowSyntaxError("'declare' modifier cannot appear on class elements of this kind");
1177         }
1178 
1179         desc->classMethod = true;
1180     } else {
1181         if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1182             ThrowSyntaxError("Expected '('");
1183         }
1184         desc->classField = true;
1185 
1186         if (desc->invalidComputedProperty) {
1187             ThrowSyntaxError(
1188                 "Computed property name must refer to a symbol or "
1189                 "literal expression whose value is "
1190                 "number or string");
1191         }
1192     }
1193 
1194     if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1195         desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1196     }
1197 
1198     if (desc->isGenerator) {
1199         desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1200     }
1201 }
1202 
ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, ir::ScriptFunction *func)1203 void ASParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1204                                    ir::Expression *propName, ir::ScriptFunction *func)
1205 {
1206     if (func->Params().size() != 1) {
1207         ThrowSyntaxError("Setter must have exactly one formal parameter");
1208     }
1209 
1210     if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1211         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1212         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1213     }
1214 }
1215 
ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)1216 void ASParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1217                                    ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)
1218 {
1219     if ((desc->modifiers & ir::ModifierFlags::STATIC) != 0) {
1220         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1221 
1222         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1223     }
1224 }
1225 
ParseClassStaticBlock()1226 ir::ClassElement *ASParser::ParseClassStaticBlock()
1227 {
1228     ThrowSyntaxError("Unexpected token");
1229     return nullptr;
1230 }
1231 
ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)1232 void ASParser::ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)
1233 {
1234     ThrowSyntaxError("Optional properties are not supported");
1235 }
1236 
ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)1237 void ASParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1238 {
1239     if (typeAnnotation == nullptr) {
1240         ThrowSyntaxError("':' expected");
1241     }
1242 
1243     if (!typeAnnotation->IsNamedType()) {
1244         ThrowSyntaxError("Identifier expected");
1245     }
1246 }
1247 
IsModifierKind(const lexer::Token &token)1248 bool ASParser::IsModifierKind(const lexer::Token &token)
1249 {
1250     switch (token.KeywordType()) {
1251         case lexer::TokenType::KEYW_PUBLIC:
1252         case lexer::TokenType::KEYW_PRIVATE:
1253         case lexer::TokenType::KEYW_PROTECTED:
1254         case lexer::TokenType::KEYW_STATIC:
1255         case lexer::TokenType::KEYW_ASYNC:
1256         case lexer::TokenType::KEYW_DECLARE:
1257         case lexer::TokenType::KEYW_READONLY:
1258             return true;
1259         default:
1260             break;
1261     }
1262 
1263     return false;
1264 }
1265 
ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc, [[maybe_unused]] char32_t *nextCp)1266 void ASParser::ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc,
1267                                              [[maybe_unused]] char32_t *nextCp)
1268 {
1269     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1270         ThrowSyntaxError("Invalid character");
1271     }
1272 }
1273 
ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)1274 std::tuple<bool, bool, bool> ASParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1275 {
1276     Lexer()->NextToken();  // eat left square bracket
1277 
1278     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1279         Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1280         if (!Lexer()->GetToken().Ident().Is("key")) {
1281             ThrowSyntaxError("'key' expected.");
1282         }
1283 
1284         auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1285         id->SetRange(Lexer()->GetToken().Loc());
1286 
1287         Lexer()->NextToken();  // eat param
1288 
1289         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1290             ThrowSyntaxError("':' expected");
1291         }
1292 
1293         Lexer()->NextToken();  // eat ':'
1294         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1295         ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1296 
1297         if (!typeAnnotation->IsNamedType()) {
1298             ThrowSyntaxError("Type expected");
1299         }
1300 
1301         id->SetTsTypeAnnotation(typeAnnotation);
1302         *propName = id;
1303 
1304         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1305             ThrowSyntaxError("']' expected");
1306         }
1307 
1308         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1309 
1310         return {false, false, true};
1311     }
1312 
1313     *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1314 
1315     bool invalidComputedProperty =
1316         !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
1317         !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
1318           (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
1319 
1320     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1321         ThrowSyntaxError("Unexpected token, expected ']'");
1322     }
1323 
1324     return {true, invalidComputedProperty, false};
1325 }
1326 
ParseFunctionBody( [[maybe_unused]] const ArenaVector<ir::Expression *> &params, [[maybe_unused]] ParserStatus newStatus, ParserStatus contextStatus)1327 std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> ASParser::ParseFunctionBody(
1328     [[maybe_unused]] const ArenaVector<ir::Expression *> &params, [[maybe_unused]] ParserStatus newStatus,
1329     ParserStatus contextStatus)
1330 {
1331     bool isDeclare = InAmbientContext();
1332     bool isOverload = false;
1333     bool letDeclare = true;
1334     ir::BlockStatement *body = nullptr;
1335     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1336 
1337     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1338         if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
1339             ThrowSyntaxError("Unexpected token, expected '{'");
1340         } else {
1341             letDeclare = false;
1342         }
1343 
1344         isOverload = true;
1345     } else if (isDeclare) {
1346         ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
1347     } else {
1348         body = ParseBlockStatement();
1349         endLoc = body->End();
1350     }
1351 
1352     return {letDeclare, body, endLoc, isOverload};
1353 }
1354 
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)1355 ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1356 {
1357     ir::Identifier *local = ParseNamedImport(Lexer()->GetToken());
1358     Lexer()->NextToken();  // eat local name
1359 
1360     auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1361     specifier->SetRange(specifier->Local()->Range());
1362     specifiers->push_back(specifier);
1363 
1364     return nullptr;
1365 }
1366 
ParseArrowFunctionRestParameter(lexer::SourcePosition start)1367 ir::Expression *ASParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
1368 {
1369     ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1370 
1371     restElement->SetGrouped();
1372     restElement->SetStart(start);
1373 
1374     ValidateArrowFunctionRestParameter(restElement);
1375 
1376     Lexer()->NextToken();
1377 
1378     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1379         ThrowSyntaxError(":' expected");
1380     }
1381 
1382     Lexer()->NextToken();  // eat ':'
1383 
1384     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1385     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1386 
1387     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1388         ThrowSyntaxError("'=>' expected");
1389     }
1390 
1391     return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
1392 }
1393 
ParseArrowFunctionNoParameter(lexer::SourcePosition start)1394 ir::Expression *ASParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
1395 {
1396     Lexer()->NextToken();
1397 
1398     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1399         ThrowSyntaxError(":' expected");
1400     }
1401 
1402     Lexer()->NextToken();  // eat ':'
1403 
1404     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1405     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1406 
1407     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1408         ThrowSyntaxError("'=>' expected");
1409     }
1410 
1411     auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
1412     arrowExpr->SetStart(start);
1413     arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
1414 
1415     return arrowExpr;
1416 }
1417 
1418 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList( [[maybe_unused]] ExpressionParseFlags flags)1419 ir::Expression *ASParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
1420     [[maybe_unused]] ExpressionParseFlags flags)
1421 {
1422     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1423     lexer::SourcePosition start = Lexer()->GetToken().Start();
1424     Lexer()->NextToken();
1425     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1426 
1427     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1428         return ParseArrowFunctionRestParameter(start);
1429     }
1430 
1431     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1432         return ParseArrowFunctionNoParameter(start);
1433     }
1434 
1435     ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
1436                                            ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
1437 
1438     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1439         ThrowSyntaxError("')' expected");
1440     }
1441 
1442     expr->SetGrouped();
1443     expr->SetRange({start, Lexer()->GetToken().End()});
1444     Lexer()->NextToken();
1445 
1446     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1447         ThrowSyntaxError("':' expected.");
1448     }
1449 
1450     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1451         auto savedPos = Lexer()->Save();
1452         Lexer()->NextToken();  // eat ':'
1453         options = TypeAnnotationParsingOptions::NO_OPTS;
1454         ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1455 
1456         if (returnTypeAnnotation == nullptr) {
1457             Lexer()->Rewind(savedPos);
1458             return expr;
1459         }
1460 
1461         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1462             Lexer()->Rewind(savedPos);
1463             return expr;
1464         }
1465 
1466         return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
1467     }
1468 
1469     return expr;
1470 }
1471 
ParsePrefixAssertionExpression()1472 ir::Expression *ASParser::ParsePrefixAssertionExpression()
1473 {
1474     lexer::SourcePosition startPos = Lexer()->GetToken().Start();
1475     Lexer()->NextToken();  // eat <
1476     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1477     ir::TypeNode *type = ParseTypeAnnotation(&options);
1478 
1479     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1480         ThrowSyntaxError("'>' expected");
1481     }
1482 
1483     Lexer()->NextToken();  // eat >
1484 
1485     ir::Expression *expr = ParseExpression();
1486 
1487     auto *node = AllocNode<ir::PrefixAssertionExpression>(expr, type);
1488     node->SetRange({startPos, Lexer()->GetToken().End()});
1489     return node;
1490 }
1491 
ParseConstStatement(StatementParsingFlags flags)1492 ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags)
1493 {
1494     lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
1495     Lexer()->NextToken();
1496 
1497     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1498         return ParseEnumDeclaration(true);
1499     }
1500 
1501     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
1502         ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
1503     }
1504 
1505     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
1506     variableDecl->SetStart(constVarStar);
1507     ConsumeSemicolon(variableDecl);
1508 
1509     return variableDecl;
1510 }
1511 
ParseVariableDeclaratorKey(VariableParsingFlags flags)1512 ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
1513 {
1514     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1515         ThrowSyntaxError("Identifier expected");
1516     }
1517 
1518     ValidateDeclaratorId();
1519 
1520     const util::StringView &identStr = Lexer()->GetToken().Ident();
1521     auto init = AllocNode<ir::Identifier>(identStr, Allocator());
1522     init->SetRange(Lexer()->GetToken().Loc());
1523     Lexer()->NextToken();
1524 
1525     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1526         Lexer()->NextToken();  // eat ':'
1527         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1528         init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1529     } else if (((flags & VariableParsingFlags::IN_FOR) == 0) &&
1530                Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1531         ThrowSyntaxError("Type expected");
1532     }
1533 
1534     return init;
1535 }
1536 
ParsePotentialConstEnum(VariableParsingFlags flags)1537 ir::Statement *ASParser::ParsePotentialConstEnum(VariableParsingFlags flags)
1538 {
1539     if ((flags & VariableParsingFlags::CONST) == 0) {
1540         ThrowSyntaxError("Variable declaration expected.");
1541     }
1542 
1543     return ParseEnumDeclaration(true);
1544 }
1545 
1546 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc, bool isExportEquals)1547 ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1548                                                                       bool isExportEquals)
1549 {
1550     Lexer()->NextToken();  // eat `default` keyword or `=`
1551 
1552     ir::AstNode *declNode = nullptr;
1553     bool eatSemicolon = false;
1554 
1555     switch (Lexer()->GetToken().Type()) {
1556         case lexer::TokenType::KEYW_FUNCTION: {
1557             declNode = ParseFunctionDeclaration(true);
1558             break;
1559         }
1560         case lexer::TokenType::KEYW_CLASS: {
1561             declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1562             break;
1563         }
1564         case lexer::TokenType::KEYW_INTERFACE: {
1565             declNode = ParseInterfaceDeclaration(false);
1566             break;
1567         }
1568         case lexer::TokenType::KEYW_NAMESPACE: {
1569             Lexer()->NextToken();  // eat 'namespace'
1570             declNode = ParseModuleOrNamespaceDeclaration(startLoc);
1571             break;
1572         }
1573         case lexer::TokenType::KEYW_ENUM: {
1574             declNode = ParseEnumDeclaration();
1575             break;
1576         }
1577         case lexer::TokenType::KEYW_ASYNC: {
1578             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1579                 Lexer()->NextToken();  // eat `async`
1580                 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1581                 break;
1582             }
1583 
1584             [[fallthrough]];
1585         }
1586         default: {
1587             declNode = ParseExpression();
1588             eatSemicolon = true;
1589             break;
1590         }
1591     }
1592 
1593     lexer::SourcePosition endLoc = declNode->End();
1594     auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1595     exportDeclaration->SetRange({startLoc, endLoc});
1596 
1597     if (eatSemicolon) {
1598         ConsumeSemicolon(exportDeclaration);
1599     }
1600 
1601     return exportDeclaration;
1602 }
1603 
1604 class ASParser::ParseNamedExportDeclarationHelper {
1605     friend ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc);
1606 
1607 private:
GetParsedDeclaration(ASParser *parser, lexer::TokenType type)1608     static ir::Statement *GetParsedDeclaration(ASParser *parser, lexer::TokenType type)
1609     {
1610         ir::ModifierFlags flags = ir::ModifierFlags::NONE;
1611         if (parser->Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1612             parser->Lexer()->NextToken();  // eat 'abstract'
1613             flags = ir::ModifierFlags::ABSTRACT;
1614         }
1615 
1616         switch (type) {
1617             case lexer::TokenType::KEYW_VAR: {
1618                 return parser->ParseVariableDeclaration(VariableParsingFlags::VAR);
1619             }
1620             case lexer::TokenType::KEYW_CONST: {
1621                 return parser->ParseVariableDeclaration(VariableParsingFlags::CONST);
1622             }
1623             case lexer::TokenType::KEYW_LET: {
1624                 return parser->ParseVariableDeclaration(VariableParsingFlags::LET);
1625             }
1626             case lexer::TokenType::KEYW_FUNCTION: {
1627                 return parser->ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1628             }
1629             case lexer::TokenType::KEYW_CLASS: {
1630                 return parser->ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED, flags);
1631             }
1632             case lexer::TokenType::KEYW_ENUM: {
1633                 return parser->ParseEnumDeclaration();
1634             }
1635             case lexer::TokenType::KEYW_INTERFACE: {
1636                 return parser->ParseInterfaceDeclaration(false);
1637             }
1638             case lexer::TokenType::KEYW_TYPE: {
1639                 return parser->ParseTypeAliasDeclaration();
1640             }
1641             case lexer::TokenType::KEYW_GLOBAL:
1642             case lexer::TokenType::KEYW_MODULE:
1643             case lexer::TokenType::KEYW_NAMESPACE: {
1644                 return parser->ParseModuleDeclaration();
1645             }
1646             default: {
1647                 parser->ExpectToken(lexer::TokenType::KEYW_ASYNC);
1648                 return parser->ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1649             }
1650         }
1651     }
1652 };
1653 
ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)1654 ir::ExportNamedDeclaration *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1655 {
1656     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1657         CheckDeclare();
1658     }
1659 
1660     ir::Statement *decl =
1661         ParseNamedExportDeclarationHelper::GetParsedDeclaration(this, Lexer()->GetToken().KeywordType());
1662 
1663     if (decl->IsVariableDeclaration()) {
1664         ConsumeSemicolon(decl);
1665     }
1666 
1667     ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1668     auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1669     exportDeclaration->SetRange({startLoc, decl->End()});
1670 
1671     return exportDeclaration;
1672 }
1673 
ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)1674 ir::AstNode *ASParser::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1675 {
1676     ASSERT(specifiers->empty());
1677 
1678     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1679         ParseImportDefaultSpecifier(specifiers);
1680         return nullptr;
1681     }
1682 
1683     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1684         ParseNameSpaceImport(specifiers);
1685     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1686         ParseNamedImportSpecifiers(specifiers);
1687     }
1688 
1689     return nullptr;
1690 }
1691 
ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)1692 ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
1693 {
1694     char32_t nextChar = Lexer()->Lookahead();
1695     if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
1696         return ParseExpressionStatement();
1697     }
1698 
1699     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1700     Lexer()->NextToken();  // eat import
1701 
1702     ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
1703 
1704     ir::StringLiteral *source = nullptr;
1705 
1706     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1707         ParseImportSpecifiers(&specifiers);
1708         source = ParseFromClause(true);
1709     } else {
1710         source = ParseFromClause(false);
1711     }
1712 
1713     lexer::SourcePosition endLoc = source->End();
1714     auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
1715     importDeclaration->SetRange({startLoc, endLoc});
1716 
1717     ConsumeSemicolon(importDeclaration);
1718 
1719     return importDeclaration;
1720 }
1721 
ThrowIllegalBreakError()1722 void ASParser::ThrowIllegalBreakError()
1723 {
1724     ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement");
1725 }
1726 
ThrowIllegalContinueError()1727 void ASParser::ThrowIllegalContinueError()
1728 {
1729     ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
1730 }
1731 
1732 }  // namespace ark::es2panda::parser
1733