• 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 "TypedParser.h"
17 
18 #include "parser/parserImpl.h"
19 #include "parser/parserStatusContext.h"
20 #include "varbinder/privateBinding.h"
21 #include "lexer/lexer.h"
22 #include "ir/base/classDefinition.h"
23 #include "ir/base/decorator.h"
24 #include "ir/base/spreadElement.h"
25 #include "ir/base/tsPropertySignature.h"
26 #include "ir/base/tsMethodSignature.h"
27 #include "ir/base/methodDefinition.h"
28 #include "ir/base/tsIndexSignature.h"
29 #include "ir/base/scriptFunction.h"
30 #include "ir/expressions/identifier.h"
31 #include "ir/expressions/yieldExpression.h"
32 #include "ir/expressions/objectExpression.h"
33 #include "ir/expressions/arrayExpression.h"
34 #include "ir/expressions/assignmentExpression.h"
35 #include "ir/expressions/arrowFunctionExpression.h"
36 #include "ir/expressions/sequenceExpression.h"
37 #include "ir/expressions/callExpression.h"
38 #include "ir/expressions/literals/stringLiteral.h"
39 #include "ir/expressions/literals/numberLiteral.h"
40 #include "ir/expressions/functionExpression.h"
41 #include "ir/statement.h"
42 #include "ir/statements/classDeclaration.h"
43 #include "ir/statements/variableDeclarator.h"
44 #include "ir/ts/tsModuleDeclaration.h"
45 #include "ir/ts/tsModuleBlock.h"
46 #include "ir/ts/tsInterfaceBody.h"
47 #include "ir/ts/tsInterfaceDeclaration.h"
48 #include "ir/ts/tsEnumMember.h"
49 #include "ir/ts/tsEnumDeclaration.h"
50 #include "ir/ts/tsTypeParameterInstantiation.h"
51 #include "ir/ts/tsTypeParameterDeclaration.h"
52 #include "ir/ts/tsTypeParameter.h"
53 #include "ir/ts/tsQualifiedName.h"
54 #include "ir/ts/tsTypeReference.h"
55 #include "ir/ts/tsTypeAliasDeclaration.h"
56 #include "ir/ts/tsInterfaceHeritage.h"
57 #include "ir/ts/tsClassImplements.h"
58 #include "ir/ts/tsTypeAssertion.h"
59 #include "util/errorRecovery.h"
60 
61 namespace ark::es2panda::parser {
62 
ParsePotentialAsExpression(ir::Expression * primaryExpression)63 ir::Expression *TypedParser::ParsePotentialAsExpression([[maybe_unused]] ir::Expression *primaryExpression)
64 {
65     return nullptr;
66 }
67 
68 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)69 ir::Expression *TypedParser::ParseExpression(ExpressionParseFlags flags)
70 {
71     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
72         ((flags & ExpressionParseFlags::DISALLOW_YIELD) == 0)) {
73         ir::YieldExpression *yieldExpr = ParseYieldExpression();
74 
75         return ParsePotentialExpressionSequence(yieldExpr, flags);
76     }
77 
78     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
79         const auto startPos = Lexer()->Save();
80 
81         // NOTE(rsipka): ParseTsGenericArrowFunction and ParseTsTypeAssertion might be in a common function
82         ir::Expression *expr = ParseGenericArrowFunction();
83         // NOTE(rsipka): negative cases are not covered, probably this is not a complete solution yet
84         if (expr == nullptr) {
85             Lexer()->Rewind(startPos);
86             expr = ParseTypeAssertion();
87         }
88 
89         return expr;
90     }
91 
92     ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
93     if (unaryExpressionNode == nullptr) {  // Error processing.
94         return nullptr;
95     }
96 
97     if (unaryExpressionNode->IsArrowFunctionExpression()) {
98         return unaryExpressionNode;
99     }
100 
101     ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
102 
103     if (Lexer()->GetToken().NewLine()) {
104         return assignmentExpression;
105     }
106 
107     switch (Lexer()->GetToken().Type()) {
108         case lexer::TokenType::LITERAL_IDENT: {
109             if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) {
110                 return ParsePotentialAsExpression(assignmentExpression);
111             }
112             break;
113         }
114         case lexer::TokenType::PUNCTUATOR_COMMA: {
115             if ((flags & ExpressionParseFlags::ACCEPT_COMMA) != 0) {
116                 return ParseSequenceExpression(assignmentExpression,
117                                                ((flags & ExpressionParseFlags::ACCEPT_REST) != 0));
118             }
119             break;
120         }
121         default: {
122             break;
123         }
124     }
125 
126     return assignmentExpression;
127 }
128 
ParsePotentialExpressionStatement(StatementParsingFlags flags)129 ir::Statement *TypedParser::ParsePotentialExpressionStatement(StatementParsingFlags flags)
130 {
131     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT);
132 
133     switch (Lexer()->GetToken().KeywordType()) {
134         case lexer::TokenType::KEYW_TYPE: {
135             return ParseTypeAliasDeclaration();
136         }
137         case lexer::TokenType::KEYW_ABSTRACT: {
138             Lexer()->NextToken();  // eat abstract keyword
139 
140             if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_CLASS) {
141                 LogSyntaxError(
142                     "abstract modifier can only appear on a class, struct, method, or property declaration.");
143                 if (Lexer()->GetToken().IsKeyword()) {
144                     return ParseExpressionStatement(flags);
145                 }
146                 Lexer()->GetToken().SetTokenType(lexer::TokenType::KEYW_CLASS);
147             }
148 
149             return ParseClassStatement(flags, ir::ClassDefinitionModifiers::NONE, ir::ModifierFlags::ABSTRACT);
150         }
151         case lexer::TokenType::KEYW_GLOBAL:
152         case lexer::TokenType::KEYW_MODULE:
153         case lexer::TokenType::KEYW_NAMESPACE: {
154             return ParseModuleDeclaration();
155         }
156         default: {
157             break;
158         }
159     }
160     return ParseExpressionStatement(flags);
161 }
162 
ParseTypeAssertion()163 ir::TSTypeAssertion *TypedParser::ParseTypeAssertion()
164 {
165     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
166     lexer::SourcePosition start = Lexer()->GetToken().Start();
167     Lexer()->NextToken();  // eat '<'
168 
169     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
170     ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options);
171 
172     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
173         return nullptr;
174     }
175 
176     Lexer()->NextToken();  // eat '>'
177     ir::Expression *expression = ParseExpression();
178     auto *typeAssertion = AllocNode<ir::TSTypeAssertion>(typeAnnotation, expression);
179     typeAssertion->SetRange({start, Lexer()->GetToken().End()});
180 
181     return typeAssertion;
182 }
183 
184 // NOLINTNEXTLINE(google-default-arguments)
ParseModuleDeclaration(StatementParsingFlags flags)185 ir::Statement *TypedParser::ParseModuleDeclaration([[maybe_unused]] StatementParsingFlags flags)
186 {
187     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
188     GetContext().Status() |= ParserStatus::MODULE;
189 
190     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GLOBAL) {
191         return ParseAmbientExternalModuleDeclaration(startLoc);
192     }
193 
194     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NAMESPACE) {
195         Lexer()->NextToken();
196     } else {
197         ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_MODULE);
198         Lexer()->NextToken();
199         if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING) {
200             return ParseAmbientExternalModuleDeclaration(startLoc);
201         }
202     }
203 
204     return ParseModuleOrNamespaceDeclaration(startLoc);
205 }
206 
ParseGenericArrowFunction()207 ir::ArrowFunctionExpression *TypedParser::ParseGenericArrowFunction()
208 {
209     ArrowFunctionContext arrowFunctionContext(this, false);
210 
211     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
212     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
213 
214     auto typeParamDeclOptions = TypeAnnotationParsingOptions::NO_OPTS;
215     ir::TSTypeParameterDeclaration *typeParamDecl = ParseTypeParameterDeclaration(&typeParamDeclOptions);
216 
217     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
218         return nullptr;
219     }
220 
221     FunctionParameterContext funcParamContext(&GetContext());
222     auto params = ParseFunctionParams();
223 
224     ParserStatus arrowStatus = ParserStatus::NO_OPTS;
225 
226     if (std::any_of(params.begin(), params.end(), [](const auto *param) { return !param->IsIdentifier(); })) {
227         arrowStatus = ParserStatus::HAS_COMPLEX_PARAM;
228     }
229 
230     ir::TypeNode *returnTypeAnnotation = nullptr;
231     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
232         Lexer()->NextToken();  // eat ':'
233         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
234         returnTypeAnnotation = ParseTypeAnnotation(&options);
235     }
236 
237     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
238         return nullptr;
239     }
240 
241     ArrowFunctionDescriptor desc(std::move(params), startLoc, arrowStatus);
242 
243     return ParseArrowFunctionExpressionBody(&arrowFunctionContext, &desc, typeParamDecl, returnTypeAnnotation);
244 }
245 
ParseAmbientExternalModuleDeclaration(const lexer::SourcePosition & startLoc)246 ir::TSModuleDeclaration *TypedParser::ParseAmbientExternalModuleDeclaration(const lexer::SourcePosition &startLoc)
247 {
248     bool isGlobal = false;
249     ir::Expression *name = nullptr;
250 
251     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GLOBAL) {
252         isGlobal = true;
253         name = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
254     } else {
255         ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING);
256 
257         if (!InAmbientContext()) {
258             LogSyntaxError("Only ambient modules can use quoted names");
259         }
260 
261         name = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
262     }
263 
264     name->SetRange(Lexer()->GetToken().Loc());
265 
266     Lexer()->NextToken();
267 
268     ir::Statement *body = nullptr;
269     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
270         body = ParseTsModuleBlock();
271     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
272         Lexer()->NextToken();
273     } else {
274         // test exists for ts extension only
275         LogExpectedToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
276         Lexer()->NextToken();
277     }
278 
279     auto *moduleDecl = AllocNode<ir::TSModuleDeclaration>(Allocator(), name, body,
280                                                           ir::TSModuleDeclaration::ConstructorFlags {isGlobal, true});
281     moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()});
282 
283     return moduleDecl;
284 }
285 
ParseModuleOrNamespaceDeclaration(const lexer::SourcePosition & startLoc)286 ir::TSModuleDeclaration *TypedParser::ParseModuleOrNamespaceDeclaration(const lexer::SourcePosition &startLoc)
287 {
288     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
289         LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
290     }
291 
292     auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
293     identNode->SetRange(Lexer()->GetToken().Loc());
294 
295     Lexer()->NextToken();
296 
297     ir::Statement *body = nullptr;
298 
299     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
300         Lexer()->NextToken();
301         lexer::SourcePosition moduleStart = Lexer()->GetToken().Start();
302         body = ParseModuleOrNamespaceDeclaration(moduleStart);
303     } else {
304         body = ParseTsModuleBlock();
305     }
306 
307     auto *moduleDecl = AllocNode<ir::TSModuleDeclaration>(Allocator(), identNode, body,
308                                                           ir::TSModuleDeclaration::ConstructorFlags {false, false});
309     moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()});
310 
311     return moduleDecl;
312 }
313 
ParseTsModuleBlock()314 ir::TSModuleBlock *TypedParser::ParseTsModuleBlock()
315 {
316     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
317         LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
318     }
319 
320     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
321     Lexer()->NextToken();
322     auto statements = ParseStatementList();
323 
324     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
325         // redundant check -> we have it in parse statements
326         // we even do not do lexer_->NextToken() trying to eat '}' after
327         LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
328     }
329 
330     auto *blockNode = AllocNode<ir::TSModuleBlock>(std::move(statements));
331     blockNode->SetRange({startLoc, Lexer()->GetToken().End()});
332 
333     Lexer()->NextToken();
334     return blockNode;
335 }
336 
CheckDeclare()337 void TypedParser::CheckDeclare()
338 {
339     ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE);
340 
341     if (InAmbientContext()) {
342         LogSyntaxError("A 'declare' modifier cannot be used in an already ambient context.");
343     }
344 
345     GetContext().Status() |= ParserStatus::IN_AMBIENT_CONTEXT;
346 
347     Lexer()->NextToken();  // eat 'declare'
348 
349     switch (Lexer()->GetToken().KeywordType()) {
350         case lexer::TokenType::KEYW_VAR:
351         case lexer::TokenType::KEYW_LET:
352         case lexer::TokenType::KEYW_CONST:
353         case lexer::TokenType::KEYW_FUNCTION:
354         case lexer::TokenType::KEYW_CLASS:
355         case lexer::TokenType::KEYW_TYPE:
356         case lexer::TokenType::KEYW_MODULE:
357         case lexer::TokenType::KEYW_GLOBAL:
358         case lexer::TokenType::KEYW_NAMESPACE:
359         case lexer::TokenType::KEYW_ENUM:
360         case lexer::TokenType::KEYW_ABSTRACT:
361         case lexer::TokenType::KEYW_INTERFACE: {
362             return;
363         }
364         default: {
365             LogUnexpectedToken(Lexer()->GetToken().Type());
366         }
367     }
368 }
369 
ParseDecorators(ArenaVector<ir::Decorator * > & decorators)370 void TypedParser::ParseDecorators(ArenaVector<ir::Decorator *> &decorators)
371 {
372     while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) {
373         decorators.push_back(ParseDecorator());
374     }
375 }
376 
ParseFunctionReturnType(ParserStatus status)377 ir::TypeNode *TypedParser::ParseFunctionReturnType(ParserStatus status)
378 {
379     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
380         Lexer()->NextToken();  // eat ':'
381         TypeAnnotationParsingOptions options =
382             TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::RETURN_TYPE;
383         return ParseTypeAnnotation(&options);
384     }
385 
386     if ((status & ParserStatus::NEED_RETURN_TYPE) != 0) {
387         LogSyntaxError("Type expected");
388     }
389 
390     return nullptr;
391 }
392 
ParseInterfaceExtendsElement()393 ir::TypeNode *TypedParser::ParseInterfaceExtendsElement()
394 {
395     const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start();
396     lexer::SourcePosition heritageEnd = Lexer()->GetToken().End();
397     ir::Expression *expr = ParseQualifiedName();
398 
399     if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) {
400         Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
401     }
402 
403     ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
404     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
405         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
406         typeParamInst = ParseTypeParameterInstantiation(&options);
407         heritageEnd = typeParamInst->End();
408     }
409 
410     if (expr == nullptr) {  // Error rocessing.
411         return nullptr;
412     }
413 
414     auto *typeReference = AllocNode<ir::TSTypeReference>(expr, typeParamInst);
415     typeReference->SetRange({heritageStart, heritageEnd});
416     return typeReference;
417 }
418 
ParseInterfaceExtendsClause()419 ArenaVector<ir::TSInterfaceHeritage *> TypedParser::ParseInterfaceExtendsClause()
420 {
421     Lexer()->NextToken();  // eat extends keyword
422 
423     ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
424 
425     while (true) {
426         auto *typeReference = ParseInterfaceExtendsElement();
427         if (typeReference != nullptr) {  // Error processing.
428             auto *heritage = AllocNode<ir::TSInterfaceHeritage>(typeReference);
429             heritage->SetRange(typeReference->Range());
430             extends.push_back(heritage);
431         }
432 
433         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE ||
434             Lexer()->GetToken().Type() == lexer::TokenType::EOS) {
435             break;
436         }
437 
438         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
439             LogExpectedToken(lexer::TokenType::PUNCTUATOR_COMMA);
440         }
441 
442         Lexer()->NextToken();
443     }
444 
445     return extends;
446 }
447 
ParseFunctionTypeParameters()448 ir::TSTypeParameterDeclaration *TypedParser::ParseFunctionTypeParameters()
449 {
450     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
451         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
452         return ParseTypeParameterDeclaration(&options);
453     }
454 
455     return nullptr;
456 }
457 
ParseInterfaceDeclaration(bool isStatic)458 ir::Statement *TypedParser::ParseInterfaceDeclaration(bool isStatic)
459 {
460     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_INTERFACE);
461     GetContext().Status() |= ParserStatus::ALLOW_THIS_TYPE;
462     lexer::SourcePosition interfaceStart = Lexer()->GetToken().Start();
463     Lexer()->NextToken();  // eat interface keyword
464 
465     auto id = ExpectIdentifier(true);
466     if (id == nullptr) {  // Error processing.
467         return nullptr;
468     }
469 
470     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
471     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
472         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
473         typeParamDecl = ParseTypeParameterDeclaration(&options);
474     }
475 
476     ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter());
477     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) {
478         extends = ParseInterfaceExtendsClause();
479     }
480 
481     lexer::SourcePosition bodyStart = Lexer()->GetToken().Start();
482     auto members = ParseTypeLiteralOrInterface();
483 
484     auto *body = AllocNode<ir::TSInterfaceBody>(std::move(members));
485     body->SetRange({bodyStart, Lexer()->GetToken().End()});
486 
487     const auto isExternal = IsExternal();
488     auto *interfaceDecl = AllocNode<ir::TSInterfaceDeclaration>(
489         Allocator(), std::move(extends),
490         ir::TSInterfaceDeclaration::ConstructorData {id, typeParamDecl, body, isStatic, isExternal,
491                                                      GetContext().GetLanguage()});
492     interfaceDecl->SetRange({interfaceStart, Lexer()->GetToken().End()});
493 
494     Lexer()->NextToken();
495     GetContext().Status() &= ~ParserStatus::ALLOW_THIS_TYPE;
496 
497     return interfaceDecl;
498 }
499 
GetTSPropertyName(ir::Expression * key)500 static util::StringView GetTSPropertyName(ir::Expression *key)
501 {
502     switch (key->Type()) {
503         case ir::AstNodeType::IDENTIFIER: {
504             return key->AsIdentifier()->Name();
505         }
506         case ir::AstNodeType::NUMBER_LITERAL: {
507             return key->AsNumberLiteral()->Str();
508         }
509         case ir::AstNodeType::STRING_LITERAL: {
510             return key->AsStringLiteral()->Str();
511         }
512         default: {
513             UNREACHABLE();
514         }
515     }
516 }
517 
CheckObjectTypeForDuplicatedProperties(ir::Expression * key,ArenaVector<ir::AstNode * > & members)518 void TypedParser::CheckObjectTypeForDuplicatedProperties(ir::Expression *key, ArenaVector<ir::AstNode *> &members)
519 {
520     if (!key->IsIdentifier() && !key->IsNumberLiteral() && !key->IsStringLiteral()) {
521         return;
522     }
523 
524     for (auto *it : members) {
525         ir::Expression *compare = nullptr;
526 
527         switch (it->Type()) {
528             case ir::AstNodeType::TS_PROPERTY_SIGNATURE: {
529                 compare = it->AsTSPropertySignature()->Key();
530                 break;
531             }
532             case ir::AstNodeType::TS_METHOD_SIGNATURE: {
533                 compare = it->AsTSMethodSignature()->Key();
534                 break;
535             }
536             default: {
537                 continue;
538             }
539         }
540 
541         if (!compare->IsIdentifier() && !compare->IsNumberLiteral() && !compare->IsStringLiteral()) {
542             continue;
543         }
544 
545         if (GetTSPropertyName(key) == GetTSPropertyName(compare)) {
546             LogSyntaxError("Duplicated identifier", key->Start());
547         }
548     }
549 }
550 
ParseTypeLiteralOrInterfaceBody()551 ArenaVector<ir::AstNode *> TypedParser::ParseTypeLiteralOrInterfaceBody()
552 {
553     ArenaVector<ir::AstNode *> members(Allocator()->Adapter());
554 
555     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
556            Lexer()->GetToken().Type() != lexer::TokenType::EOS) {
557         util::ErrorRecursionGuard infiniteLoopBlocker(Lexer());
558 
559         ir::AstNode *member = ParseTypeLiteralOrInterfaceMember();
560         // Error processing.
561         if (member == nullptr || (member->IsMethodDefinition() && member->AsMethodDefinition()->Function() != nullptr &&
562                                   member->AsMethodDefinition()->Function()->IsOverload() &&
563                                   member->AsMethodDefinition()->Function()->Body() != nullptr)) {
564             continue;
565         }
566 
567         if (member->IsTSPropertySignature()) {
568             CheckObjectTypeForDuplicatedProperties(member->AsTSPropertySignature()->Key(), members);
569         } else if (member->IsTSMethodSignature()) {
570             CheckObjectTypeForDuplicatedProperties(member->AsTSMethodSignature()->Key(), members);
571         }
572 
573         members.push_back(member);
574 
575         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
576             break;
577         }
578 
579         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
580             Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
581             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
582                 LogSyntaxError("Interface member initialization is prohibited");
583                 Lexer()->NextToken();  // Error processing.
584             }
585             if (!Lexer()->GetToken().NewLine()) {
586                 LogExpectedToken(lexer::TokenType::PUNCTUATOR_COMMA);
587             }
588 
589             if (Lexer()->GetToken().IsKeyword() && ((Lexer()->GetToken().Type() != lexer::TokenType::KEYW_STATIC) &&
590                                                     (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PRIVATE))) {
591                 Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
592                 Lexer()->GetToken().SetTokenStr(ERROR_LITERAL);
593             }
594 
595             continue;
596         }
597 
598         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
599     }
600 
601     return members;
602 }
603 
ParseTypeLiteralOrInterface()604 ArenaVector<ir::AstNode *> TypedParser::ParseTypeLiteralOrInterface()
605 {
606     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPLEMENTS) {
607         LogSyntaxError("Interface declaration cannot have 'implements' clause.");
608         Lexer()->NextToken();         // eat 'implements'
609         ParseClassImplementClause();  // Try to parse implements, but drop the result;
610     }
611 
612     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
613         LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
614     }
615 
616     Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
617 
618     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_OVERRIDE) {
619         LogSyntaxError("'override' modifier cannot appear in interfaces");
620         Lexer()->NextToken();  // eat 'override'
621     }
622 
623     bool const formattedParsing = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
624                                   Lexer()->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE);
625 
626     ArenaVector<ir::AstNode *> members =
627         !formattedParsing ? ParseTypeLiteralOrInterfaceBody() : std::move(ParseAstNodesArrayFormatPlaceholder());
628 
629     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
630         // redundant check since we have the same check
631         // in ParseTypeLiteralOrInterfaceBody() above
632         LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
633     }
634 
635     return members;
636 }
637 
ParseEnumMembers(ir::Identifier * key,const lexer::SourcePosition & enumStart,bool isConst,bool isStatic)638 ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const lexer::SourcePosition &enumStart,
639                                                      bool isConst, [[maybe_unused]] bool isStatic)
640 {
641     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
642         // test exists for ts extension only
643         LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
644     }
645 
646     ArenaVector<ir::AstNode *> members(Allocator()->Adapter());
647     Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat '{'
648 
649     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
650         ir::Expression *memberKey = nullptr;
651 
652         if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
653             memberKey = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
654             memberKey->SetRange(Lexer()->GetToken().Loc());
655         } else if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING) {
656             memberKey = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String());
657             memberKey->SetRange(Lexer()->GetToken().Loc());
658         } else {
659             LogSyntaxError("Unexpected token in enum member");
660             // Consider that the current token is a memberKey and skip it.
661         }
662 
663         Lexer()->NextToken();  // eat memberKey
664 
665         ir::Expression *memberInit = nullptr;
666         lexer::SourcePosition initStart = Lexer()->GetToken().Start();
667 
668         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
669             Lexer()->NextToken();  // eat '='
670             initStart = Lexer()->GetToken().Start();
671             memberInit = ParseExpression();
672         }
673 
674         if (memberKey != nullptr) {  // Error processing.
675             auto *member = AllocNode<ir::TSEnumMember>(memberKey, memberInit);
676             member->SetRange({initStart, Lexer()->GetToken().End()});
677             members.push_back(member);
678         }
679 
680         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
681             Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat ','
682         }
683     }
684 
685     auto *enumDeclaration = AllocNode<ir::TSEnumDeclaration>(Allocator(), key, std::move(members),
686                                                              ir::TSEnumDeclaration::ConstructorFlags {isConst});
687     enumDeclaration->SetRange({enumStart, Lexer()->GetToken().End()});
688     Lexer()->NextToken();  // eat '}'
689 
690     return enumDeclaration;
691 }
692 
693 // NOLINTNEXTLINE(google-default-arguments)
ParseEnumDeclaration(bool isConst,bool isStatic)694 ir::Statement *TypedParser::ParseEnumDeclaration(bool isConst, [[maybe_unused]] bool isStatic)
695 {
696     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_ENUM);
697     lexer::SourcePosition enumStart = Lexer()->GetToken().Start();
698     Lexer()->NextToken();  // eat enum keyword
699     auto *key = ExpectIdentifier(true);
700     auto *declNode = ParseEnumMembers(key, enumStart, isConst, false);
701     return declNode;
702 }
703 
ParseTypeParameter(TypeAnnotationParsingOptions * options)704 ir::TSTypeParameter *TypedParser::ParseTypeParameter(TypeAnnotationParsingOptions *options)
705 {
706     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
707     bool reportError = ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0;
708 
709     if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT || Lexer()->GetToken().IsDefinableTypeName()) {
710         if (!reportError) {
711             return nullptr;
712         }
713 
714         LogSyntaxError("Type parameter declaration expected");
715         return nullptr;
716     }
717 
718     if (reportError) {
719         CheckIfTypeParameterNameIsReserved();
720     }
721 
722     const auto &ident = Lexer()->GetToken().Ident();
723     auto *paramIdent = AllocNode<ir::Identifier>(ident, Allocator());
724 
725     paramIdent->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()});
726 
727     Lexer()->NextToken();
728 
729     TypeAnnotationParsingOptions newOptions = TypeAnnotationParsingOptions::NO_OPTS;
730 
731     if (reportError) {
732         newOptions |= TypeAnnotationParsingOptions::REPORT_ERROR;
733     }
734 
735     ir::TypeNode *constraint = nullptr;
736     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) {
737         Lexer()->NextToken();
738         constraint = ParseTypeAnnotation(&newOptions);
739     }
740 
741     ir::TypeNode *defaultType = nullptr;
742     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
743         Lexer()->NextToken();
744         defaultType = ParseTypeAnnotation(&newOptions);
745     }
746 
747     auto *typeParam = AllocNode<ir::TSTypeParameter>(paramIdent, constraint, defaultType);
748 
749     typeParam->SetRange({startLoc, Lexer()->GetToken().End()});
750 
751     return typeParam;
752 }
753 
754 //  Auxiliary method to reduce the size of functions.
ParseTypeParameterDeclarationImpl(TypeAnnotationParsingOptions * options)755 ir::AstNode *TypedParser::ParseTypeParameterDeclarationImpl(TypeAnnotationParsingOptions *options)
756 {
757     ArenaVector<ir::TSTypeParameter *> params(Allocator()->Adapter());
758     bool seenDefault = false;
759     size_t requiredParams = 0U;
760 
761     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
762         auto newOptions = *options | TypeAnnotationParsingOptions::ADD_TYPE_PARAMETER_BINDING;
763         ir::TSTypeParameter *currentParam = ParseTypeParameter(&newOptions);
764 
765         if (currentParam == nullptr) {
766             // Maybe error processing.
767             return nullptr;
768         }
769 
770         if (currentParam->DefaultType() != nullptr) {
771             seenDefault = true;
772         } else if (seenDefault) {
773             LogSyntaxError("Required type parameters may not follow optional type parameters.");
774         } else {
775             requiredParams++;
776         }
777 
778         params.push_back(currentParam);
779 
780         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) {
781             break;
782         }
783 
784         Lexer()->NextToken();
785     }
786 
787     if (params.empty()) {
788         LogSyntaxError("Type parameter list cannot be empty.");
789     }
790 
791     return AllocNode<ir::TSTypeParameterDeclaration>(std::move(params), requiredParams);
792 }
793 
ParseTypeParameterDeclaration(TypeAnnotationParsingOptions * options)794 ir::TSTypeParameterDeclaration *TypedParser::ParseTypeParameterDeclaration(TypeAnnotationParsingOptions *options)
795 {
796     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
797 
798     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
799     Lexer()->NextToken();  // eat '<'
800 
801     ir::AstNode *typeParamDecl;
802 
803     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
804         Lexer()->Lookahead() == static_cast<char32_t>(EXPRESSION_FORMAT_NODE)) {
805         typeParamDecl = ParseTypeParametersFormatPlaceholder();
806     } else {
807         typeParamDecl = ParseTypeParameterDeclarationImpl(options);
808     }
809 
810     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
811         if ((*options & TypeAnnotationParsingOptions::REPORT_ERROR) == 0) {
812             return nullptr;
813         }
814         LogExpectedToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN);
815     }
816 
817     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
818     Lexer()->NextToken();  // eat '>'
819 
820     if (typeParamDecl != nullptr) {
821         typeParamDecl->SetRange({startLoc, endLoc});
822         return typeParamDecl->AsTSTypeParameterDeclaration();
823     }
824 
825     return nullptr;
826 }
827 
ParseSuperClassReference()828 ir::Expression *TypedParser::ParseSuperClassReference()
829 {
830     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) {
831         Lexer()->NextToken();
832 
833         return ParseLeftHandSideExpression();
834     }
835 
836     return nullptr;
837 }
838 
ParseSuperClass()839 std::tuple<ir::Expression *, ir::TSTypeParameterInstantiation *> TypedParser::ParseSuperClass()
840 {
841     ir::Expression *superClass = ParseSuperClassReference();
842 
843     ir::TSTypeParameterInstantiation *superTypeParams = nullptr;
844     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
845         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
846         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
847             Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
848         }
849 
850         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
851         superTypeParams = ParseTypeParameterInstantiation(&options);
852     }
853 
854     return {superClass, superTypeParams};
855 }
856 
ParseClassImplementsElement()857 std::tuple<ir::Expression *, ir::TSTypeParameterInstantiation *> TypedParser::ParseClassImplementsElement()
858 {
859     ir::Expression *expr = ParseQualifiedName();
860 
861     ir::TSTypeParameterInstantiation *implTypeParams = nullptr;
862     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN ||
863         Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
864         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
865             Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
866         }
867 
868         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
869         implTypeParams = ParseTypeParameterInstantiation(&options);
870     }
871 
872     return {expr, implTypeParams};
873 }
874 
ParseClassImplementClause()875 ArenaVector<ir::TSClassImplements *> TypedParser::ParseClassImplementClause()
876 {
877     ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
878 
879     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
880         lexer::SourcePosition implStart = Lexer()->GetToken().Start();
881         auto [expr, implTypeParams] = ParseClassImplementsElement();
882         if (expr != nullptr) {  // Error processing.
883             auto *impl = AllocNode<ir::TSClassImplements>(expr, implTypeParams);
884             impl->SetRange({implStart, Lexer()->GetToken().End()});
885             implements.push_back(impl);
886         }
887 
888         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
889             Lexer()->NextToken();
890             continue;
891         }
892 
893         if (InAmbientContext()) {
894             break;
895         }
896 
897         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
898             LogExpectedToken(lexer::TokenType::PUNCTUATOR_COMMA);
899             break;  // Force to leave the 'implements' context.
900         }
901     }
902 
903     if (implements.empty()) {
904         LogSyntaxError("Implements clause can not be empty");
905     }
906 
907     return implements;
908 }
909 
CheckClassElementInterfaceBody(ir::AstNode * property,ArenaVector<ir::AstNode * > & properties)910 bool TypedParser::CheckClassElementInterfaceBody(ir::AstNode *property, ArenaVector<ir::AstNode *> &properties)
911 {
912     for (auto *it : property->AsTSInterfaceBody()->Body()) {
913         properties.push_back(it);
914     }
915 
916     return true;
917 }
918 
CheckClassElement(ir::AstNode * property,ir::MethodDefinition * & ctor,ArenaVector<ir::AstNode * > & properties)919 bool TypedParser::CheckClassElement(ir::AstNode *property, ir::MethodDefinition *&ctor,
920                                     [[maybe_unused]] ArenaVector<ir::AstNode *> &properties)
921 {
922     if (property->IsTSInterfaceBody()) {
923         return CheckClassElementInterfaceBody(property, properties);
924     }
925 
926     return ParserImpl::CheckClassElement(property, ctor, properties);
927 }
928 
929 // NOLINTNEXTLINE(google-default-arguments)
ParseClassDefinition(ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)930 ir::ClassDefinition *TypedParser::ParseClassDefinition(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags)
931 {
932     Lexer()->NextToken();
933 
934     ir::Identifier *identNode = ParseClassIdent(modifiers);
935 
936     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
937     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
938         auto options = TypeAnnotationParsingOptions::REPORT_ERROR;
939         typeParamDecl = ParseTypeParameterDeclaration(&options);
940     }
941 
942     varbinder::PrivateBinding privateBinding(Allocator(), ClassId()++);
943 
944     // Parse SuperClass
945     auto [superClass, superTypeParams] = ParseSuperClass();
946 
947     if (superClass != nullptr) {
948         modifiers |= ir::ClassDefinitionModifiers::HAS_SUPER;
949     }
950 
951     // Parse implements clause
952     ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
953     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IMPLEMENTS) {
954         Lexer()->NextToken();
955         implements = ParseClassImplementClause();
956     }
957 
958     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false);
959 
960     // Parse ClassBody
961     auto [ctor, properties, bodyRange] = ParseClassBody(modifiers, flags);
962 
963     if (InAmbientContext()) {
964         flags |= ir::ModifierFlags::DECLARE;
965     }
966 
967     auto *classDefinition = AllocNode<ir::ClassDefinition>(
968         privateBinding.View(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass,
969         std::move(properties), modifiers, flags, GetContext().GetLanguage());
970 
971     classDefinition->SetRange(bodyRange);
972 
973     return classDefinition;
974 }
975 
ValidateIndexSignatureTypeAnnotation(ir::TypeNode * typeAnnotation)976 void TypedParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation)
977 {
978     if (typeAnnotation == nullptr) {
979         LogSyntaxError("An index signature must have a type annotation");
980     }
981 }
982 
ParseProperty(const ArenaVector<ir::AstNode * > & properties,ClassElementDescriptor & desc,ir::Expression * propName)983 ir::AstNode *TypedParser::ParseProperty(const ArenaVector<ir::AstNode *> &properties, ClassElementDescriptor &desc,
984                                         ir::Expression *propName)
985 {
986     ir::AstNode *property = nullptr;
987     ir::TypeNode *typeAnnotation = ParseClassKeyAnnotation();
988 
989     if (desc.isIndexSignature) {
990         if (!desc.decorators.empty()) {
991             LogSyntaxError("Decorators are not valid here.", desc.decorators.front()->Start());
992         }
993 
994         ValidateIndexSignatureTypeAnnotation(typeAnnotation);
995 
996         if ((desc.modifiers & ir::ModifierFlags::DECLARE) != 0) {
997             LogSyntaxError("'declare' modifier cannot appear on an index signature.");
998         }
999 
1000         property =
1001             AllocNode<ir::TSIndexSignature>(propName, typeAnnotation, desc.modifiers & ir::ModifierFlags::READONLY);
1002 
1003         property->SetRange({property->AsTSIndexSignature()->Param()->Start(),
1004                             property->AsTSIndexSignature()->TypeAnnotation()->End()});
1005     } else {
1006         ValidateClassMethodStart(&desc, typeAnnotation);
1007         property = ParseClassProperty(&desc, properties, propName, typeAnnotation);
1008 
1009         if (!desc.decorators.empty()) {
1010             if (desc.isPrivateIdent) {
1011                 LogSyntaxError("Decorators are not valid here");
1012             }
1013 
1014             property->AddDecorators(std::move(desc.decorators));
1015         }
1016     }
1017 
1018     ASSERT(property != nullptr);
1019     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
1020         Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
1021         ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) == 0) &&
1022         !(property->IsMethodDefinition() &&
1023           property->AsMethodDefinition()->Value()->AsFunctionExpression()->Function()->Body() != nullptr)) {
1024         LogExpectedToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
1025     }
1026 
1027     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) {
1028         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1029     }
1030 
1031     GetContext().Status() &= ~ParserStatus::ALLOW_THIS_TYPE;
1032 
1033     if (desc.isPrivateIdent) {
1034         AddPrivateElement(property->AsClassElement());
1035     }
1036 
1037     return property;
1038 }
1039 
ParseClassElement(const ArenaVector<ir::AstNode * > & properties,ir::ClassDefinitionModifiers modifiers,ir::ModifierFlags flags)1040 ir::AstNode *TypedParser::ParseClassElement(const ArenaVector<ir::AstNode *> &properties,
1041                                             ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags)
1042 {
1043     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_STATIC &&
1044         Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_BRACE) {
1045         return ParseClassStaticBlock();
1046     }
1047 
1048     ClassElementDescriptor desc(Allocator());
1049 
1050     desc.methodKind = ir::MethodDefinitionKind::METHOD;
1051     desc.newStatus = ParserStatus::ALLOW_SUPER;
1052     desc.hasSuperClass = (modifiers & ir::ClassDefinitionModifiers::HAS_SUPER) != 0;
1053     desc.propStart = Lexer()->GetToken().Start();
1054 
1055     ParseDecorators(desc.decorators);
1056 
1057     desc.modifiers = ParseModifiers();
1058 
1059     if (((desc.modifiers & ir::ModifierFlags::ABSTRACT) != 0) && ((flags & ir::ModifierFlags::ABSTRACT) == 0)) {
1060         LogSyntaxError("Abstract methods can only appear within an abstract class.");
1061     }
1062 
1063     char32_t nextCp = Lexer()->Lookahead();
1064     CheckClassGeneratorMethod(&desc, &nextCp);
1065     ParseClassAccessor(&desc, &nextCp);
1066 
1067     if ((desc.modifiers & ir::ModifierFlags::STATIC) == 0) {
1068         GetContext().Status() |= ParserStatus::ALLOW_THIS_TYPE;
1069     }
1070 
1071     ir::Expression *propName = ParseClassKey(&desc);
1072     if (propName == nullptr) {  // Error processing.
1073         return nullptr;
1074     }
1075 
1076     if (desc.methodKind == ir::MethodDefinitionKind::CONSTRUCTOR && !desc.decorators.empty()) {
1077         LogSyntaxError("Decorators are not valid here.", desc.decorators.front()->Start());
1078     }
1079 
1080     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1081         ParseOptionalClassElement(&desc);
1082     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) {
1083         if (desc.isIndexSignature || Lexer()->Lookahead() != lexer::LEX_CHAR_COLON) {
1084             // test exists for ts extension only
1085             LogExpectedToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);
1086         }
1087 
1088         desc.modifiers |= ir::ModifierFlags::DEFINITE;
1089         Lexer()->NextToken();
1090     }
1091 
1092     return ParseProperty(properties, desc, propName);
1093 }
1094 
ParseOptionalClassElement(ClassElementDescriptor * desc)1095 void TypedParser::ParseOptionalClassElement(ClassElementDescriptor *desc)
1096 {
1097     if (desc->isIndexSignature) {
1098         LogExpectedToken(lexer::TokenType::PUNCTUATOR_SEMI_COLON);  // no test
1099     }
1100 
1101     if (desc->methodKind == ir::MethodDefinitionKind::CONSTRUCTOR) {
1102         // test exists for ts extension only
1103         LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1104     }
1105 
1106     desc->modifiers |= ir::ModifierFlags::OPTIONAL;
1107     Lexer()->NextToken();
1108 }
1109 
ParseActualNextStatus(lexer::TokenType keywordType)1110 static std::pair<ir::ModifierFlags, ir::ModifierFlags> ParseActualNextStatus(lexer::TokenType keywordType)
1111 {
1112     constexpr auto ASYNC_STATIC_READONLY =
1113         ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY;
1114     constexpr auto ASYNC_STATIC_READONLY_AMBIENT_ABSTRACT =
1115         ASYNC_STATIC_READONLY | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT;
1116 
1117     switch (keywordType) {
1118         case lexer::TokenType::KEYW_PUBLIC:
1119             return {ir::ModifierFlags::PUBLIC, ASYNC_STATIC_READONLY_AMBIENT_ABSTRACT};
1120         case lexer::TokenType::KEYW_PRIVATE:
1121             return {ir::ModifierFlags::PRIVATE, ASYNC_STATIC_READONLY_AMBIENT_ABSTRACT};
1122         case lexer::TokenType::KEYW_PROTECTED:
1123             return {ir::ModifierFlags::PROTECTED, ASYNC_STATIC_READONLY_AMBIENT_ABSTRACT};
1124         case lexer::TokenType::KEYW_INTERNAL:
1125             return {ir::ModifierFlags::INTERNAL, ASYNC_STATIC_READONLY_AMBIENT_ABSTRACT | ir::ModifierFlags::PROTECTED};
1126         case lexer::TokenType::KEYW_STATIC:
1127             return {ir::ModifierFlags::STATIC, ir::ModifierFlags::ASYNC | ir::ModifierFlags::READONLY |
1128                                                    ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT};
1129         case lexer::TokenType::KEYW_ASYNC:
1130             return {ir::ModifierFlags::ASYNC,
1131                     ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT};
1132         case lexer::TokenType::KEYW_ABSTRACT:
1133             return {ir::ModifierFlags::ABSTRACT,
1134                     ASYNC_STATIC_READONLY | ir::ModifierFlags::ACCESS | ir::ModifierFlags::DECLARE};
1135         case lexer::TokenType::KEYW_DECLARE:
1136             return {ir::ModifierFlags::DECLARE, ASYNC_STATIC_READONLY | ir::ModifierFlags::ACCESS};
1137         case lexer::TokenType::KEYW_READONLY:
1138             return {ir::ModifierFlags::READONLY,
1139                     ir::ModifierFlags::ASYNC | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT};
1140         default:
1141             UNREACHABLE();
1142     }
1143 }
1144 
ParseModifiers()1145 ir::ModifierFlags TypedParser::ParseModifiers()
1146 {
1147     ir::ModifierFlags resultStatus = ir::ModifierFlags::NONE;
1148     ir::ModifierFlags prevStatus = ir::ModifierFlags::ALL;
1149 
1150     while (IsModifierKind(Lexer()->GetToken())) {
1151         char32_t nextCp = Lexer()->Lookahead();
1152         if (!(nextCp != lexer::LEX_CHAR_EQUALS && nextCp != lexer::LEX_CHAR_SEMICOLON &&
1153               nextCp != lexer::LEX_CHAR_COMMA && nextCp != lexer::LEX_CHAR_LEFT_PAREN)) {
1154             break;
1155         }
1156 
1157         lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags();
1158         if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) {
1159             LogSyntaxError("Keyword must not contain escaped characters");
1160         }
1161 
1162         auto [actualStatus, nextStatus] = ParseActualNextStatus(Lexer()->GetToken().KeywordType());
1163 
1164         nextCp = Lexer()->Lookahead();
1165         if (nextCp == lexer::LEX_CHAR_COLON || nextCp == lexer::LEX_CHAR_COMMA ||
1166             nextCp == lexer::LEX_CHAR_RIGHT_PAREN || nextCp == lexer::LEX_CHAR_QUESTION ||
1167             nextCp == lexer::LEX_CHAR_RIGHT_BRACE || nextCp == lexer::LEX_CHAR_LESS_THAN) {
1168             break;
1169         }
1170 
1171         if ((prevStatus & actualStatus) == 0) {
1172             LogSyntaxError("Unexpected modifier");
1173         }
1174 
1175         if ((resultStatus & actualStatus) != 0) {
1176             LogSyntaxError("Duplicated modifier is not allowed");
1177         }
1178 
1179         if ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0 &&
1180             (actualStatus & ~ir::ModifierFlags::ALLOWED_IN_CTOR_PARAMETER) != 0) {
1181             LogParameterModifierError(actualStatus);
1182         }
1183 
1184         Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
1185 
1186         resultStatus |= actualStatus;
1187         prevStatus = nextStatus;
1188     }
1189 
1190     return resultStatus;
1191 }
1192 
ParseQualifiedName(ExpressionParseFlags flags)1193 ir::Expression *TypedParser::ParseQualifiedName(ExpressionParseFlags flags)
1194 {
1195     ir::Expression *expr = nullptr;
1196 
1197     switch (Lexer()->GetToken().Type()) {
1198         case lexer::TokenType::PUNCTUATOR_FORMAT:
1199             expr = ParseIdentifierFormatPlaceholder(std::nullopt);
1200             break;
1201         case lexer::TokenType::LITERAL_IDENT:
1202             expr = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1203             expr->SetRange(Lexer()->GetToken().Loc());
1204             Lexer()->NextToken();
1205             break;
1206         default:
1207             if ((flags & ExpressionParseFlags::POTENTIAL_NEW_ARRAY) != 0) {
1208                 return expr;
1209             }
1210             LogSyntaxError("Identifier expected");
1211             return nullptr;
1212     }
1213 
1214     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
1215         expr = ParseQualifiedReference(expr, flags);
1216     }
1217 
1218     return expr;
1219 }
1220 
ParseLiteralIndent(ir::Expression * typeName,ExpressionParseFlags flags,const lexer::SourcePosition & startLoc)1221 ir::Expression *TypedParser::ParseLiteralIndent(ir::Expression *typeName, ExpressionParseFlags flags,
1222                                                 const lexer::SourcePosition &startLoc)
1223 {
1224     if ((flags & ExpressionParseFlags::POTENTIAL_CLASS_LITERAL) != 0) {
1225         if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS) {
1226             typeName->SetRange({startLoc, Lexer()->GetToken().End()});
1227             return typeName;
1228         }
1229         if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS) {
1230             return static_cast<ir::Expression *>(nullptr);
1231         }
1232     }
1233 
1234     LogSyntaxError("Identifier expected");
1235     return nullptr;
1236 }
1237 
ParseQualifiedReference(ir::Expression * typeName,ExpressionParseFlags flags)1238 ir::Expression *TypedParser::ParseQualifiedReference(ir::Expression *typeName, ExpressionParseFlags flags)
1239 {
1240     lexer::SourcePosition startLoc = typeName->Start();
1241 
1242     do {
1243         Lexer()->NextToken();  // eat '.'
1244 
1245         ir::Identifier *propName {};
1246         if ((flags & ExpressionParseFlags::IMPORT) != 0 &&
1247             Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1248             Lexer()->NextToken();  // eat '*'
1249             propName = AllocNode<ir::Identifier>(varbinder::VarBinder::STAR_IMPORT, Allocator());
1250         } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT) {
1251             propName = ParseIdentifierFormatPlaceholder(std::nullopt);
1252         } else if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1253             return ParseLiteralIndent(typeName, flags, startLoc);
1254         } else {
1255             propName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator());
1256         }
1257 
1258         propName->SetRange(Lexer()->GetToken().Loc());
1259 
1260         typeName = AllocNode<ir::TSQualifiedName>(typeName, propName);
1261         typeName->SetRange({typeName->AsTSQualifiedName()->Left()->Start(), Lexer()->GetToken().End()});
1262 
1263         if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
1264             Lexer()->NextToken();
1265         }
1266     } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD);
1267 
1268     typeName->SetRange({startLoc, Lexer()->GetToken().End()});
1269 
1270     return typeName;
1271 }
1272 
1273 //  Auxiliary method to reduce the size of functions.
ParseTypeParameterInstantiationImpl(TypeAnnotationParsingOptions * options)1274 ir::AstNode *TypedParser::ParseTypeParameterInstantiationImpl(TypeAnnotationParsingOptions *options)
1275 {
1276     ArenaVector<ir::TypeNode *> params(Allocator()->Adapter());
1277 
1278     while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1279         TypeAnnotationParsingOptions tmpOptions = *options &= ~TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE;
1280         // Need to parse correctly the cases like `x: T|C<T|U>`
1281         tmpOptions &= ~TypeAnnotationParsingOptions::DISALLOW_UNION;
1282         ir::TypeNode *currentParam = ParseTypeAnnotation(&tmpOptions);
1283 
1284         if (currentParam == nullptr) {
1285             return nullptr;
1286         }
1287 
1288         params.push_back(currentParam);
1289 
1290         switch (Lexer()->GetToken().Type()) {
1291             case lexer::TokenType::PUNCTUATOR_COMMA: {
1292                 Lexer()->NextToken();
1293                 continue;
1294             }
1295             case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: {
1296                 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 1);
1297                 break;
1298             }
1299             case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
1300                 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 2U);
1301                 break;
1302             }
1303             case lexer::TokenType::PUNCTUATOR_GREATER_THAN: {
1304                 break;
1305             }
1306             default: {
1307                 return nullptr;
1308             }
1309         }
1310     }
1311 
1312     return AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
1313 }
1314 
ParseTypeParameterInstantiation(TypeAnnotationParsingOptions * options)1315 ir::TSTypeParameterInstantiation *TypedParser::ParseTypeParameterInstantiation(TypeAnnotationParsingOptions *options)
1316 {
1317     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN);
1318 
1319     const bool inPotentialNewArray = (*options & TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY) != 0;
1320     *options &= ~TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY;
1321     lexer::SourcePosition startLoc = Lexer()->GetToken().Start();
1322     Lexer()->NextToken();  // eat '<'
1323 
1324     ir::AstNode *typeParamInst;
1325     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
1326         Lexer()->Lookahead() == static_cast<char32_t>(EXPRESSION_FORMAT_NODE)) {
1327         typeParamInst = ParseTypeParametersFormatPlaceholder();
1328     } else {
1329         typeParamInst = ParseTypeParameterInstantiationImpl(options);
1330     }
1331 
1332     if (inPotentialNewArray) {
1333         *options |= TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY;
1334     }
1335 
1336     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) {
1337         if ((*options & TypeAnnotationParsingOptions::REPORT_ERROR) == 0) {
1338             return nullptr;
1339         }
1340         LogExpectedToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN);
1341     }
1342 
1343     lexer::SourcePosition endLoc = Lexer()->GetToken().End();
1344     Lexer()->NextToken();  // eat '>'
1345 
1346     if (typeParamInst != nullptr) {
1347         typeParamInst->SetRange({startLoc, endLoc});
1348         return typeParamInst->AsTSTypeParameterInstantiation();
1349     }
1350 
1351     return nullptr;
1352 }
1353 
ParseDeclareAndDecorators(StatementParsingFlags flags)1354 ir::Statement *TypedParser::ParseDeclareAndDecorators(StatementParsingFlags flags)
1355 {
1356     ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter());
1357 
1358     ParseDecorators(decorators);
1359 
1360     if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) {
1361         CheckDeclare();
1362     }
1363 
1364     ir::Statement *stmt = TypedParser::ParseStatement(flags);
1365 
1366     GetContext().Status() &= ~ParserStatus::IN_AMBIENT_CONTEXT;
1367     if (stmt != nullptr) {  // Error processing.
1368         AddDecorators(stmt, decorators);
1369     }
1370 
1371     return stmt;
1372 }
1373 
ConvertThisKeywordToIdentIfNecessary()1374 void TypedParser::ConvertThisKeywordToIdentIfNecessary()
1375 {
1376     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS) {
1377         Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT);
1378         Lexer()->GetToken().SetTokenStr(ERROR_LITERAL);
1379     }
1380 }
1381 
ParseVariableDeclarator(ir::Expression * init,lexer::SourcePosition startLoc,VariableParsingFlags flags)1382 ir::VariableDeclarator *TypedParser::ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc,
1383                                                              VariableParsingFlags flags)
1384 {
1385     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1386         return ParseVariableDeclaratorInitializer(init, flags, startLoc);
1387     }
1388 
1389     if (((flags & VariableParsingFlags::CONST) != 0) && ((flags & VariableParsingFlags::ACCEPT_CONST_NO_INIT) == 0) &&
1390         !InAmbientContext()) {
1391         LogSyntaxError("Missing initializer in const declaration");
1392     }
1393 
1394     if (((flags & VariableParsingFlags::IN_FOR) == 0) && (init->IsArrayPattern() || init->IsObjectPattern())) {
1395         LogSyntaxError("Missing initializer in destructuring declaration");
1396     }
1397 
1398     lexer::SourcePosition endLoc = init->End();
1399     auto declarator = AllocNode<ir::VariableDeclarator>(GetFlag(flags), init);
1400     declarator->SetRange({startLoc, endLoc});
1401 
1402     return declarator;
1403 }
1404 
ParsePotentialOptionalFunctionParameter(ir::AnnotatedExpression * returnNode)1405 void TypedParser::ParsePotentialOptionalFunctionParameter(ir::AnnotatedExpression *returnNode)
1406 {
1407     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1408         switch (returnNode->Type()) {
1409             case ir::AstNodeType::IDENTIFIER: {
1410                 returnNode->AsIdentifier()->SetOptional(true);
1411                 break;
1412             }
1413             case ir::AstNodeType::OBJECT_PATTERN: {
1414                 returnNode->AsObjectPattern()->SetOptional(true);
1415                 break;
1416             }
1417             case ir::AstNodeType::ARRAY_PATTERN: {
1418                 returnNode->AsArrayPattern()->SetOptional(true);
1419                 break;
1420             }
1421             case ir::AstNodeType::REST_ELEMENT: {
1422                 returnNode->AsRestElement()->SetOptional(true);
1423                 break;
1424             }
1425             default: {
1426                 LogSyntaxError("Unexpected '?' for parameter");
1427             }
1428         }
1429 
1430         Lexer()->NextToken();  // eat '?'
1431     }
1432 
1433     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1434         Lexer()->NextToken();  // eat ':'
1435         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
1436         returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options));
1437     }
1438 }
1439 
ValidateArrowParameterAssignment(ir::AssignmentExpression * assignmentExpr)1440 ParserStatus TypedParser::ValidateArrowParameterAssignment(ir::AssignmentExpression *assignmentExpr)
1441 {
1442     if (assignmentExpr->Right()->IsYieldExpression()) {
1443         LogSyntaxError("yield is not allowed in arrow function parameters");
1444     }
1445 
1446     if (assignmentExpr->Right()->IsAwaitExpression()) {
1447         LogSyntaxError("await is not allowed in arrow function parameters");
1448     }
1449 
1450     if (!assignmentExpr->ConvertibleToAssignmentPattern()) {
1451         LogSyntaxError("Invalid destructuring assignment target");
1452     }
1453 
1454     if (assignmentExpr->Left()->IsIdentifier() && assignmentExpr->Left()->AsIdentifier()->IsOptional()) {
1455         LogSyntaxError("Parameter cannot have question mark and initializer.", assignmentExpr->Start());
1456     }
1457 
1458     ValidateArrowParameterBindings(assignmentExpr);
1459     return ParserStatus::HAS_COMPLEX_PARAM;
1460 }
1461 
ValidateArrowParameterArray(ir::ArrayExpression * arrayPattern)1462 ParserStatus TypedParser::ValidateArrowParameterArray(ir::ArrayExpression *arrayPattern)
1463 {
1464     if (!arrayPattern->ConvertibleToArrayPattern()) {
1465         LogSyntaxError("Invalid destructuring assignment target");
1466     }
1467 
1468     if (!InAmbientContext() && ((GetContext().Status() & ParserStatus::FUNCTION) != 0) && arrayPattern->IsOptional()) {
1469         LogSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.",
1470                        arrayPattern->Start());
1471     }
1472 
1473     ValidateArrowParameterBindings(arrayPattern);
1474     return ParserStatus::HAS_COMPLEX_PARAM;
1475 }
1476 
ValidateArrowParameterObject(ir::ObjectExpression * objectPattern)1477 ParserStatus TypedParser::ValidateArrowParameterObject(ir::ObjectExpression *objectPattern)
1478 {
1479     if (!objectPattern->ConvertibleToObjectPattern()) {
1480         LogSyntaxError("Invalid destructuring assignment target");
1481     }
1482 
1483     if (!InAmbientContext() && ((GetContext().Status() & ParserStatus::FUNCTION) != 0) && objectPattern->IsOptional()) {
1484         LogSyntaxError("A binding pattern parameter cannot be optional in an implementation signature.",
1485                        objectPattern->Start());
1486     }
1487 
1488     ValidateArrowParameterBindings(objectPattern);
1489     return ParserStatus::HAS_COMPLEX_PARAM;
1490 }
1491 
ValidateArrowParameter(ir::Expression * expr,bool * seenOptional)1492 ParserStatus TypedParser::ValidateArrowParameter(ir::Expression *expr, bool *seenOptional)
1493 {
1494     switch (expr->Type()) {
1495         case ir::AstNodeType::SPREAD_ELEMENT: {
1496             if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
1497                 LogSyntaxError("Invalid rest element.");
1498             }
1499 
1500             [[fallthrough]];
1501         }
1502         case ir::AstNodeType::REST_ELEMENT: {
1503             if (expr->AsRestElement()->IsOptional()) {
1504                 LogSyntaxError("A rest parameter cannot be optional.", expr->Start());
1505             }
1506 
1507             ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
1508             return ParserStatus::HAS_COMPLEX_PARAM;
1509         }
1510         case ir::AstNodeType::IDENTIFIER: {
1511             const util::StringView &identifier = expr->AsIdentifier()->Name();
1512             bool isOptional = expr->AsIdentifier()->IsOptional();
1513             if ((*seenOptional) && !isOptional) {
1514                 LogSyntaxError("A required parameter cannot follow an optional parameter.", expr->Start());
1515             }
1516 
1517             (*seenOptional) |= isOptional;
1518 
1519             if (identifier.Is("arguments")) {
1520                 LogSyntaxError("Binding 'arguments' in strict mode is invalid");
1521             } else if (identifier.Is("eval")) {
1522                 LogSyntaxError("Binding 'eval' in strict mode is invalid");
1523             }
1524 
1525             ValidateArrowParameterBindings(expr);
1526             return ParserStatus::NO_OPTS;
1527         }
1528         case ir::AstNodeType::OBJECT_EXPRESSION:
1529             return ValidateArrowParameterObject(expr->AsObjectExpression());
1530         case ir::AstNodeType::ARRAY_EXPRESSION:
1531             return ValidateArrowParameterArray(expr->AsArrayExpression());
1532         case ir::AstNodeType::ASSIGNMENT_EXPRESSION:
1533             return ValidateArrowParameterAssignment(expr->AsAssignmentExpression());
1534         default:
1535             break;
1536     }
1537     LogSyntaxError("Insufficient formal parameter in arrow function.");
1538     return ParserStatus::NO_OPTS;
1539 }
1540 
1541 }  // namespace ark::es2panda::parser
1542