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 "ETSparser.h"
17 #include "ETSNolintParser.h"
18 #include <utility>
19 
20 #include "macros.h"
21 #include "parser/parserFlags.h"
22 #include "parser/parserStatusContext.h"
23 #include "util/helpers.h"
24 #include "util/language.h"
25 #include "utils/arena_containers.h"
26 #include "varbinder/varbinder.h"
27 #include "varbinder/ETSBinder.h"
28 #include "lexer/lexer.h"
29 #include "lexer/ETSLexer.h"
30 #include "checker/types/ets/etsEnumType.h"
31 #include "ir/astNode.h"
32 #include "ir/base/classDefinition.h"
33 #include "ir/base/decorator.h"
34 #include "ir/base/catchClause.h"
35 #include "ir/base/classProperty.h"
36 #include "ir/base/scriptFunction.h"
37 #include "ir/base/methodDefinition.h"
38 #include "ir/base/classStaticBlock.h"
39 #include "ir/base/spreadElement.h"
40 #include "ir/expressions/identifier.h"
41 #include "ir/expressions/functionExpression.h"
42 #include "ir/statements/functionDeclaration.h"
43 #include "ir/statements/expressionStatement.h"
44 #include "ir/statements/classDeclaration.h"
45 #include "ir/statements/variableDeclarator.h"
46 #include "ir/statements/variableDeclaration.h"
47 #include "ir/expressions/dummyNode.h"
48 #include "ir/expressions/callExpression.h"
49 #include "ir/expressions/thisExpression.h"
50 #include "ir/expressions/typeofExpression.h"
51 #include "ir/expressions/memberExpression.h"
52 #include "ir/expressions/updateExpression.h"
53 #include "ir/expressions/arrowFunctionExpression.h"
54 #include "ir/expressions/unaryExpression.h"
55 #include "ir/expressions/yieldExpression.h"
56 #include "ir/expressions/awaitExpression.h"
57 #include "ir/expressions/literals/nullLiteral.h"
58 #include "ir/expressions/literals/numberLiteral.h"
59 #include "ir/expressions/literals/stringLiteral.h"
60 #include "ir/expressions/literals/undefinedLiteral.h"
61 #include "ir/module/importDeclaration.h"
62 #include "ir/module/importDefaultSpecifier.h"
63 #include "ir/module/importSpecifier.h"
64 #include "ir/module/exportSpecifier.h"
65 #include "ir/module/exportNamedDeclaration.h"
66 #include "ir/statements/assertStatement.h"
67 #include "ir/statements/blockStatement.h"
68 #include "ir/statements/ifStatement.h"
69 #include "ir/statements/labelledStatement.h"
70 #include "ir/statements/switchStatement.h"
71 #include "ir/statements/throwStatement.h"
72 #include "ir/statements/tryStatement.h"
73 #include "ir/statements/whileStatement.h"
74 #include "ir/statements/forOfStatement.h"
75 #include "ir/statements/doWhileStatement.h"
76 #include "ir/statements/breakStatement.h"
77 #include "ir/statements/debuggerStatement.h"
78 #include "ir/ets/etsLaunchExpression.h"
79 #include "ir/ets/etsClassLiteral.h"
80 #include "ir/ets/etsPrimitiveType.h"
81 #include "ir/ets/etsPackageDeclaration.h"
82 #include "ir/ets/etsReExportDeclaration.h"
83 #include "ir/ets/etsWildcardType.h"
84 #include "ir/ets/etsNewArrayInstanceExpression.h"
85 #include "ir/ets/etsTuple.h"
86 #include "ir/ets/etsFunctionType.h"
87 #include "ir/ets/etsNewClassInstanceExpression.h"
88 #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h"
89 #include "ir/ets/etsScript.h"
90 #include "ir/ets/etsTypeReference.h"
91 #include "ir/ets/etsTypeReferencePart.h"
92 #include "ir/ets/etsNullishTypes.h"
93 #include "ir/ets/etsUnionType.h"
94 #include "ir/ets/etsImportSource.h"
95 #include "ir/ets/etsImportDeclaration.h"
96 #include "ir/ets/etsStructDeclaration.h"
97 #include "ir/ets/etsParameterExpression.h"
98 #include "ir/module/importNamespaceSpecifier.h"
99 #include "ir/ts/tsAsExpression.h"
100 #include "ir/ts/tsInterfaceDeclaration.h"
101 #include "ir/ts/tsEnumDeclaration.h"
102 #include "ir/ts/tsTypeParameterInstantiation.h"
103 #include "ir/ts/tsInterfaceBody.h"
104 #include "ir/ts/tsImportEqualsDeclaration.h"
105 #include "ir/ts/tsArrayType.h"
106 #include "ir/ts/tsQualifiedName.h"
107 #include "ir/ts/tsTypeReference.h"
108 #include "ir/ts/tsTypeParameter.h"
109 #include "ir/ts/tsInterfaceHeritage.h"
110 #include "ir/ts/tsFunctionType.h"
111 #include "ir/ts/tsClassImplements.h"
112 #include "ir/ts/tsEnumMember.h"
113 #include "ir/ts/tsTypeAliasDeclaration.h"
114 #include "ir/ts/tsTypeParameterDeclaration.h"
115 #include "ir/ts/tsNonNullExpression.h"
116 #include "ir/ts/tsThisType.h"
117 #include "generated/signatures.h"
118 
119 namespace ark::es2panda::parser {
120 class FunctionContext;
121 
122 using namespace std::literals::string_literals;
123 
ParseLaunchExpression(ExpressionParseFlags flags)124 ir::Expression *ETSParser::ParseLaunchExpression(ExpressionParseFlags flags)
125 {
126     lexer::SourcePosition start = Lexer()->GetToken().Start();
127     Lexer()->NextToken();  // eat launch
128 
129     ir::Expression *expr = ParseLeftHandSideExpression(flags);
130     if (!expr->IsCallExpression()) {
131         ThrowSyntaxError("Only call expressions are allowed after 'launch'", expr->Start());
132     }
133     auto call = expr->AsCallExpression();
134     auto *launchExpression = AllocNode<ir::ETSLaunchExpression>(call);
135     launchExpression->SetRange({start, call->End()});
136 
137     return launchExpression;
138 }
139 
140 // NOLINTBEGIN(modernize-avoid-c-arrays)
141 static constexpr char const NO_DEFAULT_FOR_REST[] = "Rest parameter cannot have the default value.";
142 // NOLINTEND(modernize-avoid-c-arrays)
143 
ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent, ir::ETSUndefinedType *defaultUndef)144 ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent,
145                                                             ir::ETSUndefinedType *defaultUndef)
146 {
147     ir::ETSParameterExpression *paramExpression;
148     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
149         if (paramIdent->IsRestElement()) {
150             ThrowSyntaxError(NO_DEFAULT_FOR_REST);
151         }
152 
153         auto const lexerPos = Lexer()->Save().Iterator();
154         Lexer()->NextToken();  // eat '='
155 
156         if ((GetContext().Status() & ParserStatus::ALLOW_DEFAULT_VALUE) != 0) {
157             ThrowSyntaxError("Default value is allowed only for optional parameters");
158         }
159 
160         if (defaultUndef != nullptr) {
161             ThrowSyntaxError("Not enable default value with default undefined");
162         }
163         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS ||
164             Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
165             ThrowSyntaxError("You didn't set the value.");
166         }
167 
168         paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), ParseExpression());
169 
170         std::string value = Lexer()->SourceView(lexerPos.Index(), Lexer()->Save().Iterator().Index()).Mutf8();
171         while (value.back() == ' ') {
172             value.pop_back();
173         }
174         if (value.back() == ')' || value.back() == ',') {
175             value.pop_back();
176         }
177         paramExpression->SetLexerSaved(util::UString(value, Allocator()).View());
178 
179         paramExpression->SetRange({paramIdent->Start(), paramExpression->Initializer()->End()});
180     } else if (paramIdent->IsIdentifier()) {
181         auto *typeAnnotation = paramIdent->AsIdentifier()->TypeAnnotation();
182 
183         const auto typeAnnotationValue = [this, typeAnnotation,
184                                           defaultUndef]() -> std::pair<ir::Expression *, std::string> {
185             if (typeAnnotation == nullptr) {
186                 return std::make_pair(nullptr, "");
187             }
188             return std::make_pair(defaultUndef != nullptr ? AllocNode<ir::UndefinedLiteral>() : nullptr, "undefined");
189         }();
190 
191         paramExpression =
192             AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), std::get<0>(typeAnnotationValue));
193         if (defaultUndef != nullptr) {
194             paramExpression->SetLexerSaved(util::UString(std::get<1>(typeAnnotationValue), Allocator()).View());
195         }
196         paramExpression->SetRange({paramIdent->Start(), paramIdent->End()});
197     } else {
198         paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsRestElement(), nullptr);
199         paramExpression->SetRange({paramIdent->Start(), paramIdent->End()});
200     }
201     return paramExpression;
202 }
203 
ResolveArgumentUnaryExpr(ExpressionParseFlags flags)204 ir::Expression *ETSParser::ResolveArgumentUnaryExpr(ExpressionParseFlags flags)
205 {
206     switch (Lexer()->GetToken().Type()) {
207         case lexer::TokenType::PUNCTUATOR_PLUS:
208         case lexer::TokenType::PUNCTUATOR_MINUS:
209         case lexer::TokenType::PUNCTUATOR_TILDE:
210         case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK:
211         case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR:
212         case lexer::TokenType::PUNCTUATOR_PLUS_PLUS:
213         case lexer::TokenType::PUNCTUATOR_MINUS_MINUS:
214         case lexer::TokenType::KEYW_TYPEOF: {
215             return ParseUnaryOrPrefixUpdateExpression();
216         }
217         default: {
218             return ParseLeftHandSideExpression(flags);
219         }
220     }
221 }
222 
223 // NOLINTNEXTLINE(google-default-arguments)
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)224 ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
225 {
226     switch (Lexer()->GetToken().Type()) {
227         case lexer::TokenType::PUNCTUATOR_PLUS_PLUS:
228         case lexer::TokenType::PUNCTUATOR_MINUS_MINUS:
229         case lexer::TokenType::PUNCTUATOR_PLUS:
230         case lexer::TokenType::PUNCTUATOR_MINUS:
231         case lexer::TokenType::PUNCTUATOR_TILDE:
232         case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR:
233         case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK:
234         case lexer::TokenType::KEYW_TYPEOF: {
235             break;
236         }
237         case lexer::TokenType::KEYW_LAUNCH: {
238             return ParseLaunchExpression(flags);
239         }
240         default: {
241             return ParseLeftHandSideExpression(flags);
242         }
243     }
244 
245     lexer::TokenType operatorType = Lexer()->GetToken().Type();
246     auto start = Lexer()->GetToken().Start();
247     Lexer()->NextToken();
248 
249     ir::Expression *argument = ResolveArgumentUnaryExpr(flags);
250 
251     if (lexer::Token::IsUpdateToken(operatorType)) {
252         if (!argument->IsIdentifier() && !argument->IsMemberExpression()) {
253             ThrowSyntaxError("Invalid left-hand side in prefix operation");
254         }
255     }
256 
257     lexer::SourcePosition end = argument->End();
258 
259     ir::Expression *returnExpr = nullptr;
260     if (lexer::Token::IsUpdateToken(operatorType)) {
261         returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true);
262     } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) {
263         returnExpr = AllocNode<ir::TypeofExpression>(argument);
264     } else {
265         returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType);
266     }
267 
268     returnExpr->SetRange({start, end});
269 
270     return returnExpr;
271 }
272 
273 // NOLINTNEXTLINE(google-default-arguments)
ParseDefaultPrimaryExpression(ExpressionParseFlags flags)274 ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags)
275 {
276     auto startLoc = Lexer()->GetToken().Start();
277     auto savedPos = Lexer()->Save();
278     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL |
279                                            TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE |
280                                            TypeAnnotationParsingOptions::DISALLOW_UNION;
281     ir::TypeNode *potentialType = ParseTypeAnnotation(&options);
282 
283     if (potentialType != nullptr) {
284         if (potentialType->IsTSArrayType()) {
285             return potentialType;
286         }
287 
288         if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
289             Lexer()->NextToken();  // eat '.'
290         }
291 
292         if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) {
293             Lexer()->NextToken();  // eat 'class' and 'struct'
294             auto *classLiteral = AllocNode<ir::ETSClassLiteral>(potentialType);
295             classLiteral->SetRange({startLoc, Lexer()->GetToken().End()});
296             return classLiteral;
297         }
298     }
299 
300     Lexer()->Rewind(savedPos);
301 
302     Lexer()->NextToken();
303     bool pretendArrow = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW;
304     Lexer()->Rewind(savedPos);
305 
306     if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !pretendArrow) {
307         return ParsePrimaryExpressionIdent(flags);
308     }
309 
310     ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(Lexer()->GetToken().Type()), "'."});
311     return nullptr;
312 }
313 
ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)314 ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)
315 {
316     switch (Lexer()->GetToken().Type()) {
317         case lexer::TokenType::LITERAL_TRUE:
318         case lexer::TokenType::LITERAL_FALSE: {
319             return ParseBooleanLiteral();
320         }
321         case lexer::TokenType::LITERAL_NULL: {
322             return ParseNullLiteral();
323         }
324         case lexer::TokenType::KEYW_UNDEFINED: {
325             return ParseUndefinedLiteral();
326         }
327         case lexer::TokenType::LITERAL_NUMBER: {
328             return ParseCoercedNumberLiteral();
329         }
330         case lexer::TokenType::LITERAL_STRING: {
331             return ParseStringLiteral();
332         }
333         case lexer::TokenType::LITERAL_CHAR: {
334             return ParseCharLiteral();
335         }
336         default: {
337             return ParseDefaultPrimaryExpression(flags);
338         }
339     }
340 }
341 
342 // NOLINTNEXTLINE(google-default-arguments)
ParsePrimaryExpression(ExpressionParseFlags flags)343 ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags)
344 {
345     switch (Lexer()->GetToken().Type()) {
346         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
347             return ParseCoverParenthesizedExpressionAndArrowParameterList(flags);
348         }
349         case lexer::TokenType::KEYW_THIS: {
350             return ParseThisExpression();
351         }
352         case lexer::TokenType::KEYW_SUPER: {
353             return ParseSuperExpression();
354         }
355         case lexer::TokenType::KEYW_NEW: {
356             return ParseNewExpression();
357         }
358         case lexer::TokenType::KEYW_ASYNC: {
359             return ParseAsyncExpression();
360         }
361         case lexer::TokenType::KEYW_AWAIT: {
362             return ParseAwaitExpression();
363         }
364         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
365             return ParseArrayExpression(CarryPatternFlags(flags));
366         }
367         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
368             return ParseObjectExpression(CarryPatternFlags(flags));
369         }
370         case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
371             return ParseTemplateLiteral();
372         }
373         case lexer::TokenType::KEYW_TYPE: {
374             ThrowSyntaxError("Type alias is allowed only as top-level declaration");
375         }
376         case lexer::TokenType::PUNCTUATOR_FORMAT: {
377             return ParseExpressionFormatPlaceholder();
378         }
379         case lexer::TokenType::KEYW_TYPEOF: {
380             return ParseUnaryOrPrefixUpdateExpression();
381         }
382         default: {
383             return ParsePrimaryExpressionWithLiterals(flags);
384         }
385     }
386 }
387 
IsPunctuartorSpecialCharacter(lexer::TokenType tokenType)388 bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType)
389 {
390     switch (tokenType) {
391         case lexer::TokenType::PUNCTUATOR_COLON:
392         case lexer::TokenType::PUNCTUATOR_COMMA:
393         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
394         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
395         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
396         case lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET:
397         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
398         case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
399         case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
400             return true;
401         default:
402             return false;
403     }
404 }
405 
IsArrowFunctionExpressionStart()406 bool ETSParser::IsArrowFunctionExpressionStart()
407 {
408     const auto savedPos = Lexer()->Save();
409     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
410     Lexer()->NextToken();
411     auto tokenType = Lexer()->GetToken().Type();
412 
413     size_t openBrackets = 1;
414     bool expectIdentifier = true;
415     while (tokenType != lexer::TokenType::EOS && openBrackets > 0) {
416         switch (tokenType) {
417             case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
418                 --openBrackets;
419                 break;
420             case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
421                 ++openBrackets;
422                 break;
423             case lexer::TokenType::PUNCTUATOR_COMMA:
424                 expectIdentifier = true;
425                 break;
426             case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
427                 Lexer()->Rewind(savedPos);
428                 return false;
429             default:
430                 if (!expectIdentifier) {
431                     break;
432                 }
433                 if (tokenType != lexer::TokenType::LITERAL_IDENT &&
434                     tokenType != lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
435                     Lexer()->Rewind(savedPos);
436                     return false;
437                 }
438                 expectIdentifier = false;
439         }
440         Lexer()->NextToken();
441         tokenType = Lexer()->GetToken().Type();
442     }
443 
444     while (tokenType != lexer::TokenType::EOS && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
445         if (lexer::Token::IsPunctuatorToken(tokenType) && !IsPunctuartorSpecialCharacter(tokenType)) {
446             break;
447         }
448         Lexer()->NextToken();
449         tokenType = Lexer()->GetToken().Type();
450     }
451     Lexer()->Rewind(savedPos);
452     return tokenType == lexer::TokenType::PUNCTUATOR_ARROW;
453 }
454 
ParseArrowFunctionExpression()455 ir::ArrowFunctionExpression *ETSParser::ParseArrowFunctionExpression()
456 {
457     auto newStatus = ParserStatus::ARROW_FUNCTION;
458     auto *func = ParseFunction(newStatus);
459     auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
460     arrowFuncNode->SetRange(func->Range());
461     return arrowFuncNode;
462 }
463 
464 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)465 ir::Expression *ETSParser::ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)
466 {
467     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
468     if (IsArrowFunctionExpressionStart()) {
469         return ParseArrowFunctionExpression();
470     }
471 
472     lexer::SourcePosition start = Lexer()->GetToken().Start();
473     Lexer()->NextToken();
474 
475     ExpressionParseFlags newFlags = ExpressionParseFlags::ACCEPT_COMMA;
476     if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
477         newFlags |= ExpressionParseFlags::INSTANCEOF;
478     };
479 
480     ir::Expression *expr = ParseExpression(newFlags);
481 
482     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
483         ThrowSyntaxError("Unexpected token, expected ')'");
484     }
485 
486     expr->SetGrouped();
487     expr->SetRange({start, Lexer()->GetToken().End()});
488     Lexer()->NextToken();
489 
490     return expr;
491 }
492 
GetPostPrimaryExpression(ir::Expression *returnExpression, lexer::SourcePosition startLoc, bool ignoreCallExpression, [[maybe_unused]] bool *isChainExpression)493 std::optional<ir::Expression *> ETSParser::GetPostPrimaryExpression(ir::Expression *returnExpression,
494                                                                     lexer::SourcePosition startLoc,
495                                                                     bool ignoreCallExpression,
496                                                                     [[maybe_unused]] bool *isChainExpression)
497 {
498     switch (Lexer()->GetToken().Type()) {
499         case lexer::TokenType::PUNCTUATOR_QUESTION_DOT:
500             if (*isChainExpression) {
501                 return std::nullopt;  // terminate current chain
502             }
503             *isChainExpression = true;
504             Lexer()->NextToken();  // eat ?.
505 
506             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
507                 return ParseElementAccess(returnExpression, true);
508             }
509 
510             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
511                 return ParseCallExpression(returnExpression, true, false);
512             }
513 
514             return ParsePropertyAccess(returnExpression, true);
515         case lexer::TokenType::PUNCTUATOR_PERIOD:
516             Lexer()->NextToken();  // eat period
517 
518             return ParsePropertyAccess(returnExpression);
519         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
520             return ParseElementAccess(returnExpression);
521         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
522         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
523             if (ParsePotentialGenericFunctionCall(returnExpression, &returnExpression, startLoc,
524                                                   ignoreCallExpression)) {
525                 return std::nullopt;
526             }
527 
528             return returnExpression;
529         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
530             if (ignoreCallExpression) {
531                 return std::nullopt;
532             }
533             return ParseCallExpression(returnExpression, false, false);
534         case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
535             const bool shouldBreak = ParsePotentialNonNullExpression(&returnExpression, startLoc);
536             if (shouldBreak) {
537                 return std::nullopt;
538             }
539 
540             return returnExpression;
541         }
542         case lexer::TokenType::PUNCTUATOR_FORMAT:
543             ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_FORMAT);
544         case lexer::TokenType::PUNCTUATOR_ARROW:
545             ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_ARROW);
546         default:
547             return std::nullopt;
548     }
549 }
550 
ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, bool ignoreCallExpression, [[maybe_unused]] bool *isChainExpression)551 ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
552                                                       bool ignoreCallExpression,
553                                                       [[maybe_unused]] bool *isChainExpression)
554 {
555     ir::Expression *returnExpression = primaryExpr;
556 
557     while (true) {
558         auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression);
559         if (expr.has_value()) {
560             returnExpression = expr.value();
561             continue;
562         }
563 
564         break;
565     }
566 
567     return returnExpression;
568 }
569 
ParsePotentialAsExpression(ir::Expression *primaryExpr)570 ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExpr)
571 {
572     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS);
573     Lexer()->NextToken();
574 
575     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
576     ir::TypeNode *type = ParseTypeAnnotation(&options);
577 
578     auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpr, type, false);
579     asExpression->SetRange(primaryExpr->Range());
580     return asExpression;
581 }
582 
583 //  Extracted from 'ParseNewExpression()' to reduce function's size
CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments, ir::TypeNode *typeReference, ir::TypeNode *baseTypeReference)584 ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments,
585                                                                       ir::TypeNode *typeReference,
586                                                                       ir::TypeNode *baseTypeReference)
587 {
588     lexer::SourcePosition endLoc = typeReference->End();
589 
590     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
591         if (baseTypeReference != nullptr) {
592             ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start());
593         }
594 
595         Lexer()->NextToken();
596 
597         while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
598             ir::Expression *argument = ParseExpression();
599             arguments.push_back(argument);
600 
601             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
602                 Lexer()->NextToken();
603                 continue;
604             }
605         }
606 
607         endLoc = Lexer()->GetToken().End();
608         Lexer()->NextToken();
609     }
610 
611     ir::ClassDefinition *classDefinition {};
612 
613     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
614         ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
615         auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER;
616         auto [ctor, properties, bodyRange] = ParseClassBody(modifiers);
617 
618         auto newIdent = AllocNode<ir::Identifier>("#0", Allocator());
619         classDefinition = AllocNode<ir::ClassDefinition>(
620             "#0", newIdent, nullptr, nullptr, std::move(implements), ctor,  // remove name
621             typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE,
622             Language(Language::Id::ETS));
623 
624         classDefinition->SetRange(bodyRange);
625     }
626 
627     return classDefinition;
628 }
629 
ParseNewExpression()630 ir::Expression *ETSParser::ParseNewExpression()
631 {
632     lexer::SourcePosition start = Lexer()->GetToken().Start();
633 
634     Lexer()->NextToken();  // eat new
635 
636     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR;
637     ir::TypeNode *baseTypeReference = ParseBaseTypeReference(&options);
638     ir::TypeNode *typeReference = baseTypeReference;
639     if (typeReference == nullptr) {
640         options |= TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | TypeAnnotationParsingOptions::ALLOW_WILDCARD |
641                    TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY;
642         typeReference = ParseTypeReference(&options);
643         if (typeReference == nullptr) {
644             typeReference = ParseTypeAnnotation(&options);
645         }
646     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
647         ThrowSyntaxError("Invalid { after base types.");
648     }
649 
650     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
651         Lexer()->NextToken();
652         ir::Expression *dimension = ParseExpression();
653 
654         auto endLoc = Lexer()->GetToken().End();
655         ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
656 
657         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
658             auto *arrInstance = AllocNode<ir::ETSNewArrayInstanceExpression>(typeReference, dimension);
659             arrInstance->SetRange({start, endLoc});
660             return arrInstance;
661         }
662 
663         ArenaVector<ir::Expression *> dimensions(Allocator()->Adapter());
664         dimensions.push_back(dimension);
665 
666         do {
667             Lexer()->NextToken();
668             dimensions.push_back(ParseExpression());
669 
670             endLoc = Lexer()->GetToken().End();
671             ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
672         } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
673 
674         auto *multiArray = AllocNode<ir::ETSNewMultiDimArrayInstanceExpression>(typeReference, std::move(dimensions));
675         multiArray->SetRange({start, endLoc});
676         return multiArray;
677     }
678 
679     ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
680     ir::ClassDefinition *classDefinition =
681         CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference);
682 
683     auto *newExprNode =
684         AllocNode<ir::ETSNewClassInstanceExpression>(typeReference, std::move(arguments), classDefinition);
685     newExprNode->SetRange({start, Lexer()->GetToken().End()});
686 
687     return newExprNode;
688 }
689 
ParseAsyncExpression()690 ir::Expression *ETSParser::ParseAsyncExpression()
691 {
692     Lexer()->NextToken();  // eat 'async'
693     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
694         !IsArrowFunctionExpressionStart()) {
695         ThrowSyntaxError("Unexpected token. expected '('");
696     }
697 
698     auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ARROW_FUNCTION | ParserStatus::ASYNC_FUNCTION;
699     auto *func = ParseFunction(newStatus);
700     auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
701     arrowFuncNode->SetRange(func->Range());
702     return arrowFuncNode;
703 }
704 
ParseAwaitExpression()705 ir::Expression *ETSParser::ParseAwaitExpression()
706 {
707     lexer::SourcePosition start = Lexer()->GetToken().Start();
708     Lexer()->NextToken();
709     ir::Expression *argument = ParseExpression();
710     auto *awaitExpression = AllocNode<ir::AwaitExpression>(argument);
711     awaitExpression->SetRange({start, Lexer()->GetToken().End()});
712     return awaitExpression;
713 }
714 
ParseThisExpression()715 ir::ThisExpression *ETSParser::ParseThisExpression()
716 {
717     auto *thisExpression = TypedParser::ParseThisExpression();
718 
719     if (Lexer()->GetToken().NewLine()) {
720         return thisExpression;
721     }
722 
723     switch (Lexer()->GetToken().Type()) {
724         case lexer::TokenType::PUNCTUATOR_PERIOD:
725         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
726         case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
727         case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
728         case lexer::TokenType::PUNCTUATOR_COLON:
729         case lexer::TokenType::PUNCTUATOR_EQUAL:
730         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
731         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
732         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
733         case lexer::TokenType::PUNCTUATOR_COMMA:
734         case lexer::TokenType::PUNCTUATOR_QUESTION_MARK:
735         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
736         case lexer::TokenType::KEYW_INSTANCEOF:
737         case lexer::TokenType::KEYW_AS: {
738             break;
739         }
740         default: {
741             ThrowUnexpectedToken(Lexer()->GetToken().Type());
742             break;
743         }
744     }
745 
746     return thisExpression;
747 }
748 
ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)749 ir::Expression *ETSParser::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
750 {
751     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
752         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0 && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
753         return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
754     }
755 
756     return expr;
757 }
758 
ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)759 bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)
760 {
761     if (expression == nullptr || Lexer()->GetToken().NewLine()) {
762         return true;
763     }
764 
765     const auto nonNullExpr = AllocNode<ir::TSNonNullExpression>(*expression);
766     nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()});
767 
768     *expression = nonNullExpr;
769 
770     Lexer()->NextToken();
771 
772     return false;
773 }
774 
ValidateInstanceOfExpression(ir::Expression *expr)775 void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr)
776 {
777     ValidateGroupedExpression(expr);
778     lexer::TokenType tokenType = Lexer()->GetToken().Type();
779     if (tokenType == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
780         auto options = TypeAnnotationParsingOptions::NO_OPTS;
781 
782         // Run checks to validate type declarations
783         // Should provide helpful messages with incorrect declarations like the following:
784         // `instanceof A<String;`
785         ParseTypeParameterDeclaration(&options);
786 
787         // Display error message even when type declaration is correct
788         // `instanceof A<String>;`
789         ThrowSyntaxError("Invalid right-hand side in 'instanceof' expression");
790     }
791 }
792 
793 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)794 ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags)
795 {
796     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
797         (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
798         ir::YieldExpression *yieldExpr = ParseYieldExpression();
799 
800         return ParsePotentialExpressionSequence(yieldExpr, flags);
801     }
802 
803     ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
804     if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
805         ValidateInstanceOfExpression(unaryExpressionNode);
806     }
807 
808     ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
809 
810     if (Lexer()->GetToken().NewLine()) {
811         return assignmentExpression;
812     }
813 
814     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
815         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
816         return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
817     }
818 
819     return assignmentExpression;
820 }
821 
822 }  // namespace ark::es2panda::parser
823