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