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