• 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 "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,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         default:
545             return std::nullopt;
546     }
547 }
548 
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)549 ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
550                                                       bool ignoreCallExpression,
551                                                       [[maybe_unused]] bool *isChainExpression)
552 {
553     ir::Expression *returnExpression = primaryExpr;
554 
555     while (true) {
556         auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression);
557         if (expr.has_value()) {
558             returnExpression = expr.value();
559             continue;
560         }
561 
562         break;
563     }
564 
565     return returnExpression;
566 }
567 
ParsePotentialAsExpression(ir::Expression * primaryExpr)568 ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExpr)
569 {
570     ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS);
571     Lexer()->NextToken();
572 
573     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
574     ir::TypeNode *type = ParseTypeAnnotation(&options);
575 
576     auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpr, type, false);
577     asExpression->SetRange(primaryExpr->Range());
578     return asExpression;
579 }
580 
581 //  Extracted from 'ParseNewExpression()' to reduce function's size
CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression * > & arguments,ir::TypeNode * typeReference,ir::TypeNode * baseTypeReference)582 ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments,
583                                                                       ir::TypeNode *typeReference,
584                                                                       ir::TypeNode *baseTypeReference)
585 {
586     lexer::SourcePosition endLoc = typeReference->End();
587 
588     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
589         if (baseTypeReference != nullptr) {
590             ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start());
591         }
592 
593         Lexer()->NextToken();
594 
595         while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
596             ir::Expression *argument = ParseExpression();
597             arguments.push_back(argument);
598 
599             if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
600                 Lexer()->NextToken();
601                 continue;
602             }
603         }
604 
605         endLoc = Lexer()->GetToken().End();
606         Lexer()->NextToken();
607     }
608 
609     ir::ClassDefinition *classDefinition {};
610 
611     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
612         ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter());
613         auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER;
614         auto [ctor, properties, bodyRange] = ParseClassBody(modifiers);
615 
616         auto newIdent = AllocNode<ir::Identifier>("#0", Allocator());
617         classDefinition = AllocNode<ir::ClassDefinition>(
618             "#0", newIdent, nullptr, nullptr, std::move(implements), ctor,  // remove name
619             typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE,
620             Language(Language::Id::ETS));
621 
622         classDefinition->SetRange(bodyRange);
623     }
624 
625     return classDefinition;
626 }
627 
ParseNewExpression()628 ir::Expression *ETSParser::ParseNewExpression()
629 {
630     lexer::SourcePosition start = Lexer()->GetToken().Start();
631 
632     Lexer()->NextToken();  // eat new
633 
634     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
635     ir::TypeNode *baseTypeReference = ParseBaseTypeReference(&options);
636     ir::TypeNode *typeReference = baseTypeReference;
637     if (typeReference == nullptr) {
638         options |= TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | TypeAnnotationParsingOptions::ALLOW_WILDCARD;
639         typeReference = ParseTypeReference(&options);
640     } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
641         ThrowSyntaxError("Invalid { after base types.");
642     }
643 
644     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
645         Lexer()->NextToken();
646         ir::Expression *dimension = ParseExpression();
647 
648         auto endLoc = Lexer()->GetToken().End();
649         ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
650 
651         if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
652             auto *arrInstance = AllocNode<ir::ETSNewArrayInstanceExpression>(typeReference, dimension);
653             arrInstance->SetRange({start, endLoc});
654             return arrInstance;
655         }
656 
657         ArenaVector<ir::Expression *> dimensions(Allocator()->Adapter());
658         dimensions.push_back(dimension);
659 
660         do {
661             Lexer()->NextToken();
662             dimensions.push_back(ParseExpression());
663 
664             endLoc = Lexer()->GetToken().End();
665             ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
666         } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
667 
668         auto *multiArray = AllocNode<ir::ETSNewMultiDimArrayInstanceExpression>(typeReference, std::move(dimensions));
669         multiArray->SetRange({start, endLoc});
670         return multiArray;
671     }
672 
673     ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
674     ir::ClassDefinition *classDefinition =
675         CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference);
676 
677     auto *newExprNode =
678         AllocNode<ir::ETSNewClassInstanceExpression>(typeReference, std::move(arguments), classDefinition);
679     newExprNode->SetRange({start, Lexer()->GetToken().End()});
680 
681     return newExprNode;
682 }
683 
ParseAsyncExpression()684 ir::Expression *ETSParser::ParseAsyncExpression()
685 {
686     Lexer()->NextToken();  // eat 'async'
687     if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
688         !IsArrowFunctionExpressionStart()) {
689         ThrowSyntaxError("Unexpected token. expected '('");
690     }
691 
692     auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ARROW_FUNCTION | ParserStatus::ASYNC_FUNCTION;
693     auto *func = ParseFunction(newStatus);
694     auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func);
695     arrowFuncNode->SetRange(func->Range());
696     return arrowFuncNode;
697 }
698 
ParseAwaitExpression()699 ir::Expression *ETSParser::ParseAwaitExpression()
700 {
701     lexer::SourcePosition start = Lexer()->GetToken().Start();
702     Lexer()->NextToken();
703     ir::Expression *argument = ParseExpression();
704     auto *awaitExpression = AllocNode<ir::AwaitExpression>(argument);
705     awaitExpression->SetRange({start, Lexer()->GetToken().End()});
706     return awaitExpression;
707 }
708 
ParseThisExpression()709 ir::ThisExpression *ETSParser::ParseThisExpression()
710 {
711     auto *thisExpression = TypedParser::ParseThisExpression();
712 
713     if (Lexer()->GetToken().NewLine()) {
714         return thisExpression;
715     }
716 
717     switch (Lexer()->GetToken().Type()) {
718         case lexer::TokenType::PUNCTUATOR_PERIOD:
719         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
720         case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
721         case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
722         case lexer::TokenType::PUNCTUATOR_COLON:
723         case lexer::TokenType::PUNCTUATOR_EQUAL:
724         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
725         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
726         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
727         case lexer::TokenType::PUNCTUATOR_COMMA:
728         case lexer::TokenType::PUNCTUATOR_QUESTION_MARK:
729         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
730         case lexer::TokenType::KEYW_INSTANCEOF:
731         case lexer::TokenType::KEYW_AS: {
732             break;
733         }
734         default: {
735             ThrowUnexpectedToken(Lexer()->GetToken().Type());
736             break;
737         }
738     }
739 
740     return thisExpression;
741 }
742 
ParsePotentialExpressionSequence(ir::Expression * expr,ExpressionParseFlags flags)743 ir::Expression *ETSParser::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
744 {
745     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
746         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0 && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
747         return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
748     }
749 
750     return expr;
751 }
752 
ParsePotentialNonNullExpression(ir::Expression ** expression,const lexer::SourcePosition startLoc)753 bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc)
754 {
755     if (expression == nullptr || Lexer()->GetToken().NewLine()) {
756         return true;
757     }
758 
759     const auto nonNullExpr = AllocNode<ir::TSNonNullExpression>(*expression);
760     nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()});
761 
762     *expression = nonNullExpr;
763 
764     Lexer()->NextToken();
765 
766     return false;
767 }
768 
ValidateInstanceOfExpression(ir::Expression * expr)769 void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr)
770 {
771     ValidateGroupedExpression(expr);
772     lexer::TokenType tokenType = Lexer()->GetToken().Type();
773     if (tokenType == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
774         auto options = TypeAnnotationParsingOptions::NO_OPTS;
775 
776         // Run checks to validate type declarations
777         // Should provide helpful messages with incorrect declarations like the following:
778         // `instanceof A<String;`
779         ParseTypeParameterDeclaration(&options);
780 
781         // Display error message even when type declaration is correct
782         // `instanceof A<String>;`
783         ThrowSyntaxError("Invalid right-hand side in 'instanceof' expression");
784     }
785 }
786 
787 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)788 ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags)
789 {
790     if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
791         (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
792         ir::YieldExpression *yieldExpr = ParseYieldExpression();
793 
794         return ParsePotentialExpressionSequence(yieldExpr, flags);
795     }
796 
797     ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
798     if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) {
799         ValidateInstanceOfExpression(unaryExpressionNode);
800     }
801 
802     ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
803 
804     if (Lexer()->GetToken().NewLine()) {
805         return assignmentExpression;
806     }
807 
808     if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
809         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) {
810         return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
811     }
812 
813     return assignmentExpression;
814 }
815 
816 }  // namespace ark::es2panda::parser
817