• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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(), DiagnosticEngine());
85     SetLexer(lexer.get());
86     return lexer;
87 }
88 
ParseDecorator()89 ir::Decorator *ASParser::ParseDecorator()
90 {
91     ES2PANDA_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     ES2PANDA_ASSERT(decorator != nullptr);
99     decorator->SetRange({start, expr->End()});
100     return decorator;
101 }
102 
AddDecorators(ir::AstNode * node,ArenaVector<ir::Decorator * > & decorators)103 void ASParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators)
104 {
105     if (decorators.empty()) {
106         return;
107     }
108 
109     if (!node->CanHaveDecorator(false)) {
110         ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start());
111     }
112 
113     node->AddDecorators(std::move(decorators));
114 }
115 
ParseTypeAliasDeclaration()116 ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration()
117 {
118     ES2PANDA_ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE);
119     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
120     Lexer()->NextToken();  // eat type keyword
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     ES2PANDA_ASSERT(id != nullptr);
129     id->SetRange(Lexer()->GetToken().Loc());
130     Lexer()->NextToken();
131 
132     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
133     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
134         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
135         typeParamDecl = ParseTypeParameterDeclaration(&options);
136     }
137 
138     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
139         ThrowSyntaxError("'=' expected");
140     }
141 
142     Lexer()->NextToken();  // eat '='
143 
144     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
145         Lexer()->NextToken();  // eat '|'
146     }
147 
148     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
149     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
150 
151     auto *typeAliasDecl = AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation);
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         ES2PANDA_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             ES2PANDA_ASSERT(returnNode != nullptr);
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(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     ES2PANDA_ASSERT(key != nullptr);
437     key->SetRange(Lexer()->GetToken().Loc());
438 
439     Lexer()->NextToken();
440 
441     ir::Expression *value = nullptr;
442 
443     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
444         Lexer()->NextToken();
445         value = ParseExpression();
446     } else if (!key->IsStringLiteral()) {
447         value = key;
448     } else {
449         ThrowSyntaxError("':' expected");
450     }
451 
452     auto *property = AllocNode<ir::Property>(key, value);
453     ES2PANDA_ASSERT(property != nullptr);
454     property->SetRange({key->Start(), value->End()});
455     return property;
456 }
457 
CurrentIsBasicType()458 bool ASParser::CurrentIsBasicType()
459 {
460     switch (Lexer()->GetToken().Type()) {
461         case lexer::TokenType::LITERAL_STRING:
462         case lexer::TokenType::LITERAL_FALSE:
463         case lexer::TokenType::LITERAL_TRUE:
464         case lexer::TokenType::LITERAL_NULL:
465         case lexer::TokenType::KEYW_VOID: {
466             return true;
467         }
468         case lexer::TokenType::LITERAL_IDENT: {
469             switch (Lexer()->GetToken().KeywordType()) {
470                 case lexer::TokenType::KEYW_I8:
471                 case lexer::TokenType::KEYW_I16:
472                 case lexer::TokenType::KEYW_I32:
473                 case lexer::TokenType::KEYW_I64:
474                 case lexer::TokenType::KEYW_ISIZE:
475                 case lexer::TokenType::KEYW_U8:
476                 case lexer::TokenType::KEYW_U16:
477                 case lexer::TokenType::KEYW_U32:
478                 case lexer::TokenType::KEYW_U64:
479                 case lexer::TokenType::KEYW_USIZE:
480                 case lexer::TokenType::KEYW_F32:
481                 case lexer::TokenType::KEYW_F64:
482                 case lexer::TokenType::KEYW_V128:
483                 case lexer::TokenType::KEYW_FUNCREF:
484                 case lexer::TokenType::KEYW_EXTERNREF:
485                 case lexer::TokenType::KEYW_ANYREF:
486                 case lexer::TokenType::KEYW_EQREF:
487                 case lexer::TokenType::KEYW_I31REF:
488                 case lexer::TokenType::KEYW_DATAREF: {
489                     return true;
490                 }
491                 default: {
492                     break;
493                 }
494             }
495 
496             break;
497         }
498         default: {
499             break;
500         }
501     }
502     return false;
503 }
504 
ParseFunctionType(lexer::SourcePosition startLoc)505 ir::TypeNode *ASParser::ParseFunctionType(lexer::SourcePosition startLoc)
506 {
507     auto params = ParseFunctionParams();
508 
509     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
510         ThrowSyntaxError("'=>' expected");
511     }
512 
513     Lexer()->NextToken();  // eat '=>'
514 
515     TypeAnnotationParsingOptions options =
516         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
517     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
518 
519     auto signature = ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation);
520     auto funcType = AllocNode<ir::TSFunctionType>(std::move(signature), Allocator());
521 
522     funcType->SetRange({startLoc, returnTypeAnnotation->End()});
523 
524     return funcType;
525 }
526 
ParseParenthesizedOrFunctionType(bool throwError)527 ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError)
528 {
529     lexer::SourcePosition typeStart = Lexer()->GetToken().Start();
530     const auto startPos = Lexer()->Save();
531     ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
532     Lexer()->NextToken();  // eat '('
533 
534     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
535     ir::TypeNode *type = ParseTypeAnnotation(&options);
536 
537     if (type == nullptr) {
538         Lexer()->Rewind(startPos);
539 
540         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
541             if (throwError) {
542                 ThrowSyntaxError("Identifier expected");
543             }
544 
545             return nullptr;
546         }
547 
548         return ParseFunctionType(typeStart);
549     }
550 
551     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ||
552         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK ||
553         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
554         Lexer()->Rewind(startPos);
555         return ParseFunctionType(typeStart);
556     }
557 
558     if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
559         ThrowSyntaxError("')' expected");
560     }
561 
562     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
563     Lexer()->NextToken();  // eat ')'
564 
565     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
566         Lexer()->Rewind(startPos);
567 
568         return ParseFunctionType(typeStart);
569     }
570 
571     type->SetRange({typeStart, endLoc});
572     return type;
573 }
574 
ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode * type,TypeAnnotationParsingOptions * options)575 ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options)
576 {
577     auto *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
578     ES2PANDA_ASSERT(typeName != nullptr);
579     typeName->SetRange(Lexer()->GetToken().Loc());
580     type = AllocNode<ir::NamedType>(typeName, Allocator());
581     ES2PANDA_ASSERT(type != nullptr);
582     type->SetRange(Lexer()->GetToken().Loc());
583     Lexer()->NextToken();
584 
585     ir::NamedType *current = type->AsNamedType();
586     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
587         Lexer()->NextToken();
588 
589         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
590             ThrowSyntaxError("Identifier expected");
591         }
592 
593         typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
594         ES2PANDA_ASSERT(typeName != nullptr);
595         typeName->SetRange(Lexer()->GetToken().Loc());
596         auto *next = AllocNode<ir::NamedType>(typeName, Allocator());
597         current->SetRange(Lexer()->GetToken().Loc());
598         current->SetNext(next);
599         current = next;
600         Lexer()->NextToken();
601     }
602 
603     ir::TSTypeParameterInstantiation *typeParams = nullptr;
604     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
605         typeParams = ParseTypeParameterInstantiation(options);
606         if (typeParams == nullptr) {
607             return nullptr;
608         }
609 
610         type->AsNamedType()->SetTypeParams(typeParams);
611     }
612     return type;
613 }
614 
ParseTypeAnnotationTokens(ir::TypeNode * type,bool throwError,TypeAnnotationParsingOptions * options)615 ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throwError,
616                                                   TypeAnnotationParsingOptions *options)
617 {
618     util::StringView name = "";
619     switch (Lexer()->GetToken().Type()) {
620         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
621             return ParseParenthesizedOrFunctionType(throwError);
622         }
623         case lexer::TokenType::KEYW_VOID: {
624             name = "void";
625             break;
626         }
627         case lexer::TokenType::KEYW_THIS: {
628             name = "this";
629             break;
630         }
631         case lexer::TokenType::LITERAL_FALSE:
632         case lexer::TokenType::LITERAL_TRUE: {
633             name = "bool";
634             break;
635         }
636         case lexer::TokenType::LITERAL_NULL: {
637             name = "null";
638             break;
639         }
640         case lexer::TokenType::LITERAL_STRING: {
641             name = "string";
642             break;
643         }
644         case lexer::TokenType::LITERAL_IDENT: {
645             return ParseTypeAnnotationLiteralIdentHelper(type, options);
646         }
647         default: {
648             if (throwError) {
649                 ThrowSyntaxError("Type expected");
650             }
651 
652             return nullptr;
653         }
654     }
655 
656     auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
657     ES2PANDA_ASSERT(typeName != nullptr);
658     typeName->SetRange(Lexer()->GetToken().Loc());
659     type = AllocNode<ir::NamedType>(typeName, Allocator());
660     ES2PANDA_ASSERT(type != nullptr);
661     type->SetRange(Lexer()->GetToken().Loc());
662     Lexer()->NextToken();
663     return type;
664 }
665 
ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode * type,bool throwError,bool isNullable)666 ir::TypeNode *ASParser::ParseTypeAnnotationTokensBitwiseOr(ir::TypeNode *type, bool throwError, bool isNullable)
667 {
668     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
669         Lexer()->NextToken();
670 
671         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL) {
672             if (throwError) {
673                 ThrowSyntaxError("'null' expected");
674             }
675 
676             return nullptr;
677         }
678 
679         if (!isNullable) {
680             isNullable = true;
681             if (type->IsTSFunctionType()) {
682                 type->AsTSFunctionType()->SetNullable(isNullable);
683             } else {
684                 ES2PANDA_ASSERT(type->IsNamedType());
685                 type->AsNamedType()->SetNullable(isNullable);
686             }
687         }
688 
689         type->SetEnd(Lexer()->GetToken().End());
690         Lexer()->NextToken();
691     }
692     return type;
693 }
694 
ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode * type,bool throwError,bool isNullable)695 ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode *type, bool throwError, bool isNullable)
696 {
697     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
698         Lexer()->NextToken();
699 
700         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
701             if (throwError) {
702                 ThrowSyntaxError("']' expected");
703             }
704 
705             return nullptr;
706         }
707 
708         Lexer()->NextToken();
709 
710         isNullable = false;
711 
712         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) {
713             Lexer()->NextToken();
714 
715             bool isLiteralNull = Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NULL;
716             if (isLiteralNull && throwError) {
717                 ThrowSyntaxError("'null' expected");
718             }
719             if (isLiteralNull) {
720                 return nullptr;
721             }
722 
723             isNullable = true;
724         }
725 
726         const lexer::SourcePosition &startPos = type->Start();
727 
728         util::StringView name = "Array";
729         auto *typeName = AllocNode<ir::Identifier>(name, Allocator());
730         ES2PANDA_ASSERT(typeName != nullptr);
731         typeName->SetRange(Lexer()->GetToken().Loc());
732 
733         ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
734         params.push_back(type);
735         auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
736 
737         type = AllocNode<ir::NamedType>(typeName, Allocator());
738         type->AsNamedType()->SetTypeParams(typeParamInst);
739         type->AsNamedType()->SetNullable(isNullable);
740         type->SetRange({startPos, Lexer()->GetToken().End()});
741 
742         if (isNullable) {
743             Lexer()->NextToken();
744             break;
745         }
746     }
747     return type;
748 }
749 
ParseTypeAnnotation(TypeAnnotationParsingOptions * options)750 ir::TypeNode *ASParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options)
751 {
752     bool reportError = (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0);
753     ir::TypeNode *type = ParseTypeAnnotationTokens(nullptr, reportError, options);
754     if (type == nullptr) {
755         return nullptr;
756     }
757 
758     bool isNullable = false;
759     type = ParseTypeAnnotationTokensBitwiseOr(type, reportError, isNullable);
760     if (type == nullptr) {
761         return nullptr;
762     }
763 
764     type = ParseTypeAnnotationTokenLeftSquareBracket(type, reportError, isNullable);
765     return type;
766 }
767 
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)768 ir::ArrowFunctionExpression *ASParser::ParsePotentialArrowExpression(
769     // CC-OFFNXT(G.FMT.06-CPP) project code style
770     [[maybe_unused]] ir::Expression **returnExpression, [[maybe_unused]] const lexer::SourcePosition &startLoc)
771 {
772     return nullptr;
773 }
774 
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)775 bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc)
776 {
777     if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) {
778         return true;
779     }
780 
781     *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression);
782     ES2PANDA_ASSERT(*returnExpression != nullptr);
783     // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
784     (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()});
785     Lexer()->NextToken();
786     return false;
787 }
788 
ParsePotentialGenericFunctionCall(ir::Expression * primaryExpr,ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)789 bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression,
790                                                  const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
791 {
792     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN ||
793         (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) {
794         return true;
795     }
796 
797     const auto savedPos = Lexer()->Save();
798 
799     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
800         Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
801     }
802 
803     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS;
804     ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options);
805 
806     if (typeParams == nullptr) {
807         Lexer()->Rewind(savedPos);
808         return true;
809     }
810 
811     if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
812         ThrowSyntaxError("'(' or '`' expected");
813     }
814 
815     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
816         if (!ignoreCallExpression) {
817             *returnExpression = ParseCallExpression(*returnExpression, false);
818             (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
819             return false;
820         }
821 
822         return true;
823     }
824 
825     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
826         ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
827         lexer::SourcePosition endLoc = propertyNode->End();
828 
829         *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
830         ES2PANDA_ASSERT(returnExpression != nullptr);
831         // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
832         (*returnExpression)->SetRange({startLoc, endLoc});
833         return false;
834     }
835 
836     Lexer()->Rewind(savedPos);
837     return true;
838 }
839 
IsNamedFunctionExpression()840 bool ASParser::IsNamedFunctionExpression()
841 {
842     return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
843            Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN;
844 }
845 
ParsePotentialAsExpression(ir::Expression * primaryExpression)846 ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpression)
847 {
848     if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) {
849         return nullptr;
850     }
851 
852     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
853     Lexer()->NextToken();
854     ir::TypeNode *type = ParseTypeAnnotation(&options);
855     auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpression, type, false);
856     return asExpression;
857 }
858 
ParsePrimaryExpressionIdent(ExpressionParseFlags flags)859 ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
860 {
861     auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
862     ES2PANDA_ASSERT(identNode != nullptr);
863     identNode->SetRange(Lexer()->GetToken().Loc());
864 
865     Lexer()->NextToken();
866 
867     ParsePotentialOptionalFunctionParameter(identNode);
868 
869     return identNode;
870 }
871 
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)872 bool ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
873 {
874     ParseOptionalFunctionParameter(restElement, true);
875 
876     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
877         ThrowSyntaxError("')' expected");
878     }
879 
880     return true;
881 }
882 
883 // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic
ParseInterfaceExtendsClause()884 ArenaVector<ir::TSInterfaceHeritage *> ASParser::ParseInterfaceExtendsClause()
885 {
886     Lexer()->NextToken();  // eat extends keyword
887 
888     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
889         ThrowSyntaxError("Identifier expected");
890     }
891 
892     const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
893     lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
894     auto *extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
895     ES2PANDA_ASSERT(extendsName != nullptr);
896     extendsName->SetRange(Lexer()->GetToken().Loc());
897     auto *extendsClause = AllocNode<ir::NamedType>(extendsName, Allocator());
898     ES2PANDA_ASSERT(extendsClause != nullptr);
899     extendsClause->SetRange(Lexer()->GetToken().Loc());
900     Lexer()->NextToken();
901 
902     ir::NamedType *current = extendsClause->AsNamedType();
903     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
904         Lexer()->NextToken();
905 
906         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
907             ThrowSyntaxError("Identifier expected");
908         }
909 
910         extendsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
911         extendsName->SetRange(Lexer()->GetToken().Loc());
912         auto *next = AllocNode<ir::NamedType>(extendsName, Allocator());
913         current->SetRange(Lexer()->GetToken().Loc());
914         current->SetNext(next);
915         current = next;
916         heritageEnd = Lexer()->GetToken().End();
917         Lexer()->NextToken();
918     }
919 
920     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
921         Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
922     } else {
923         Lexer()->NextToken();
924     }
925 
926     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
927         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
928         extendsClause->AsNamedType()->SetTypeParams(ParseTypeParameterInstantiation(&options));
929         heritageEnd = Lexer()->GetToken().End();
930     }
931 
932     extendsClause->SetRange({heritageStart, heritageEnd});
933 
934     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
935         ThrowSyntaxError("Interface declaration cannot have 'implements' clause");
936     }
937 
938     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
939         ThrowSyntaxError("'{' expected");
940     }
941 
942     ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
943     auto *heritage = AllocNode<ir::TSInterfaceHeritage>(extendsClause);
944     heritage->SetRange(extendsClause->Range());
945     extends.push_back(heritage);
946     return extends;
947 }
948 
949 // NOLINTNEXTLINE(google-default-arguments)
ParseIndexSignature(const lexer::SourcePosition & startLoc,bool isReadonly)950 ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
951 {
952     Lexer()->NextToken();  // eat '['
953 
954     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
955         ThrowSyntaxError("Identifier expected.");
956     }
957 
958     if (!Lexer()->GetToken().Ident().Is("key")) {
959         ThrowSyntaxError("'key' expected.");
960     }
961 
962     auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
963     ES2PANDA_ASSERT(key != nullptr);
964     key->SetRange(Lexer()->GetToken().Loc());
965 
966     Lexer()->NextToken();  // eat key
967 
968     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
969         ThrowSyntaxError("':' expected.");
970     }
971 
972     Lexer()->NextToken();  // eat ':'
973 
974     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
975     ir::TypeNode *keyType = ParseTypeAnnotation(&options);
976     key->SetTsTypeAnnotation(keyType);
977 
978     if (!keyType->IsNamedType()) {
979         ThrowSyntaxError("Type expected.");
980     }
981 
982     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
983         ThrowSyntaxError("']' expected.");
984     }
985 
986     Lexer()->NextToken();  // eat ']'
987 
988     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
989         ThrowSyntaxError("':' expected.");
990     }
991 
992     Lexer()->NextToken();  // eat ':'
993 
994     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
995 
996     if (!typeAnnotation->IsNamedType()) {
997         ThrowSyntaxError("Identifier expected.");
998     }
999 
1000     auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly);
1001     indexSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1002     return indexSignature;
1003 }
1004 
ParseInterfacePropertyKey()1005 std::tuple<ir::Expression *, bool> ASParser::ParseInterfacePropertyKey()
1006 {
1007     ir::Expression *key = nullptr;
1008 
1009     switch (Lexer()->GetToken().Type()) {
1010         case lexer::TokenType::LITERAL_IDENT: {
1011             const util::StringView &ident = Lexer()->GetToken().Ident();
1012             key = AllocNode<ir::Identifier>(ident, Allocator());
1013             ES2PANDA_ASSERT(key != nullptr);
1014             key->SetRange(Lexer()->GetToken().Loc());
1015             break;
1016         }
1017         case lexer::TokenType::LITERAL_STRING: {
1018             const util::StringView &string = Lexer()->GetToken().String();
1019             key = AllocNode<ir::StringLiteral>(string);
1020             ES2PANDA_ASSERT(key != nullptr);
1021             key->SetRange(Lexer()->GetToken().Loc());
1022             break;
1023         }
1024         case lexer::TokenType::LITERAL_NUMBER: {
1025             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
1026                 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt());
1027             } else {
1028                 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber());
1029             }
1030 
1031             ES2PANDA_ASSERT(key != nullptr);
1032             key->SetRange(Lexer()->GetToken().Loc());
1033             break;
1034         }
1035         default: {
1036             ThrowSyntaxError("Unexpected token in property key");
1037         }
1038     }
1039 
1040     Lexer()->NextToken();
1041     return {key, false};
1042 }
1043 
ParsePropertyOrMethodSignature(const lexer::SourcePosition & startLoc,bool isReadonly)1044 ir::AstNode *ASParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly)
1045 {
1046     auto [key, isComputed] = ParseInterfacePropertyKey();
1047 
1048     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1049         ThrowSyntaxError("Optional properties are not supported.");
1050     }
1051 
1052     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1053         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1054         ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1055 
1056         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1057             auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
1058             typeParamDecl = ParseTypeParameterDeclaration(&options);
1059         }
1060 
1061         FunctionParameterContext funcParamContext(&GetContext());
1062         auto params = ParseFunctionParams();
1063 
1064         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1065             ThrowSyntaxError("Type expected.");
1066         }
1067 
1068         Lexer()->NextToken();  // eat ':'
1069         TypeAnnotationParsingOptions options =
1070             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE;
1071         ir::TypeNode *returnType = ParseTypeAnnotation(&options);
1072 
1073         auto signature = ir::FunctionSignature(typeParamDecl, std::move(params), returnType);
1074         auto *methodSignature = AllocNode<ir::TSMethodSignature>(key, std::move(signature), isComputed, false);
1075         methodSignature->SetRange({startLoc, Lexer()->GetToken().End()});
1076         return methodSignature;
1077     }
1078 
1079     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1080         ThrowSyntaxError("Type expected.");
1081     }
1082 
1083     Lexer()->NextToken();  // eat ':'
1084     TypeAnnotationParsingOptions options =
1085         TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1086     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1087 
1088     auto *propertySignature = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, false, isReadonly);
1089     propertySignature->SetRange({startLoc, Lexer()->GetToken().End()});
1090     return propertySignature;
1091 }
1092 
ParseTypeLiteralOrInterfaceMember()1093 ir::AstNode *ASParser::ParseTypeLiteralOrInterfaceMember()
1094 {
1095     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
1096         ThrowSyntaxError("Decorators are not allowed here");
1097     }
1098 
1099     char32_t nextCp = Lexer()->Lookahead();
1100     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1101     bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY &&
1102                       nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON;
1103     if (isReadonly) {
1104         Lexer()->NextToken();  // eat 'readonly"
1105     }
1106 
1107     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1108         return ParseIndexSignature(startLoc, isReadonly);
1109     }
1110 
1111     return ParsePropertyOrMethodSignature(startLoc, isReadonly);
1112 }
1113 
ParseClassImplementClause()1114 ArenaVector<ir::TSClassImplements *> ASParser::ParseClassImplementClause()
1115 {
1116     ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
1117 
1118     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1119         if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1120             ThrowSyntaxError("Identifier expected");
1121         }
1122 
1123         const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start();
1124         auto *implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1125         ES2PANDA_ASSERT(implementsName != nullptr);
1126         implementsName->SetRange(Lexer()->GetToken().Loc());
1127         auto *implementsClause = AllocNode<ir::NamedType>(implementsName, Allocator());
1128         ES2PANDA_ASSERT(implementsClause != nullptr);
1129         implementsClause->SetRange(Lexer()->GetToken().Loc());
1130         Lexer()->NextToken();
1131 
1132         ir::NamedType *current = implementsClause->AsNamedType();
1133         while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1134             Lexer()->NextToken();
1135 
1136             if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1137                 ThrowSyntaxError("Identifier expected");
1138             }
1139 
1140             implementsName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1141             ES2PANDA_ASSERT(implementsName != nullptr);
1142             implementsName->SetRange(Lexer()->GetToken().Loc());
1143             auto *next = AllocNode<ir::NamedType>(implementsName, Allocator());
1144             current->SetRange(Lexer()->GetToken().Loc());
1145             current->SetNext(next);
1146             current = next;
1147             Lexer()->NextToken();
1148         }
1149 
1150         ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
1151         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1152             Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1153         }
1154 
1155         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
1156             Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1157             TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1158             implTypeParams = ParseTypeParameterInstantiation(&options);
1159         }
1160 
1161         auto *impl = AllocNode<ir::TSClassImplements>(current, implTypeParams);
1162         ES2PANDA_ASSERT(impl != nullptr);
1163         impl->SetRange({implementStart, Lexer()->GetToken().End()});
1164         implements.push_back(impl);
1165 
1166         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1167             Lexer()->NextToken();
1168             continue;
1169         }
1170         ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
1171     }
1172 
1173     if (implements.empty()) {
1174         ThrowSyntaxError("Implements clause can not be empty");
1175     }
1176 
1177     return implements;
1178 }
1179 
ParseClassKeyAnnotation()1180 ir::TypeNode *ASParser::ParseClassKeyAnnotation()
1181 {
1182     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1183         Lexer()->NextToken();  // eat ':'
1184         TypeAnnotationParsingOptions options =
1185             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE;
1186         return ParseTypeAnnotation(&options);
1187     }
1188 
1189     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1190         Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) {
1191         ThrowSyntaxError("Type expected");
1192     }
1193 
1194     return nullptr;
1195 }
1196 
ValidateClassMethodStart(ClassElementDescriptor * desc,ir::TypeNode * typeAnnotation)1197 void ASParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation)
1198 {
1199     if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
1200                                       Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) {
1201         if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) {
1202             ThrowSyntaxError("'declare' modifier cannot appear on class elements of this kind");
1203         }
1204 
1205         desc->classMethod = true;
1206     } else {
1207         if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) {
1208             ThrowSyntaxError("Expected '('");
1209         }
1210         desc->classField = true;
1211 
1212         if (desc->invalidComputedProperty) {
1213             ThrowSyntaxError(
1214                 "Computed property name must refer to a symbol or "
1215                 "literal expression whose value is "
1216                 "number or string");
1217         }
1218     }
1219 
1220     if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) {
1221         desc->newStatus |= ParserStatus::ASYNC_FUNCTION;
1222     }
1223 
1224     if (desc->isGenerator) {
1225         desc->newStatus |= ParserStatus::GENERATOR_FUNCTION;
1226     }
1227 }
1228 
ValidateClassSetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1229 void ASParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1230                                    ir::Expression *propName, ir::ScriptFunction *func)
1231 {
1232     ValidateGetterSetter(ir::MethodDefinitionKind::SET, func->Params().size());
1233 
1234     if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) {
1235         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1236         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access);
1237     }
1238 }
1239 
ValidateClassGetter(ClassElementDescriptor * desc,const ArenaVector<ir::AstNode * > & properties,ir::Expression * propName,ir::ScriptFunction * func)1240 void ASParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties,
1241                                    ir::Expression *propName, [[maybe_unused]] ir::ScriptFunction *func)
1242 {
1243     if ((desc->modifiers & ir::ModifierFlags::STATIC) != 0) {
1244         ir::ModifierFlags access = GetAccessability(desc->modifiers);
1245 
1246         CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access);
1247     }
1248 }
1249 
ParseClassStaticBlock()1250 ir::ClassElement *ASParser::ParseClassStaticBlock()
1251 {
1252     ThrowSyntaxError("Unexpected token");
1253     return nullptr;
1254 }
1255 
ParseOptionalClassElement(ClassElementDescriptor * desc)1256 void ASParser::ParseOptionalClassElement([[maybe_unused]] ClassElementDescriptor *desc)
1257 {
1258     ThrowSyntaxError("Optional properties are not supported");
1259 }
1260 
ValidateIndexSignatureTypeAnnotation(ir::TypeNode * typeAnnotation)1261 void ASParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
1262 {
1263     if (typeAnnotation == nullptr) {
1264         ThrowSyntaxError("':' expected");
1265     }
1266 
1267     if (!typeAnnotation->IsNamedType()) {
1268         ThrowSyntaxError("Identifier expected");
1269     }
1270 }
1271 
IsModifierKind(const lexer::Token & token)1272 bool ASParser::IsModifierKind(const lexer::Token &token)
1273 {
1274     switch (token.KeywordType()) {
1275         case lexer::TokenType::KEYW_PUBLIC:
1276         case lexer::TokenType::KEYW_PRIVATE:
1277         case lexer::TokenType::KEYW_PROTECTED:
1278         case lexer::TokenType::KEYW_STATIC:
1279         case lexer::TokenType::KEYW_ASYNC:
1280         case lexer::TokenType::KEYW_DECLARE:
1281         case lexer::TokenType::KEYW_READONLY:
1282             return true;
1283         default:
1284             break;
1285     }
1286 
1287     return false;
1288 }
1289 
ConsumeClassPrivateIdentifier(ClassElementDescriptor * desc,char32_t * nextCp)1290 void ASParser::ConsumeClassPrivateIdentifier([[maybe_unused]] ClassElementDescriptor *desc,
1291                                              [[maybe_unused]] char32_t *nextCp)
1292 {
1293     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1294         ThrowSyntaxError("Invalid character");
1295     }
1296 }
1297 
ParseComputedClassFieldOrIndexSignature(ir::Expression ** propName)1298 std::tuple<bool, bool, bool> ASParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName)
1299 {
1300     Lexer()->NextToken();  // eat left square bracket
1301 
1302     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
1303         Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) {
1304         if (!Lexer()->GetToken().Ident().Is("key")) {
1305             ThrowSyntaxError("'key' expected.");
1306         }
1307 
1308         auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1309         ES2PANDA_ASSERT(id != nullptr);
1310         id->SetRange(Lexer()->GetToken().Loc());
1311 
1312         Lexer()->NextToken();  // eat param
1313 
1314         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1315             ThrowSyntaxError("':' expected");
1316         }
1317 
1318         Lexer()->NextToken();  // eat ':'
1319         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1320         ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
1321 
1322         if (!typeAnnotation->IsNamedType()) {
1323             ThrowSyntaxError("Type expected");
1324         }
1325 
1326         id->SetTsTypeAnnotation(typeAnnotation);
1327         *propName = id;
1328 
1329         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1330             ThrowSyntaxError("']' expected");
1331         }
1332 
1333         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1334 
1335         return {false, false, true};
1336     }
1337 
1338     *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1339 
1340     bool invalidComputedProperty =
1341         !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() &&
1342         !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() &&
1343           (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol"));
1344 
1345     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1346         ThrowSyntaxError("Unexpected token, expected ']'");
1347     }
1348 
1349     return {true, invalidComputedProperty, false};
1350 }
1351 
ParseFunctionBody(const ArenaVector<ir::Expression * > & params,ParserStatus newStatus,ParserStatus contextStatus)1352 std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> ASParser::ParseFunctionBody(
1353     // CC-OFFNXT(G.FMT.06-CPP) project code style
1354     [[maybe_unused]] const ArenaVector<ir::Expression *> &params, [[maybe_unused]] ParserStatus newStatus,
1355     ParserStatus contextStatus)
1356 {
1357     bool isDeclare = InAmbientContext();
1358     bool isOverload = false;
1359     bool letDeclare = true;
1360     ir::BlockStatement *body = nullptr;
1361     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1362 
1363     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1364         if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) {
1365             ThrowSyntaxError("Unexpected token, expected '{'");
1366         } else {
1367             letDeclare = false;
1368         }
1369 
1370         isOverload = true;
1371     } else if (isDeclare) {
1372         ThrowSyntaxError("An implementation cannot be declared in ambient contexts.");
1373     } else {
1374         body = ParseBlockStatement();
1375         ES2PANDA_ASSERT(body != nullptr);
1376         endLoc = body->End();
1377     }
1378 
1379     return {letDeclare, body, endLoc, isOverload};
1380 }
1381 
ParseImportDefaultSpecifier(ArenaVector<ir::AstNode * > * specifiers)1382 ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers)
1383 {
1384     ir::Identifier *local = ParseNamedImport(&Lexer()->GetToken());
1385     Lexer()->NextToken();  // eat local name
1386 
1387     auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local);
1388     ES2PANDA_ASSERT(specifier != nullptr);
1389     specifier->SetRange(specifier->Local()->Range());
1390     specifiers->push_back(specifier);
1391 
1392     return nullptr;
1393 }
1394 
ParseArrowFunctionRestParameter(lexer::SourcePosition start)1395 ir::Expression *ASParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start)
1396 {
1397     ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1398 
1399     restElement->SetGrouped();
1400     restElement->SetStart(start);
1401 
1402     ValidateArrowFunctionRestParameter(restElement);
1403 
1404     Lexer()->NextToken();
1405 
1406     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1407         ThrowSyntaxError(":' expected");
1408     }
1409 
1410     Lexer()->NextToken();  // eat ':'
1411 
1412     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1413     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1414 
1415     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1416         ThrowSyntaxError("'=>' expected");
1417     }
1418 
1419     return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false);
1420 }
1421 
ParseArrowFunctionNoParameter(lexer::SourcePosition start)1422 ir::Expression *ASParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start)
1423 {
1424     Lexer()->NextToken();
1425 
1426     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
1427         ThrowSyntaxError(":' expected");
1428     }
1429 
1430     Lexer()->NextToken();  // eat ':'
1431 
1432     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1433     ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1434 
1435     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1436         ThrowSyntaxError("'=>' expected");
1437     }
1438 
1439     auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false);
1440     arrowExpr->SetStart(start);
1441     arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
1442 
1443     return arrowExpr;
1444 }
1445 
1446 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)1447 ir::Expression *ASParser::ParseCoverParenthesizedExpressionAndArrowParameterList(
1448     [[maybe_unused]] ExpressionParseFlags flags)  // CC-OFF(G.FMT.06-CPP) project code style
1449 {
1450     ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1451     lexer::SourcePosition start = Lexer()->GetToken().Start();
1452     Lexer()->NextToken();
1453     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1454 
1455     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1456         return ParseArrowFunctionRestParameter(start);
1457     }
1458 
1459     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1460         return ParseArrowFunctionNoParameter(start);
1461     }
1462 
1463     ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
1464                                            ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
1465 
1466     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1467         ThrowSyntaxError("')' expected");
1468     }
1469 
1470     expr->SetGrouped();
1471     expr->SetRange({start, Lexer()->GetToken().End()});
1472     Lexer()->NextToken();
1473 
1474     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1475         ThrowSyntaxError("':' expected.");
1476     }
1477 
1478     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1479         auto savedPos = Lexer()->Save();
1480         Lexer()->NextToken();  // eat ':'
1481         options = TypeAnnotationParsingOptions::NO_OPTS;
1482         ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options);
1483 
1484         if (returnTypeAnnotation == nullptr) {
1485             Lexer()->Rewind(savedPos);
1486             return expr;
1487         }
1488 
1489         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1490             Lexer()->Rewind(savedPos);
1491             return expr;
1492         }
1493 
1494         return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false);
1495     }
1496 
1497     return expr;
1498 }
1499 
ParsePrefixAssertionExpression()1500 ir::Expression *ASParser::ParsePrefixAssertionExpression()
1501 {
1502     lexer::SourcePosition startPos = Lexer()->GetToken().Start();
1503     Lexer()->NextToken();  // eat <
1504     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1505     ir::TypeNode *type = ParseTypeAnnotation(&options);
1506 
1507     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1508         ThrowSyntaxError("'>' expected");
1509     }
1510 
1511     Lexer()->NextToken();  // eat >
1512 
1513     ir::Expression *expr = ParseExpression();
1514 
1515     auto *node = AllocNode<ir::PrefixAssertionExpression>(expr, type);
1516     node->SetRange({startPos, Lexer()->GetToken().End()});
1517     return node;
1518 }
1519 
ParseConstStatement(StatementParsingFlags flags)1520 ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags)
1521 {
1522     lexer::SourcePosition constVarStar = Lexer()->GetToken().Start();
1523     Lexer()->NextToken();
1524 
1525     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM) {
1526         return ParseEnumDeclaration(true);
1527     }
1528 
1529     if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) {
1530         ThrowSyntaxError("Lexical declaration is not allowed in single statement context");
1531     }
1532 
1533     auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND);
1534     ES2PANDA_ASSERT(variableDecl != nullptr);
1535     variableDecl->SetStart(constVarStar);
1536     ConsumeSemicolon(variableDecl);
1537 
1538     return variableDecl;
1539 }
1540 
ParseVariableDeclaratorKey(VariableParsingFlags flags)1541 ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFlags flags)
1542 {
1543     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1544         ThrowSyntaxError("Identifier expected");
1545     }
1546 
1547     ValidateDeclaratorId();
1548 
1549     const util::StringView &identStr = Lexer()->GetToken().Ident();
1550     auto init = AllocNode<ir::Identifier>(identStr, Allocator());
1551     ES2PANDA_ASSERT(init != nullptr);
1552     init->SetRange(Lexer()->GetToken().Loc());
1553     Lexer()->NextToken();
1554 
1555     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1556         Lexer()->NextToken();  // eat ':'
1557         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1558         init->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1559     } else if (((flags & VariableParsingFlags::IN_FOR) == 0) &&
1560                Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1561         ThrowSyntaxError("Type expected");
1562     }
1563 
1564     return init;
1565 }
1566 
ParsePotentialConstEnum(VariableParsingFlags flags)1567 ir::Statement *ASParser::ParsePotentialConstEnum(VariableParsingFlags flags)
1568 {
1569     if ((flags & VariableParsingFlags::CONST) == 0) {
1570         ThrowSyntaxError("Variable declaration expected.");
1571     }
1572 
1573     return ParseEnumDeclaration(true);
1574 }
1575 
1576 // NOLINTNEXTLINE(google-default-arguments)
ParseExportDefaultDeclaration(const lexer::SourcePosition & startLoc,bool isExportEquals)1577 ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexer::SourcePosition &startLoc,
1578                                                                       bool isExportEquals)
1579 {
1580     Lexer()->NextToken();  // eat `default` keyword or `=`
1581 
1582     ir::AstNode *declNode = nullptr;
1583     bool eatSemicolon = false;
1584 
1585     switch (Lexer()->GetToken().Type()) {
1586         case lexer::TokenType::KEYW_FUNCTION: {
1587             declNode = ParseFunctionDeclaration(true);
1588             break;
1589         }
1590         case lexer::TokenType::KEYW_CLASS: {
1591             declNode = ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED);
1592             break;
1593         }
1594         case lexer::TokenType::KEYW_INTERFACE: {
1595             declNode = ParseInterfaceDeclaration(false);
1596             break;
1597         }
1598         case lexer::TokenType::KEYW_NAMESPACE: {
1599             Lexer()->NextToken();  // eat 'namespace'
1600             declNode = ParseModuleOrNamespaceDeclaration(startLoc);
1601             break;
1602         }
1603         case lexer::TokenType::KEYW_ENUM: {
1604             declNode = ParseEnumDeclaration();
1605             break;
1606         }
1607         case lexer::TokenType::KEYW_ASYNC: {
1608             if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) == 0) {
1609                 Lexer()->NextToken();  // eat `async`
1610                 declNode = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1611                 break;
1612             }
1613 
1614             [[fallthrough]];
1615         }
1616         default: {
1617             declNode = ParseExpression();
1618             eatSemicolon = true;
1619             break;
1620         }
1621     }
1622 
1623     lexer::SourcePosition endLoc = declNode->End();
1624     auto *exportDeclaration = AllocNode<ir::ExportDefaultDeclaration>(declNode, isExportEquals);
1625     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1626     exportDeclaration->SetRange({startLoc, endLoc});
1627 
1628     if (eatSemicolon) {
1629         ConsumeSemicolon(exportDeclaration);
1630     }
1631 
1632     return exportDeclaration;
1633 }
1634 
1635 class ASParser::ParseNamedExportDeclarationHelper {
1636     friend ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc);
1637 
1638 private:
GetParsedDeclaration(ASParser * parser,lexer::TokenType type)1639     static ir::Statement *GetParsedDeclaration(ASParser *parser, lexer::TokenType type)
1640     {
1641         ir::ModifierFlags flags = ir::ModifierFlags::NONE;
1642         if (parser->Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) {
1643             parser->Lexer()->NextToken();  // eat 'abstract'
1644             flags = ir::ModifierFlags::ABSTRACT;
1645         }
1646 
1647         switch (type) {
1648             case lexer::TokenType::KEYW_VAR: {
1649                 return parser->ParseVariableDeclaration(VariableParsingFlags::VAR);
1650             }
1651             case lexer::TokenType::KEYW_CONST: {
1652                 return parser->ParseVariableDeclaration(VariableParsingFlags::CONST);
1653             }
1654             case lexer::TokenType::KEYW_LET: {
1655                 return parser->ParseVariableDeclaration(VariableParsingFlags::LET);
1656             }
1657             case lexer::TokenType::KEYW_FUNCTION: {
1658                 return parser->ParseFunctionDeclaration(false, ParserStatus::NO_OPTS);
1659             }
1660             case lexer::TokenType::KEYW_CLASS: {
1661                 return parser->ParseClassDeclaration(ir::ClassDefinitionModifiers::ID_REQUIRED, flags);
1662             }
1663             case lexer::TokenType::KEYW_ENUM: {
1664                 return parser->ParseEnumDeclaration();
1665             }
1666             case lexer::TokenType::KEYW_INTERFACE: {
1667                 return parser->ParseInterfaceDeclaration(false);
1668             }
1669             case lexer::TokenType::KEYW_TYPE: {
1670                 return parser->ParseTypeAliasDeclaration();
1671             }
1672             case lexer::TokenType::KEYW_GLOBAL:
1673             case lexer::TokenType::KEYW_MODULE:
1674             case lexer::TokenType::KEYW_NAMESPACE: {
1675                 return parser->ParseModuleDeclaration();
1676             }
1677             default: {
1678                 parser->ExpectToken(lexer::TokenType::KEYW_ASYNC);
1679                 return parser->ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION);
1680             }
1681         }
1682     }
1683 };
1684 
ParseNamedExportDeclaration(const lexer::SourcePosition & startLoc)1685 ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition &startLoc)
1686 {
1687     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1688         CheckDeclare();
1689     }
1690 
1691     ir::Statement *decl =
1692         ParseNamedExportDeclarationHelper::GetParsedDeclaration(this, Lexer()->GetToken().KeywordType());
1693 
1694     if (decl->IsVariableDeclaration()) {
1695         ConsumeSemicolon(decl);
1696     }
1697 
1698     ArenaVector<ir::ExportSpecifier *> specifiers(Allocator()->Adapter());
1699     auto *exportDeclaration = AllocNode<ir::ExportNamedDeclaration>(Allocator(), decl, std::move(specifiers));
1700     ES2PANDA_ASSERT(exportDeclaration != nullptr);
1701     exportDeclaration->SetRange({startLoc, decl->End()});
1702 
1703     return exportDeclaration;
1704 }
1705 
ParseImportSpecifiers(ArenaVector<ir::AstNode * > * specifiers)1706 ir::AstNode *ASParser::ParseImportSpecifiers(ArenaVector<ir::AstNode *> *specifiers)
1707 {
1708     ES2PANDA_ASSERT(specifiers->empty());
1709 
1710     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1711         ParseImportDefaultSpecifier(specifiers);
1712         return nullptr;
1713     }
1714 
1715     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1716         ParseNameSpaceImport(specifiers);
1717     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
1718         ParseNamedImportSpecifiers(specifiers);
1719     }
1720 
1721     return nullptr;
1722 }
1723 
ParseImportDeclaration(StatementParsingFlags flags)1724 ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags)
1725 {
1726     char32_t nextChar = Lexer()->Lookahead();
1727     if (nextChar == lexer::LEX_CHAR_LEFT_PAREN || nextChar == lexer::LEX_CHAR_DOT) {
1728         return ParseExpressionStatement();
1729     }
1730 
1731     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1732     Lexer()->NextToken();  // eat import
1733 
1734     ArenaVector<ir::AstNode *> specifiers(Allocator()->Adapter());
1735 
1736     ir::StringLiteral *source = nullptr;
1737 
1738     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) {
1739         ParseImportSpecifiers(&specifiers);
1740         source = ParseFromClause(true);
1741     } else {
1742         source = ParseFromClause(false);
1743     }
1744 
1745     ES2PANDA_ASSERT(source != nullptr);
1746     lexer::SourcePosition endLoc = source->End();
1747     auto *importDeclaration = AllocNode<ir::ImportDeclaration>(source, std::move(specifiers));
1748     ES2PANDA_ASSERT(importDeclaration != nullptr);
1749     importDeclaration->SetRange({startLoc, endLoc});
1750 
1751     ConsumeSemicolon(importDeclaration);
1752 
1753     return importDeclaration;
1754 }
1755 
ReportIllegalBreakError(const lexer::SourcePosition & pos)1756 void ASParser::ReportIllegalBreakError(const lexer::SourcePosition &pos)
1757 {
1758     ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement", pos);
1759 }
1760 
ReportIllegalContinueError()1761 void ASParser::ReportIllegalContinueError()
1762 {
1763     ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement");
1764 }
1765 
1766 }  // namespace ark::es2panda::parser
1767