• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "generated/tokenType.h"
17 #include "parser/parserFlags.h"
18 #include "ir/astNode.h"
19 #include "ir/base/classDefinition.h"
20 #include "ir/base/decorator.h"
21 #include "ir/base/metaProperty.h"
22 #include "ir/base/methodDefinition.h"
23 #include "ir/base/property.h"
24 #include "ir/base/scriptFunction.h"
25 #include "ir/base/spreadElement.h"
26 #include "ir/base/templateElement.h"
27 #include "ir/expression.h"
28 #include "ir/expressions/arrayExpression.h"
29 #include "ir/expressions/arrowFunctionExpression.h"
30 #include "ir/expressions/assignmentExpression.h"
31 #include "ir/expressions/awaitExpression.h"
32 #include "ir/expressions/binaryExpression.h"
33 #include "ir/expressions/callExpression.h"
34 #include "ir/expressions/chainExpression.h"
35 #include "ir/expressions/classExpression.h"
36 #include "ir/expressions/conditionalExpression.h"
37 #include "ir/expressions/directEvalExpression.h"
38 #include "ir/expressions/functionExpression.h"
39 #include "ir/expressions/identifier.h"
40 #include "ir/expressions/importExpression.h"
41 #include "ir/expressions/literals/bigIntLiteral.h"
42 #include "ir/expressions/literals/booleanLiteral.h"
43 #include "ir/expressions/literals/nullLiteral.h"
44 #include "ir/expressions/literals/numberLiteral.h"
45 #include "ir/expressions/literals/regExpLiteral.h"
46 #include "ir/expressions/literals/charLiteral.h"
47 #include "ir/expressions/literals/stringLiteral.h"
48 #include "ir/expressions/literals/undefinedLiteral.h"
49 #include "ir/expressions/memberExpression.h"
50 #include "ir/expressions/newExpression.h"
51 #include "ir/expressions/objectExpression.h"
52 #include "ir/expressions/omittedExpression.h"
53 #include "ir/expressions/sequenceExpression.h"
54 #include "ir/expressions/superExpression.h"
55 #include "ir/expressions/taggedTemplateExpression.h"
56 #include "ir/expressions/templateLiteral.h"
57 #include "ir/expressions/thisExpression.h"
58 #include "ir/expressions/typeofExpression.h"
59 #include "ir/expressions/unaryExpression.h"
60 #include "ir/expressions/updateExpression.h"
61 #include "ir/expressions/yieldExpression.h"
62 #include "ir/statements/blockStatement.h"
63 #include "ir/statements/classDeclaration.h"
64 #include "ir/ts/tsAsExpression.h"
65 #include "ir/ts/tsNonNullExpression.h"
66 #include "ir/validationInfo.h"
67 #include "lexer/lexer.h"
68 #include "lexer/regexp/regexp.h"
69 #include "lexer/token/letters.h"
70 #include "lexer/token/sourceLocation.h"
71 #include "lexer/token/token.h"
72 #include "util/es2pandaMacros.h"
73 #include "util/errorRecovery.h"
74 #include "util/options.h"
75 #include "generated/diagnostic.h"
76 
77 #include <memory>
78 
79 #include "parser/parserStatusContext.h"
80 #include "parserImpl.h"
81 
82 namespace ark::es2panda::parser {
ParseYieldExpression()83 ir::YieldExpression *ParserImpl::ParseYieldExpression()
84 {
85     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD);
86 
87     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
88     lexer::SourcePosition endLoc = lexer_->GetToken().End();
89 
90     if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) {
91         LogError(diagnostic::UNEXPECTED_ID);
92     }
93 
94     lexer_->NextToken();
95 
96     bool isDelegate = false;
97     ir::Expression *argument = nullptr;
98 
99     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY && !lexer_->GetToken().NewLine()) {
100         isDelegate = true;
101         lexer_->NextToken();
102 
103         argument = ParseExpression();
104         endLoc = argument->End();
105     } else if (!lexer_->GetToken().NewLine() && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
106                lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS &&
107                lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET &&
108                lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
109                lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON &&
110                lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
111                lexer_->GetToken().Type() != lexer::TokenType::EOS) {
112         argument = ParseExpression();
113         endLoc = argument->End();
114     }
115 
116     auto *yieldNode = AllocNode<ir::YieldExpression>(argument, isDelegate);
117     ES2PANDA_ASSERT(yieldNode != nullptr);
118     yieldNode->SetRange({startLoc, endLoc});
119 
120     return yieldNode;
121 }
122 
ParsePotentialExpressionSequence(ir::Expression * expr,ExpressionParseFlags flags)123 ir::Expression *ParserImpl::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags)
124 {
125     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
126         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0) {
127         return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0);
128     }
129 
130     return expr;
131 }
132 
133 // NOLINTNEXTLINE(google-default-arguments)
ParseExpression(ExpressionParseFlags flags)134 ir::Expression *ParserImpl::ParseExpression(ExpressionParseFlags flags)
135 {
136     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD &&
137         (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) {
138         ir::YieldExpression *yieldExpr = ParseYieldExpression();
139 
140         return ParsePotentialExpressionSequence(yieldExpr, flags);
141     }
142 
143     ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags);
144     ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags);
145 
146     if (lexer_->GetToken().NewLine()) {
147         return assignmentExpression;
148     }
149 
150     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
151         (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U) {
152         return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U);
153     }
154 
155     return assignmentExpression;
156 }
157 
ParseArrayExpressionRightBracketHelper(bool containsRest,const lexer::SourcePosition & startLoc)158 bool ParserImpl::ParseArrayExpressionRightBracketHelper(bool containsRest, const lexer::SourcePosition &startLoc)
159 {
160     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
161         if (containsRest) {
162             LogError(diagnostic::REST_PARAM_NOT_LAST, {}, startLoc);
163         }
164 
165         return true;
166     }
167     return false;
168 }
169 
170 // NOLINTNEXTLINE(google-default-arguments)
ParseArrayExpression(ExpressionParseFlags flags,bool allowOmitted)171 ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags, bool allowOmitted)
172 {
173     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
174 
175     ArenaVector<ir::Expression *> elements(Allocator()->Adapter());
176 
177     lexer_->NextToken();
178 
179     bool trailingComma = false;
180     bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
181 
182     lexer::SourcePosition endLoc;
183     ParseList(
184         lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE,
185         [this, inPattern, startLoc, allowOmitted, &elements, &trailingComma]() {
186             if (allowOmitted && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
187                 auto *omitted = AllocNode<ir::OmittedExpression>();
188                 omitted->SetRange(lexer_->GetToken().Loc());
189                 elements.push_back(omitted);
190                 return true;
191             }
192 
193             ir::Expression *element {};
194             if (inPattern) {
195                 element = ParsePatternElement();
196             } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
197                 element = ParseSpreadElement(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
198             } else {
199                 element = ParseExpression(ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
200             }
201 
202             bool containsRest = element->IsRestElement();
203             elements.push_back(element);
204             trailingComma = ParseArrayExpressionRightBracketHelper(containsRest, startLoc);
205             return true;
206         },
207         &endLoc, true);
208 
209     auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION;
210     auto *arrayExpressionNode =
211         AllocNode<ir::ArrayExpression>(nodeType, std::move(elements), Allocator(), trailingComma);
212     ES2PANDA_ASSERT(arrayExpressionNode != nullptr);
213     arrayExpressionNode->SetRange({startLoc, endLoc});
214 
215     if (inPattern) {
216         arrayExpressionNode->SetDeclaration();
217     }
218 
219     ParseArrayExpressionErrorCheck(arrayExpressionNode, flags, inPattern);
220     return arrayExpressionNode;
221 }
222 
ParseArrayExpression(ExpressionParseFlags flags)223 ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags)
224 {
225     return ParseArrayExpression(flags, true);
226 }
227 
ParseArrayExpressionErrorCheck(ir::ArrayExpression * arrayExpressionNode,const ExpressionParseFlags flags,const bool inPattern)228 void ParserImpl::ParseArrayExpressionErrorCheck(ir::ArrayExpression *arrayExpressionNode,
229                                                 const ExpressionParseFlags flags, const bool inPattern)
230 {
231     if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) {
232         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
233             !arrayExpressionNode->ConvertibleToArrayPattern()) {
234             LogError(diagnostic::INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING, {}, arrayExpressionNode->Start());
235         } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
236             ir::ValidationInfo info = arrayExpressionNode->ValidateExpression();
237             if (info.Fail()) {
238                 LogSyntaxError(info.msg.Utf8(), info.pos);
239             }
240         }
241     }
242 }
243 
ValidateArrowParameter(ir::Expression * expr,bool * seenOptional)244 ParserStatus ParserImpl::ValidateArrowParameter(ir::Expression *expr, [[maybe_unused]] bool *seenOptional)
245 {
246     switch (expr->Type()) {
247         case ir::AstNodeType::SPREAD_ELEMENT: {
248             if (!expr->AsSpreadElement()->ConvertibleToRest(true)) {
249                 LogError(diagnostic::INVALID_REST_ELEMENT);
250             }
251 
252             [[fallthrough]];
253         }
254         case ir::AstNodeType::REST_ELEMENT: {
255             ValidateArrowParameterBindings(expr->AsRestElement()->Argument());
256             return ParserStatus::HAS_COMPLEX_PARAM;
257         }
258         case ir::AstNodeType::IDENTIFIER: {
259             ValidateArrowParameterBindings(expr);
260             return ParserStatus::NO_OPTS;
261         }
262         case ir::AstNodeType::OBJECT_EXPRESSION: {
263             if (ir::ObjectExpression *objectPattern = expr->AsObjectExpression();
264                 !objectPattern->ConvertibleToObjectPattern()) {
265                 LogError(diagnostic::INVALID_DESTRUCTURING_TARGET);
266             }
267 
268             ValidateArrowParameterBindings(expr);
269             return ParserStatus::HAS_COMPLEX_PARAM;
270         }
271         case ir::AstNodeType::ARRAY_EXPRESSION: {
272             if (ir::ArrayExpression *arrayPattern = expr->AsArrayExpression();
273                 !arrayPattern->ConvertibleToArrayPattern()) {
274                 LogError(diagnostic::INVALID_DESTRUCTURING_TARGET);
275             }
276 
277             ValidateArrowParameterBindings(expr);
278             return ParserStatus::HAS_COMPLEX_PARAM;
279         }
280         case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
281             ValidateArrowParameterAssignment(expr->AsAssignmentExpression());
282             ValidateArrowParameterBindings(expr);
283             return ParserStatus::HAS_COMPLEX_PARAM;
284         }
285         default: {
286             break;
287         }
288     }
289     LogError(diagnostic::INSUFFICIENT_PARAM_IN_ARROW_FUN);
290     return ParserStatus::NO_OPTS;
291 }
292 
ValidateArrowParameterAssignment(ir::AssignmentExpression * expr)293 void ParserImpl::ValidateArrowParameterAssignment(ir::AssignmentExpression *expr)
294 {
295     if (expr->Right()->IsYieldExpression()) {
296         LogError(diagnostic::YIELD_IN_ARROW_FUN_PARAM);
297     } else if (expr->Right()->IsAwaitExpression()) {
298         LogError(diagnostic::AWAIT_IN_ARROW_FUN_PARAM);
299     } else if (!expr->ConvertibleToAssignmentPattern()) {
300         LogError(diagnostic::INVALID_DESTRUCTURING_TARGET);
301     }
302 }
303 
ParseArrowFunctionExpressionBody(ArrowFunctionContext * arrowFunctionContext,ArrowFunctionDescriptor * desc,ir::TSTypeParameterDeclaration * typeParamDecl,ir::TypeNode * returnTypeAnnotation)304 ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowFunctionContext *arrowFunctionContext,
305                                                                           ArrowFunctionDescriptor *desc,
306                                                                           ir::TSTypeParameterDeclaration *typeParamDecl,
307                                                                           ir::TypeNode *returnTypeAnnotation)
308 {
309     context_.Status() |= desc->newStatus;
310 
311     lexer_->NextToken();  // eat '=>'
312     ir::ScriptFunction *funcNode {};
313 
314     ir::AstNode *body = nullptr;
315     lexer::SourcePosition endLoc;
316     lexer::SourcePosition bodyStart = lexer_->GetToken().Start();
317 
318     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) {
319         body = ParseExpression();
320         endLoc = body->End();
321         arrowFunctionContext->AddFlag(ir::ScriptFunctionFlags::EXPRESSION);
322     } else {
323         lexer_->NextToken();
324         auto statements = ParseStatementList();
325         body = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements));
326         ES2PANDA_ASSERT(body);
327         body->SetRange({bodyStart, lexer_->GetToken().End()});
328 
329         // This check is redundant since we have ParseStatementList()
330         // It is impossible to leave without eos/} or error.
331         ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
332         endLoc = body->End();
333     }
334 
335     // clang-format off
336     funcNode = AllocNode<ir::ScriptFunction>(
337         Allocator(), ir::ScriptFunction::ScriptFunctionData {
338                         body,
339                         ir::FunctionSignature(typeParamDecl, std::move(desc->params), returnTypeAnnotation),
340                         arrowFunctionContext->Flags(),
341                         {},
342                         context_.GetLanguage()});
343     // clang-format on
344     ES2PANDA_ASSERT(funcNode != nullptr);
345     funcNode->SetRange({desc->startLoc, endLoc});
346 
347     auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(funcNode, Allocator());
348     ES2PANDA_ASSERT(arrowFuncNode != nullptr);
349     arrowFuncNode->SetRange(funcNode->Range());
350 
351     return arrowFuncNode;
352 }
353 
ConvertToArrowParameter(ir::Expression * expr,bool isAsync)354 ArrowFunctionDescriptor ParserImpl::ConvertToArrowParameter(ir::Expression *expr, bool isAsync)
355 {
356     auto arrowStatus = isAsync ? ParserStatus::ASYNC_FUNCTION : ParserStatus::NO_OPTS;
357     ArenaVector<ir::Expression *> params(Allocator()->Adapter());
358 
359     if (expr == nullptr) {
360         return ArrowFunctionDescriptor {std::move(params), lexer_->GetToken().Start(), arrowStatus};
361     }
362 
363     bool seenOptional = false;
364 
365     switch (expr->Type()) {
366         case ir::AstNodeType::REST_ELEMENT:
367         case ir::AstNodeType::IDENTIFIER:
368         case ir::AstNodeType::OBJECT_EXPRESSION:
369         case ir::AstNodeType::ASSIGNMENT_EXPRESSION:
370         case ir::AstNodeType::ARRAY_EXPRESSION: {
371             arrowStatus |= ValidateArrowParameter(expr, &seenOptional);
372 
373             params.push_back(expr);
374             break;
375         }
376         case ir::AstNodeType::SEQUENCE_EXPRESSION: {
377             auto &sequence = expr->AsSequenceExpression()->Sequence();
378 
379             for (auto *it : sequence) {
380                 arrowStatus |= ValidateArrowParameter(it, &seenOptional);
381             }
382 
383             params.swap(sequence);
384             break;
385         }
386         case ir::AstNodeType::CALL_EXPRESSION: {
387             if (isAsync) {
388                 auto *callExpression = expr->AsCallExpression();
389                 auto &arguments = callExpression->Arguments();
390 
391                 if (callExpression->HasTrailingComma()) {
392                     ES2PANDA_ASSERT(!arguments.empty());
393                     LogError(diagnostic::REST_PARAM_NOT_LAST, {}, arguments.back()->End());
394                 }
395 
396                 for (auto *it : arguments) {
397                     arrowStatus |= ValidateArrowParameter(it, &seenOptional);
398                 }
399 
400                 params.swap(arguments);
401                 break;
402             }
403 
404             [[fallthrough]];
405         }
406         default: {
407             LogError(diagnostic::UNEXPECTED_TOKEN);
408         }
409     }
410 
411     return ArrowFunctionDescriptor {std::move(params), expr->Start(), arrowStatus};
412 }
413 
ParseArrowFunctionExpression(ir::Expression * expr,ir::TSTypeParameterDeclaration * typeParamDecl,ir::TypeNode * returnTypeAnnotation,bool isAsync)414 ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpression(ir::Expression *expr,
415                                                                       ir::TSTypeParameterDeclaration *typeParamDecl,
416                                                                       ir::TypeNode *returnTypeAnnotation, bool isAsync)
417 {
418     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW);
419 
420     if (lexer_->GetToken().NewLine()) {
421         LogError(diagnostic::EXPECTED_ARROW_SAME_LINE);
422     }
423 
424     ArrowFunctionContext arrowFunctionContext(this, isAsync);
425     FunctionParameterContext functionParamContext(&context_);
426     ArrowFunctionDescriptor desc = ConvertToArrowParameter(expr, isAsync);
427 
428     return ParseArrowFunctionExpressionBody(&arrowFunctionContext, &desc, typeParamDecl, returnTypeAnnotation);
429 }
430 
ValidateArrowFunctionRestParameter(ir::SpreadElement * restElement)431 bool ParserImpl::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadElement *restElement)
432 {
433     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
434         // unexpected_token_3.js
435         LogError(diagnostic::REST_PARAM_NOT_LAST);
436         return false;
437     }
438 
439     return true;
440 }
441 
442 // NOLINTNEXTLINE(google-default-arguments)
ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags)443 ir::Expression *ParserImpl::ParseCoverParenthesizedExpressionAndArrowParameterList(
444     [[maybe_unused]] ExpressionParseFlags flags)  // CC-OFF(G.FMT.06-CPP) project code style
445 {
446     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
447     lexer::SourcePosition start = lexer_->GetToken().Start();
448     lexer_->NextToken();
449 
450     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
451         ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
452         restElement->SetGrouped();
453         restElement->SetStart(start);
454 
455         if (ValidateArrowFunctionRestParameter(restElement)) {
456             lexer_->NextToken();
457         }
458 
459         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
460             // test exists for js extension only
461             LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW);
462         }
463 
464         return ParseArrowFunctionExpression(restElement, nullptr, nullptr, false);
465     }
466 
467     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
468         lexer_->NextToken();
469 
470         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
471             // test exists for js extension only
472             LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW);
473         }
474 
475         auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, nullptr, false);
476         arrowExpr->SetStart(start);
477         arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start);
478 
479         return arrowExpr;
480     }
481 
482     ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST |
483                                            ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
484 
485     expr->SetGrouped();
486     expr->SetRange({start, lexer_->GetToken().End()});
487 
488     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
489 
490     return expr;
491 }
492 
ValidateGroupedExpression(ir::Expression * lhsExpression)493 void ParserImpl::ValidateGroupedExpression(ir::Expression *lhsExpression)
494 {
495     lexer::TokenType tokenType = lexer_->GetToken().Type();
496     if (lhsExpression->IsGrouped() && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
497         if (lhsExpression->IsSequenceExpression()) {
498             for (auto *seq : lhsExpression->AsSequenceExpression()->Sequence()) {
499                 ValidateParenthesizedExpression(seq);
500             }
501         } else {
502             ValidateParenthesizedExpression(lhsExpression);
503         }
504     }
505 }
506 
ValidateParenthesizedExpression(ir::Expression * lhsExpression)507 void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression)
508 {
509     switch (lhsExpression->Type()) {
510         case ir::AstNodeType::IDENTIFIER: {
511             auto info = lhsExpression->AsIdentifier()->ValidateExpression();
512             if (info.Fail()) {
513                 LogSyntaxError(info.msg.Utf8(), info.pos);
514             }
515             break;
516         }
517         case ir::AstNodeType::MEMBER_EXPRESSION: {
518             break;
519         }
520         case ir::AstNodeType::ARRAY_EXPRESSION: {
521             auto info = lhsExpression->AsArrayExpression()->ValidateExpression();
522             if (info.Fail()) {
523                 LogSyntaxError(info.msg.Utf8(), info.pos);
524             }
525             break;
526         }
527         case ir::AstNodeType::OBJECT_EXPRESSION: {
528             auto info = lhsExpression->AsObjectExpression()->ValidateExpression();
529             if (info.Fail()) {
530                 LogSyntaxError(info.msg.Utf8(), info.pos);
531             }
532             break;
533         }
534         case ir::AstNodeType::ASSIGNMENT_EXPRESSION: {
535             if (lhsExpression->AsAssignmentExpression()->ConvertibleToAssignmentPattern(false)) {
536                 break;
537             }
538             [[fallthrough]];
539         }
540         case ir::AstNodeType::SPREAD_ELEMENT: {
541             LogError(diagnostic::INVALID_LEFT_SIDE_IN_ASSIGNMENT);
542             break;
543         }
544         default: {
545             break;
546         }
547     }
548 }
549 
ParsePrefixAssertionExpression()550 ir::Expression *ParserImpl::ParsePrefixAssertionExpression()
551 {
552     LogUnexpectedToken(lexer_->GetToken());
553     return AllocBrokenExpression(Lexer()->GetToken().Loc());
554 }
555 
ParseAssignmentExpressionHelper()556 ir::Expression *ParserImpl::ParseAssignmentExpressionHelper()
557 {
558     lexer_->NextToken();
559     ir::Expression *consequent = ParseExpression();
560 
561     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
562         if (lexer::Token::IsPunctuatorToken(lexer_->GetToken().Type())) {
563             // typo happened like ';'
564             // unexpected_token_41.ets - bad test
565             LogExpectedToken(lexer::TokenType::PUNCTUATOR_COLON);
566             lexer_->NextToken();  // eat ':'
567         } else {
568             // just go to the next token if we missed ':'
569             LogError(diagnostic::UNEXPECTED_TOKEN);
570         }
571     } else {
572         lexer_->NextToken();  // eat ':'
573     }
574     return consequent;
575 }
576 
CreateBinaryAssignmentExpression(ir::Expression * assignmentExpression,ir::Expression * lhsExpression,lexer::TokenType tokenType)577 ir::Expression *ParserImpl::CreateBinaryAssignmentExpression(ir::Expression *assignmentExpression,
578                                                              ir::Expression *lhsExpression, lexer::TokenType tokenType)
579 {
580     auto *binaryAssignmentExpression =
581         AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
582     ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr);
583 
584     binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
585     return binaryAssignmentExpression;
586 }
587 
ParseAssignmentExpression(ir::Expression * lhsExpression,ExpressionParseFlags flags)588 ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpression, ExpressionParseFlags flags)
589 {
590     ValidateGroupedExpression(lhsExpression);
591 
592     lexer::TokenType tokenType = lexer_->GetToken().Type();
593     switch (tokenType) {
594         case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: {
595             ir::Expression *consequent = ParseAssignmentExpressionHelper();
596             ir::Expression *alternate = ParseExpression();
597             auto *conditionalExpr = AllocNode<ir::ConditionalExpression>(lhsExpression, consequent, alternate);
598             ES2PANDA_ASSERT(conditionalExpr != nullptr);
599             conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()});
600             return conditionalExpr;
601         }
602         case lexer::TokenType::PUNCTUATOR_ARROW: {
603             if (lexer_->GetToken().NewLine()) {
604                 LogError(diagnostic::EXPECTED_EXPRESSION_GOT_ARROW);
605             }
606 
607             return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false);
608         }
609         case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: {
610             ValidateAssignmentTarget(flags, lhsExpression);
611 
612             lexer_->NextToken();
613             ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
614             return CreateBinaryAssignmentExpression(assignmentExpression, lhsExpression, tokenType);
615         }
616         case lexer::TokenType::KEYW_AS: {
617             if (auto asExpression = ParsePotentialAsExpression(lhsExpression); asExpression != nullptr) {
618                 return ParseAssignmentExpression(asExpression);
619             }
620             break;
621         }
622         default: {
623             if (tokenType == lexer::TokenType::LITERAL_IDENT &&
624                 lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_INSTANCEOF) {
625                 tokenType = lexer::TokenType::KEYW_INSTANCEOF;
626             }
627             auto expression = ParseAssignmentBinaryExpression(tokenType, lhsExpression, flags);
628             if (expression == nullptr) {
629                 expression = ParseAssignmentEqualExpression(tokenType, lhsExpression, flags);
630             }
631 
632             if (expression != nullptr) {
633                 return expression;
634             }
635 
636             break;
637         }
638     }
639 
640     return lhsExpression;
641 }
642 
ParseAssignmentBinaryExpression(const lexer::TokenType tokenType,ir::Expression * lhsExpression,const ExpressionParseFlags flags)643 ir::Expression *ParserImpl::ParseAssignmentBinaryExpression(const lexer::TokenType tokenType,
644                                                             ir::Expression *lhsExpression,
645                                                             const ExpressionParseFlags flags)
646 {
647     switch (tokenType) {
648         case lexer::TokenType::KEYW_IN: {
649             if ((flags & ExpressionParseFlags::STOP_AT_IN) != 0) {
650                 break;
651             }
652 
653             [[fallthrough]];
654         }
655         case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING:
656         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR:
657         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
658         case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
659         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR:
660         case lexer::TokenType::PUNCTUATOR_BITWISE_AND:
661         case lexer::TokenType::PUNCTUATOR_EQUAL:
662         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
663         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
664         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
665         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
666         case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
667         case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
668         case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
669         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
670         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
671         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
672         case lexer::TokenType::PUNCTUATOR_PLUS:
673         case lexer::TokenType::PUNCTUATOR_MINUS:
674         case lexer::TokenType::PUNCTUATOR_MULTIPLY:
675         case lexer::TokenType::PUNCTUATOR_DIVIDE:
676         case lexer::TokenType::PUNCTUATOR_MOD:
677         case lexer::TokenType::KEYW_INSTANCEOF:
678         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
679             return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression, tokenType));
680         }
681         default:
682             break;
683     }
684 
685     return nullptr;
686 }
687 
ParseAssignmentEqualExpression(const lexer::TokenType tokenType,ir::Expression * lhsExpression,const ExpressionParseFlags flags)688 ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenType tokenType,
689                                                            ir::Expression *lhsExpression,
690                                                            const ExpressionParseFlags flags)
691 {
692     switch (tokenType) {
693         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL:
694         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL:
695         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL:
696         case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL:
697         case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL:
698         case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL:
699         case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
700         case lexer::TokenType::PUNCTUATOR_MOD_EQUAL:
701         case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL:
702         case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL:
703         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL:
704         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: {
705             ValidateLvalueAssignmentTarget(lhsExpression);
706 
707             lexer_->NextToken();
708             ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
709 
710             auto *binaryAssignmentExpression =
711                 AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
712             ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr);
713 
714             binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
715             return binaryAssignmentExpression;
716         }
717         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL:
718         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL:
719         case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL: {
720             LogUnexpectedToken(tokenType);
721             lexer_->NextToken();  // eat token
722             ParseExpression();    // Try to parse expression, but skip the result.
723             [[fallthrough]];
724         }
725         default:
726             break;
727     }
728 
729     return nullptr;
730 }
731 
ParseTemplateLiteral()732 ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral()
733 {
734     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
735 
736     auto startPos = lexer_->Save();
737     auto multilineStr = Lexer()->ScanMultilineString();
738     lexer_->Rewind(startPos);
739 
740     ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter());
741     ArenaVector<ir::Expression *> expressions(Allocator()->Adapter());
742 
743     while (true) {
744         lexer_->ResetTokenEnd();
745         startPos = lexer_->Save();
746         lexer_->ScanString<lexer::LEX_CHAR_BACK_TICK>();
747         const util::StringView cooked = lexer_->GetToken().String();
748         lexer_->Rewind(startPos);
749 
750         const auto templateStr = lexer_->ScanTemplateString();
751         if (templateStr.validSequence) {
752             auto *const element = AllocNode<ir::TemplateElement>(templateStr.str.View(), cooked);
753             ES2PANDA_ASSERT(element != nullptr);
754             element->SetRange({lexer::SourcePosition {startPos.Iterator().Index(), startPos.Line(), GetProgram()},
755                                lexer::SourcePosition {templateStr.end, lexer_->Line(), GetProgram()}});
756             quasis.push_back(element);
757         }
758 
759         if (!templateStr.scanExpression) {
760             lexer_->ScanTemplateStringEnd();
761             break;
762         }
763 
764         ir::Expression *expression = nullptr;
765 
766         {
767             lexer::TemplateLiteralParserContext ctx(lexer_);
768             lexer_->PushTemplateContext(&ctx);
769             lexer_->NextToken();
770             expression = ParseExpression();
771         }
772 
773         ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, false);
774 
775         expressions.push_back(expression);
776     }
777 
778     auto *templateNode = AllocNode<ir::TemplateLiteral>(std::move(quasis), std::move(expressions), multilineStr);
779     ES2PANDA_ASSERT(templateNode != nullptr);
780     templateNode->SetRange({startLoc, lexer_->GetToken().End()});
781 
782     lexer_->NextToken();
783 
784     return templateNode;
785 }
786 
ParseNewExpression()787 ir::Expression *ParserImpl::ParseNewExpression()
788 {
789     lexer::SourcePosition start = lexer_->GetToken().Start();
790 
791     lexer_->NextToken();  // eat new
792 
793     // parse callee part of NewExpression
794     ir::Expression *callee = ParseMemberExpression(true);
795     if (callee->IsImportExpression() && !callee->IsGrouped()) {
796         LogError(diagnostic::NEW_WITH_IMPORT);
797     }
798 
799     ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
800 
801     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
802         lexer::SourcePosition endLoc = callee->End();
803         auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments));
804         ES2PANDA_ASSERT(newExprNode != nullptr);
805         newExprNode->SetRange({start, endLoc});
806 
807         return newExprNode;
808     }
809 
810     lexer_->NextToken();  // eat left parenthesis
811 
812     lexer::SourcePosition endLoc;
813     // parse argument part of NewExpression
814     ParseList(
815         lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE,
816         [this, &arguments]() {
817             ir::Expression *argument = nullptr;
818 
819             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
820                 argument = ParseSpreadElement();
821             } else {
822                 argument = ParseExpression();
823             }
824             arguments.push_back(argument);
825             return true;
826         },
827         &endLoc, true);
828 
829     auto *newExprNode = AllocNode<ir::NewExpression>(callee, std::move(arguments));
830     ES2PANDA_ASSERT(newExprNode != nullptr);
831     newExprNode->SetRange({start, endLoc});
832 
833     return newExprNode;
834 }
835 
ParseLeftHandSideExpression(ExpressionParseFlags flags)836 ir::Expression *ParserImpl::ParseLeftHandSideExpression(ExpressionParseFlags flags)
837 {
838     return ParseMemberExpression(false, flags);
839 }
840 
ParsePotentialNewTarget()841 ir::MetaProperty *ParserImpl::ParsePotentialNewTarget()
842 {
843     lexer::SourceRange loc = lexer_->GetToken().Loc();
844 
845     if (lexer_->Lookahead() == lexer::LEX_CHAR_DOT) {
846         lexer_->NextToken();
847         lexer_->NextToken();
848 
849         if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_TARGET) {
850             if ((context_.Status() & ParserStatus::ALLOW_NEW_TARGET) == 0) {
851                 LogError(diagnostic::NEW_TARGET_IS_NOT_ALLOWED);
852             }
853 
854             if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) {
855                 LogError(diagnostic::NEW_TARGET_WITH_ESCAPED_CHARS);
856             }
857 
858             auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::NEW_TARGET);
859             ES2PANDA_ASSERT(metaProperty != nullptr);
860             metaProperty->SetRange(loc);
861             lexer_->NextToken();
862             return metaProperty;
863         }
864     }
865 
866     return nullptr;
867 }
868 
ParsePrimaryExpressionIdent(ExpressionParseFlags flags)869 ir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags)
870 {
871     auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
872     ES2PANDA_ASSERT(identNode != nullptr);
873     identNode->SetRange(lexer_->GetToken().Loc());
874 
875     lexer_->NextToken();
876     return identNode;
877 }
878 
ParseBooleanLiteral()879 ir::BooleanLiteral *ParserImpl::ParseBooleanLiteral()
880 {
881     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE ||
882                     lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE);
883 
884     auto *booleanNode = AllocNode<ir::BooleanLiteral>(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE);
885     ES2PANDA_ASSERT(booleanNode != nullptr);
886     booleanNode->SetRange(lexer_->GetToken().Loc());
887 
888     lexer_->NextToken();
889     return booleanNode;
890 }
891 
ParseNullLiteral()892 ir::NullLiteral *ParserImpl::ParseNullLiteral()
893 {
894     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL);
895     auto *nullNode = AllocNode<ir::NullLiteral>();
896     ES2PANDA_ASSERT(nullNode != nullptr);
897     nullNode->SetRange(lexer_->GetToken().Loc());
898 
899     lexer_->NextToken();
900     return nullNode;
901 }
902 
ParseNumberLiteral()903 ir::Literal *ParserImpl::ParseNumberLiteral()
904 {
905     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER);
906 
907     ir::Literal *numberNode {};
908 
909     if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0U) {
910         numberNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
911     } else {
912         numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber());
913     }
914 
915     ES2PANDA_ASSERT(numberNode != nullptr);
916     numberNode->SetRange(lexer_->GetToken().Loc());
917 
918     lexer_->NextToken();
919     return numberNode;
920 }
921 
ParseCharLiteral()922 ir::CharLiteral *ParserImpl::ParseCharLiteral()
923 {
924     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR);
925 
926     auto *charNode = AllocNode<ir::CharLiteral>(lexer_->GetToken().Utf16());
927     ES2PANDA_ASSERT(charNode != nullptr);
928     charNode->SetRange(lexer_->GetToken().Loc());
929 
930     lexer_->NextToken();
931     return charNode;
932 }
933 
ParseStringLiteral()934 ir::StringLiteral *ParserImpl::ParseStringLiteral()
935 {
936     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING);
937 
938     auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
939     ES2PANDA_ASSERT(stringNode != nullptr);
940     stringNode->SetRange(lexer_->GetToken().Loc());
941 
942     lexer_->NextToken();
943     return stringNode;
944 }
945 
ParseUndefinedLiteral()946 ir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral()
947 {
948     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED);
949     auto *undefinedNode = AllocNode<ir::UndefinedLiteral>();
950     ES2PANDA_ASSERT(undefinedNode != nullptr);
951     undefinedNode->SetRange(lexer_->GetToken().Loc());
952 
953     lexer_->NextToken();
954     return undefinedNode;
955 }
956 
ParseThisExpression()957 ir::ThisExpression *ParserImpl::ParseThisExpression()
958 {
959     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS);
960 
961     auto *thisExprNode = AllocNode<ir::ThisExpression>();
962     ES2PANDA_ASSERT(thisExprNode);
963     thisExprNode->SetRange(lexer_->GetToken().Loc());
964 
965     lexer_->NextToken();
966     return thisExprNode;
967 }
968 
ParseRegularExpression()969 ir::RegExpLiteral *ParserImpl::ParseRegularExpression()
970 {
971     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE ||
972                     lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL);
973 
974     lexer_->ResetTokenEnd();
975     auto regexp = lexer_->ScanRegExp();
976 
977     lexer::RegExpParser reParser(regexp, Allocator(), this);
978 
979     reParser.ParsePattern();
980 
981     auto *regexpNode = AllocNode<ir::RegExpLiteral>(regexp.patternStr, regexp.flags, regexp.flagsStr);
982     ES2PANDA_ASSERT(regexpNode != nullptr);
983     regexpNode->SetRange(lexer_->GetToken().Loc());
984 
985     lexer_->NextToken();
986     return regexpNode;
987 }
988 
ParseSuperExpression()989 ir::SuperExpression *ParserImpl::ParseSuperExpression()
990 {
991     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER);
992 
993     auto *superExprNode = AllocNode<ir::SuperExpression>();
994     ES2PANDA_ASSERT(superExprNode != nullptr);
995     superExprNode->SetRange(lexer_->GetToken().Loc());
996 
997     lexer_->NextToken();  // eat super
998 
999     if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD ||
1000          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) &&
1001         (context_.Status() & ParserStatus::ALLOW_SUPER) != 0U) {
1002         return superExprNode;
1003     }
1004 
1005     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1006         (context_.Status() & ParserStatus::ALLOW_SUPER_CALL) != 0U) {
1007         return superExprNode;
1008     }
1009 
1010     LogError(diagnostic::UNEXPECTED_SUPER);
1011     return superExprNode;
1012 }
1013 
ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)1014 ir::Expression *ParserImpl::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags)
1015 {
1016     switch (lexer_->GetToken().Type()) {
1017         case lexer::TokenType::LITERAL_IDENT:
1018             return ParsePrimaryExpressionIdent(flags);
1019         case lexer::TokenType::LITERAL_TRUE:
1020         case lexer::TokenType::LITERAL_FALSE:
1021             return ParseBooleanLiteral();
1022         case lexer::TokenType::LITERAL_NULL:
1023             return ParseNullLiteral();
1024         case lexer::TokenType::KEYW_UNDEFINED:
1025             return ParseUndefinedLiteral();
1026         case lexer::TokenType::LITERAL_NUMBER:
1027             return ParseNumberLiteral();
1028         case lexer::TokenType::LITERAL_STRING:
1029             return ParseStringLiteral();
1030         default:
1031             LogUnexpectedToken(lexer_->GetToken());
1032             return AllocBrokenExpression(Lexer()->GetToken().Loc());
1033     }
1034 }
1035 
ParseHashMaskOperator()1036 ir::Expression *ParserImpl::ParseHashMaskOperator()
1037 {
1038     if (!ValidatePrivateIdentifier()) {
1039         return AllocBrokenExpression(Lexer()->GetToken().Loc());
1040     }
1041 
1042     auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1043     ES2PANDA_ASSERT(privateIdent != nullptr);
1044     privateIdent->SetPrivate(true);
1045     lexer_->NextToken();
1046 
1047     if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_IN) {
1048         LogError(diagnostic::UNEXPECTED_PRIVATE);
1049         lexer_->GetToken().SetTokenType(lexer::TokenType::KEYW_IN);
1050     }
1051 
1052     return privateIdent;
1053 }
1054 
ParseClassExpression()1055 ir::Expression *ParserImpl::ParseClassExpression()
1056 {
1057     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1058     ir::ClassDefinition *classDefinition = ParseClassDefinition(ir::ClassDefinitionModifiers::ID_REQUIRED);
1059     if (classDefinition == nullptr) {  // Error processing.
1060         // Error is logged inside ParseClassDefinition
1061         return AllocBrokenExpression(startLoc);
1062     }
1063 
1064     auto *classExpr = AllocNode<ir::ClassExpression>(classDefinition);
1065     ES2PANDA_ASSERT(classExpr != nullptr);
1066     classExpr->SetRange({startLoc, classDefinition->End()});
1067 
1068     return classExpr;
1069 }
1070 
ParsePunctuators(ExpressionParseFlags flags)1071 ir::Expression *ParserImpl::ParsePunctuators(ExpressionParseFlags flags)
1072 {
1073     switch (lexer_->GetToken().Type()) {
1074         case lexer::TokenType::PUNCTUATOR_DIVIDE:
1075         case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: {
1076             return ParseRegularExpression();
1077         }
1078         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1079             return ParseArrayExpression(CarryPatternFlags(flags));
1080         }
1081         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1082             return ParseCoverParenthesizedExpressionAndArrowParameterList();
1083         }
1084         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1085             return ParseObjectExpression(CarryPatternFlags(flags));
1086         }
1087         case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1088             return ParseTemplateLiteral();
1089         }
1090         case lexer::TokenType::PUNCTUATOR_HASH_MARK: {
1091             return ParseHashMaskOperator();
1092         }
1093         case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1094             return ParsePrefixAssertionExpression();
1095         }
1096         default: {
1097             ES2PANDA_UNREACHABLE();
1098         }
1099     }
1100 }
1101 
1102 // NOLINTNEXTLINE(google-default-arguments)
ParsePrimaryExpression(ExpressionParseFlags flags)1103 ir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags)
1104 {
1105     switch (lexer_->GetToken().Type()) {
1106         case lexer::TokenType::KEYW_IMPORT:
1107             return ParseImportExpression();
1108         case lexer::TokenType::PUNCTUATOR_DIVIDE:
1109         case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
1110         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET:
1111         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS:
1112         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE:
1113         case lexer::TokenType::PUNCTUATOR_BACK_TICK:
1114         case lexer::TokenType::PUNCTUATOR_HASH_MARK:
1115         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1116             return ParsePunctuators(flags);
1117         case lexer::TokenType::KEYW_FUNCTION:
1118             return ParseFunctionExpression();
1119         case lexer::TokenType::KEYW_CLASS:
1120             return ParseClassExpression();
1121         case lexer::TokenType::KEYW_THIS:
1122             return ParseThisExpression();
1123         case lexer::TokenType::KEYW_TYPEOF:
1124             return ParseUnaryOrPrefixUpdateExpression();
1125         case lexer::TokenType::KEYW_SUPER:
1126             return ParseSuperExpression();
1127         case lexer::TokenType::KEYW_NEW: {
1128             ir::MetaProperty *newTarget = ParsePotentialNewTarget();
1129             if (newTarget != nullptr) {
1130                 return newTarget;
1131             }
1132             return ParseNewExpression();
1133         }
1134         default:
1135             return ParsePrimaryExpressionWithLiterals(flags);
1136     }
1137 }
1138 
GetOperatorPrecedenceArithmeticAndComparison(const lexer::TokenType operatorType)1139 static constexpr size_t GetOperatorPrecedenceArithmeticAndComparison(const lexer::TokenType operatorType)
1140 {
1141     switch (operatorType) {
1142         case lexer::TokenType::PUNCTUATOR_EQUAL:
1143         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
1144         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
1145         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
1146             constexpr auto PRECEDENCE = 8;
1147             return PRECEDENCE;
1148         }
1149         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1150         case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
1151         case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
1152         case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
1153         case lexer::TokenType::KEYW_INSTANCEOF:
1154         case lexer::TokenType::KEYW_IN: {
1155             constexpr auto PRECEDENCE = 9;
1156             return PRECEDENCE;
1157         }
1158         case lexer::TokenType::PUNCTUATOR_PLUS:
1159         case lexer::TokenType::PUNCTUATOR_MINUS: {
1160             constexpr auto PRECEDENCE = 12;
1161             return PRECEDENCE;
1162         }
1163         case lexer::TokenType::PUNCTUATOR_MULTIPLY:
1164         case lexer::TokenType::PUNCTUATOR_DIVIDE:
1165         case lexer::TokenType::PUNCTUATOR_MOD: {
1166             constexpr auto PRECEDENCE = 13;
1167             return PRECEDENCE;
1168         }
1169         default: {
1170             ES2PANDA_UNREACHABLE();
1171         }
1172     }
1173 }
1174 
GetOperatorPrecedence(const lexer::TokenType operatorType)1175 static constexpr size_t GetOperatorPrecedence(const lexer::TokenType operatorType)
1176 {
1177     ES2PANDA_ASSERT(operatorType == lexer::TokenType::KEYW_AS || lexer::Token::IsBinaryToken(operatorType));
1178 
1179     switch (operatorType) {
1180         case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: {
1181             constexpr auto PRECEDENCE = 1;
1182             return PRECEDENCE;
1183         }
1184         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: {
1185             constexpr auto PRECEDENCE = 2;
1186             return PRECEDENCE;
1187         }
1188         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: {
1189             constexpr auto PRECEDENCE = 4;
1190             return PRECEDENCE;
1191         }
1192         case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
1193             constexpr auto PRECEDENCE = 5;
1194             return PRECEDENCE;
1195         }
1196         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: {
1197             constexpr auto PRECEDENCE = 6;
1198             return PRECEDENCE;
1199         }
1200         case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
1201             constexpr auto PRECEDENCE = 7;
1202             return PRECEDENCE;
1203         }
1204         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1205         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
1206         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
1207             constexpr auto PRECEDENCE = 10;
1208             return PRECEDENCE;
1209         }
1210         case lexer::TokenType::KEYW_AS: {
1211             constexpr auto PRECEDENCE = 11;
1212             return PRECEDENCE;
1213         }
1214         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
1215             constexpr auto PRECEDENCE = 14;
1216             return PRECEDENCE;
1217         }
1218         default: {
1219             return GetOperatorPrecedenceArithmeticAndComparison(operatorType);
1220         }
1221     }
1222 }
1223 
ShouldBinaryExpressionBeAmended(const ir::BinaryExpression * const binaryExpression,const lexer::TokenType operatorType)1224 static inline bool ShouldBinaryExpressionBeAmended(const ir::BinaryExpression *const binaryExpression,
1225                                                    const lexer::TokenType operatorType)
1226 {
1227     return GetOperatorPrecedence(binaryExpression->OperatorType()) <= GetOperatorPrecedence(operatorType) &&
1228            !binaryExpression->IsGrouped() &&
1229            (operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION ||
1230             binaryExpression->OperatorType() != lexer::TokenType::PUNCTUATOR_EXPONENTIATION);
1231 }
1232 
ShouldAsExpressionBeAmended(const ir::TSAsExpression * const asExpression,const lexer::TokenType operatorType)1233 static inline bool ShouldAsExpressionBeAmended(const ir::TSAsExpression *const asExpression,
1234                                                const lexer::TokenType operatorType)
1235 {
1236     return GetOperatorPrecedence(lexer::TokenType::KEYW_AS) <= GetOperatorPrecedence(operatorType) &&
1237            !asExpression->IsGrouped() && operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION;
1238 }
1239 
ShouldExpressionBeAmended(const ir::Expression * const expression,const lexer::TokenType operatorType)1240 static inline bool ShouldExpressionBeAmended(const ir::Expression *const expression,
1241                                              const lexer::TokenType operatorType)
1242 {
1243     bool shouldBeAmended = false;
1244 
1245     if (expression->IsBinaryExpression()) {
1246         shouldBeAmended = ShouldBinaryExpressionBeAmended(expression->AsBinaryExpression(), operatorType);
1247     } else if (expression->IsTSAsExpression()) {
1248         shouldBeAmended = ShouldAsExpressionBeAmended(expression->AsTSAsExpression(), operatorType);
1249     }
1250 
1251     return shouldBeAmended;
1252 }
1253 
AreLogicalAndNullishMixedIncorrectly(const ir::Expression * const expression,const lexer::TokenType operatorType)1254 static inline bool AreLogicalAndNullishMixedIncorrectly(const ir::Expression *const expression,
1255                                                         const lexer::TokenType operatorType)
1256 {
1257     return ((operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1258              operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1259             expression->IsBinaryExpression() &&
1260             expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING &&
1261             !expression->IsGrouped()) ||
1262            (operatorType == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && expression->IsBinaryExpression() &&
1263             (expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1264              expression->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1265             !expression->IsGrouped());
1266 }
1267 
GetAmendedChildExpression(ir::Expression * const expression)1268 static inline ir::Expression *GetAmendedChildExpression(ir::Expression *const expression)
1269 {
1270     ir::Expression *amendedChild = nullptr;
1271 
1272     if (expression->IsBinaryExpression()) {
1273         amendedChild = expression->AsBinaryExpression()->Left();
1274     } else if (expression->IsTSAsExpression()) {
1275         amendedChild = expression->AsTSAsExpression()->Expr();
1276     } else {
1277         ES2PANDA_UNREACHABLE();
1278     }
1279 
1280     return amendedChild;
1281 }
1282 
SetAmendedChildExpression(ir::Expression * const parent,ir::Expression * const amended)1283 static inline void SetAmendedChildExpression(ir::Expression *const parent, ir::Expression *const amended)
1284 {
1285     if (parent->IsBinaryExpression()) {
1286         parent->AsBinaryExpression()->SetLeft(amended);
1287         amended->SetParent(parent);
1288     } else if (parent->IsTSAsExpression()) {
1289         parent->AsTSAsExpression()->SetExpr(amended);
1290         amended->SetParent(parent);
1291     } else {
1292         ES2PANDA_UNREACHABLE();
1293     }
1294 }
1295 
CreateAmendedBinaryExpression(ir::Expression * const left,ir::Expression * const right,const lexer::TokenType operatorType)1296 void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::Expression *const right,
1297                                                const lexer::TokenType operatorType)
1298 {
1299     auto *amended = GetAmendedChildExpression(right);
1300 
1301     amended->SetParent(nullptr);  // Next line overwrite parent
1302     auto *binaryExpr = AllocNode<ir::BinaryExpression>(left, amended, operatorType);
1303 
1304     ES2PANDA_ASSERT(binaryExpr != nullptr);
1305     binaryExpr->SetRange({left->Start(), amended->End()});
1306     SetAmendedChildExpression(right, binaryExpr);
1307 }
1308 
ParseExpressionOrTypeAnnotation(lexer::TokenType type,ExpressionParseFlags flags)1309 ir::Expression *ParserImpl::ParseExpressionOrTypeAnnotation([[maybe_unused]] lexer::TokenType type,
1310                                                             [[maybe_unused]] ExpressionParseFlags flags)
1311 {
1312     return ParseExpression(ExpressionParseFlags::DISALLOW_YIELD);
1313 }
1314 
FindAndAmendChildExpression(ir::Expression * expression,const ir::Expression * left,lexer::TokenType operatorType)1315 static ir::Expression *FindAndAmendChildExpression(ir::Expression *expression, const ir::Expression *left,
1316                                                    lexer::TokenType operatorType)
1317 {
1318     bool shouldBeAmended = true;
1319     ir::Expression *parentExpression = nullptr;
1320     while (shouldBeAmended && GetAmendedChildExpression(expression)->IsBinaryExpression()) {
1321         parentExpression = expression;
1322         parentExpression->SetStart(left->Start());
1323 
1324         expression = GetAmendedChildExpression(expression);
1325         shouldBeAmended = ShouldExpressionBeAmended(expression, operatorType);
1326     }
1327 
1328     return shouldBeAmended ? expression : parentExpression;
1329 }
1330 
ParseBinaryExpression(ir::Expression * left,const lexer::TokenType operatorType)1331 ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const lexer::TokenType operatorType)
1332 {
1333     ES2PANDA_ASSERT(lexer::Token::IsBinaryToken(operatorType));
1334 
1335     if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) {
1336         if ((left->IsUnaryExpression() || left->IsTypeofExpression()) && !left->IsGrouped()) {
1337             LogError(diagnostic::ILLEGAL_EXPRESSION_WRAP);
1338         }
1339     }
1340 
1341     lexer_->NextToken();
1342 
1343     ir::Expression *rightExpr = ParseExpressionOrTypeAnnotation(operatorType, ExpressionParseFlags::DISALLOW_YIELD);
1344     ir::ConditionalExpression *conditionalExpr = nullptr;
1345     if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) {
1346         conditionalExpr = rightExpr->AsConditionalExpression();
1347         rightExpr = conditionalExpr->Test();
1348     }
1349 
1350     if (ShouldExpressionBeAmended(rightExpr, operatorType)) {
1351         if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) {
1352             LogError(diagnostic::NULLISH_COALESCING_MISSING_PARENS);
1353         }
1354 
1355         ir::Expression *expression = FindAndAmendChildExpression(rightExpr, left, operatorType);
1356         CreateAmendedBinaryExpression(left, expression, operatorType);
1357     } else {
1358         if (AreLogicalAndNullishMixedIncorrectly(rightExpr, operatorType)) {
1359             LogError(diagnostic::NULLISH_COALESCING_MISSING_PARENS);
1360         }
1361         const lexer::SourcePosition &endPos = rightExpr->End();
1362         rightExpr = AllocNode<ir::BinaryExpression>(left, rightExpr, operatorType);
1363         ES2PANDA_ASSERT(rightExpr != nullptr);
1364         rightExpr->SetRange({left->Start(), endPos});
1365     }
1366 
1367     if (conditionalExpr != nullptr) {
1368         conditionalExpr->SetStart(rightExpr->Start());
1369         conditionalExpr->SetTest(rightExpr);
1370         return conditionalExpr;
1371     }
1372 
1373     return rightExpr;
1374 }
1375 
ParseCallExpressionArguments(bool & trailingComma,lexer::SourcePosition & endLoc)1376 ArenaVector<ir::Expression *> ParserImpl::ParseCallExpressionArguments(bool &trailingComma,
1377                                                                        lexer::SourcePosition &endLoc)
1378 {
1379     ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
1380 
1381     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT &&
1382         lexer_->Lookahead() == static_cast<char32_t>(ARRAY_FORMAT_NODE)) {
1383         arguments = std::move(ParseExpressionsArrayFormatPlaceholder());
1384         endLoc = Lexer()->GetToken().End();
1385         ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1386     } else {
1387         ParseList(
1388             lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE,
1389             [this, &trailingComma, &arguments]() {
1390                 trailingComma = false;
1391                 ir::Expression *argument {};
1392                 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1393                     argument = ParseSpreadElement();
1394                 } else {
1395                     argument = ParseExpression();
1396                 }
1397                 arguments.push_back(argument);
1398 
1399                 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1400                     trailingComma = true;
1401                 }
1402                 return true;
1403             },
1404             &endLoc, true);
1405     }
1406 
1407     return arguments;
1408 }
1409 
ParseCallExpression(ir::Expression * callee,bool isOptionalChain,bool handleEval)1410 ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool isOptionalChain, bool handleEval)
1411 {
1412     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1413     bool trailingComma {};
1414 
1415     while (true) {
1416         lexer_->NextToken();
1417         lexer::SourcePosition endLoc;
1418         ArenaVector<ir::Expression *> arguments = ParseCallExpressionArguments(trailingComma, endLoc);
1419         ir::CallExpression *callExpr {};
1420 
1421         if (!isOptionalChain && handleEval && callee->IsIdentifier() && callee->AsIdentifier()->Name().Is("eval")) {
1422             auto parserStatus = static_cast<uint32_t>(context_.Status() | ParserStatus::DIRECT_EVAL);
1423             callExpr = AllocNode<ir::DirectEvalExpression>(callee, std::move(arguments), nullptr, isOptionalChain,
1424                                                            parserStatus);
1425         } else {
1426             callExpr =
1427                 AllocNode<ir::CallExpression>(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma);
1428         }
1429         ES2PANDA_ASSERT(callExpr != nullptr);
1430 
1431         callExpr->SetRange({callee->Start(), endLoc});
1432         isOptionalChain = false;
1433 
1434         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1435             ParseTrailingBlock(callExpr);
1436             return callExpr;
1437         }
1438 
1439         callee = callExpr;
1440     }
1441 
1442     ES2PANDA_UNREACHABLE();
1443 }
1444 
ParseOptionalChain(ir::Expression * leftSideExpr)1445 ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr)
1446 {
1447     ir::Expression *returnExpression = nullptr;
1448 
1449     bool isPrivate = false;
1450 
1451     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1452         isPrivate = true;
1453         ValidatePrivateIdentifier();
1454     }
1455 
1456     const auto tokenType = lexer_->GetToken().Type();
1457     if (tokenType == lexer::TokenType::LITERAL_IDENT) {
1458         auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1459         ES2PANDA_ASSERT(identNode != nullptr);
1460         identNode->SetPrivate(isPrivate);
1461         identNode->SetRange(lexer_->GetToken().Loc());
1462 
1463         returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, identNode,
1464                                                            ir::MemberExpressionKind::PROPERTY_ACCESS, false, true);
1465         ES2PANDA_ASSERT(returnExpression != nullptr);
1466         returnExpression->SetRange({leftSideExpr->Start(), identNode->End()});
1467         lexer_->NextToken();
1468     }
1469 
1470     if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) {
1471         lexer_->NextToken();  // eat '['
1472         ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1473 
1474         auto endLoc = lexer_->GetToken().End();
1475         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1476             // test exists for ts extension only
1477             LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
1478         }
1479 
1480         returnExpression = AllocNode<ir::MemberExpression>(leftSideExpr, propertyNode,
1481                                                            ir::MemberExpressionKind::ELEMENT_ACCESS, true, true);
1482         ES2PANDA_ASSERT(returnExpression != nullptr);
1483         returnExpression->SetRange({leftSideExpr->Start(), endLoc});
1484         lexer_->NextToken();
1485     }
1486 
1487     if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1488         returnExpression = ParseCallExpression(leftSideExpr, true);
1489     }
1490 
1491     // Static semantic
1492     if (tokenType == lexer::TokenType::PUNCTUATOR_BACK_TICK ||
1493         lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1494         LogError(diagnostic::TAGGED_TEMPLATE_LITERALS_IN_OPTIONALCHAIN);
1495     }
1496 
1497     return returnExpression;
1498 }
1499 
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc)1500 ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expression **returnExpression,
1501                                                                        const lexer::SourcePosition &startLoc)
1502 {
1503     switch (lexer_->GetToken().Type()) {
1504         case lexer::TokenType::KEYW_FUNCTION: {
1505             *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
1506             ES2PANDA_ASSERT(returnExpression != nullptr);
1507             (*returnExpression)->SetStart(startLoc);
1508             break;
1509         }
1510         case lexer::TokenType::LITERAL_IDENT: {
1511             ir::Expression *identRef = ParsePrimaryExpression();
1512             ES2PANDA_ASSERT(identRef->IsIdentifier());
1513 
1514             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) {
1515                 // test exists for js extension only
1516                 LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW);
1517             }
1518 
1519             ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
1520             arrowFuncExpr->SetStart(startLoc);
1521 
1522             return arrowFuncExpr;
1523         }
1524         case lexer::TokenType::PUNCTUATOR_ARROW: {
1525             ir::ArrowFunctionExpression *arrowFuncExpr =
1526                 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
1527             arrowFuncExpr->SetStart(startLoc);
1528             return arrowFuncExpr;
1529         }
1530         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1531             ir::CallExpression *callExpression = ParseCallExpression(*returnExpression, false);
1532 
1533             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1534                 ir::ArrowFunctionExpression *arrowFuncExpr =
1535                     ParseArrowFunctionExpression(callExpression, nullptr, nullptr, true);
1536                 arrowFuncExpr->SetStart(startLoc);
1537 
1538                 return arrowFuncExpr;
1539             }
1540 
1541             *returnExpression = callExpression;
1542             break;
1543         }
1544         default: {
1545             break;
1546         }
1547     }
1548 
1549     return nullptr;
1550 }
1551 
ParsePotentialGenericFunctionCall(ir::Expression * primaryExpr,ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1552 bool ParserImpl::ParsePotentialGenericFunctionCall([[maybe_unused]] ir::Expression *primaryExpr,
1553                                                    [[maybe_unused]] ir::Expression **returnExpression,
1554                                                    [[maybe_unused]] const lexer::SourcePosition &startLoc,
1555                                                    [[maybe_unused]] bool ignoreCallExpression)
1556 {
1557     return true;
1558 }
1559 
ParsePotentialNonNullExpression(ir::Expression ** returnExpression,lexer::SourcePosition startLoc)1560 bool ParserImpl::ParsePotentialNonNullExpression([[maybe_unused]] ir::Expression **returnExpression,
1561                                                  [[maybe_unused]] lexer::SourcePosition startLoc)
1562 {
1563     return true;
1564 }
1565 
ParsePotentialAsExpression(ir::Expression * primaryExpression)1566 ir::Expression *ParserImpl::ParsePotentialAsExpression([[maybe_unused]] ir::Expression *primaryExpression)
1567 {
1568     return nullptr;
1569 }
1570 
ParseElementAccess(ir::Expression * primaryExpr,bool isOptional)1571 ir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr, bool isOptional)
1572 {
1573     lexer_->NextToken();  // eat '['
1574     ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1575 
1576     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1577         LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
1578     }
1579 
1580     auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, propertyNode,
1581                                                        ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional);
1582     ES2PANDA_ASSERT(memberExpr != nullptr);
1583     memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()});
1584     lexer_->NextToken();
1585     return memberExpr;
1586 }
1587 
ParsePrivatePropertyAccess(ir::Expression * primaryExpr)1588 ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *primaryExpr)
1589 {
1590     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK);
1591 
1592     lexer::SourcePosition memberStart = lexer_->GetToken().Start();
1593     ValidatePrivateIdentifier();
1594 
1595     auto *privateIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1596     ES2PANDA_ASSERT(privateIdent != nullptr);
1597     privateIdent->SetRange({memberStart, lexer_->GetToken().End()});
1598     privateIdent->SetPrivate(true);
1599     lexer_->NextToken();
1600 
1601     auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, privateIdent,
1602                                                        ir::MemberExpressionKind::PROPERTY_ACCESS, false, false);
1603     ES2PANDA_ASSERT(memberExpr != nullptr);
1604     memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()});
1605     return memberExpr;
1606 }
1607 
ParsePropertyAccess(ir::Expression * primaryExpr,bool isOptional)1608 ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExpr, bool isOptional)
1609 {
1610     ir::Identifier *ident = ExpectIdentifier(true);
1611     auto *memberExpr = AllocNode<ir::MemberExpression>(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS,
1612                                                        false, isOptional);
1613     ES2PANDA_ASSERT(memberExpr != nullptr);
1614     memberExpr->SetRange({primaryExpr->Start(), ident->End()});
1615 
1616     return memberExpr;
1617 }
1618 
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)1619 ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
1620                                                        bool ignoreCallExpression, bool *isChainExpression)
1621 {
1622     ir::Expression *returnExpr = primaryExpr;
1623     while (true) {
1624         switch (lexer_->GetToken().Type()) {
1625             case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1626                 returnExpr = ParseElementAccess(returnExpr);
1627                 continue;
1628             }
1629             case lexer::TokenType::LITERAL_IDENT: {
1630                 if (auto *asExpression = ParsePotentialAsExpression(returnExpr); asExpression != nullptr) {
1631                     return asExpression;
1632                 }
1633                 break;
1634             }
1635             case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1636             case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1637                 if (ParsePotentialGenericFunctionCall(primaryExpr, &returnExpr, startLoc, ignoreCallExpression)) {
1638                     break;
1639                 }
1640                 continue;
1641             }
1642             case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1643                 returnExpr = ParsePostPrimaryExpressionBackTick(returnExpr, startLoc);
1644                 continue;
1645             }
1646             case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1647                 if (ignoreCallExpression) {
1648                     break;
1649                 }
1650                 returnExpr = ParseCallExpression(returnExpr, false);
1651                 continue;
1652             }
1653             case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
1654                 if (ParsePotentialNonNullExpression(&returnExpr, startLoc)) {
1655                     break;
1656                 }
1657                 continue;
1658             }
1659             default: {
1660                 auto tmp = ParsePostPrimaryExpressionDot(returnExpr, lexer_->GetToken().Type(), isChainExpression);
1661                 if (tmp != nullptr) {
1662                     returnExpr = tmp;
1663                     continue;
1664                 }
1665             }
1666         }
1667         break;
1668     }
1669     return returnExpr;
1670 }
1671 
ParsePostPrimaryExpressionBackTick(ir::Expression * returnExpression,const lexer::SourcePosition startLoc)1672 ir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *returnExpression,
1673                                                                const lexer::SourcePosition startLoc)
1674 {
1675     ir::TemplateLiteral *propertyNode = ParseTemplateLiteral();
1676     ES2PANDA_ASSERT(propertyNode != nullptr);
1677     lexer::SourcePosition endLoc = propertyNode->End();
1678 
1679     returnExpression = AllocNode<ir::TaggedTemplateExpression>(returnExpression, propertyNode, nullptr);
1680     ES2PANDA_ASSERT(returnExpression != nullptr);
1681     returnExpression->SetRange({startLoc, endLoc});
1682 
1683     return returnExpression;
1684 }
1685 
ParsePostPrimaryExpressionDot(ir::Expression * returnExpression,const lexer::TokenType tokenType,bool * isChainExpression)1686 ir::Expression *ParserImpl::ParsePostPrimaryExpressionDot(ir::Expression *returnExpression,
1687                                                           const lexer::TokenType tokenType, bool *isChainExpression)
1688 {
1689     switch (tokenType) {
1690         case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: {
1691             *isChainExpression = true;
1692             lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat ?.
1693             return ParseOptionalChain(returnExpression);
1694         }
1695         case lexer::TokenType::PUNCTUATOR_PERIOD: {
1696             lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);  // eat period
1697 
1698             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1699                 return ParsePrivatePropertyAccess(returnExpression);
1700             }
1701 
1702             return ParsePropertyAccess(returnExpression);
1703         }
1704         default: {
1705             return nullptr;
1706         }
1707     }
1708 }
1709 
ValidateUpdateExpression(ir::Expression * returnExpression,bool isChainExpression)1710 void ParserImpl::ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression)
1711 {
1712     if ((!returnExpression->IsMemberExpression() && !returnExpression->IsIdentifier() &&
1713          !returnExpression->IsTSNonNullExpression()) ||
1714         isChainExpression) {
1715         LogError(diagnostic::INVALID_LEFT_SITE_OPERATOR);
1716     }
1717 
1718     if (returnExpression->IsIdentifier()) {
1719         const util::StringView &returnExpressionStr = returnExpression->AsIdentifier()->Name();
1720 
1721         if (returnExpressionStr.Is("eval")) {
1722             LogError(diagnostic::ASSIGN_TO_EVAL_INVALID);
1723         }
1724 
1725         if (returnExpressionStr.Is("arguments")) {
1726             LogError(diagnostic::ASSIGN_TO_ARGS_INVALID);
1727         }
1728     }
1729 }
1730 
SetupChainExpr(ir::Expression * const top,lexer::SourcePosition startLoc)1731 ir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::SourcePosition startLoc)
1732 {
1733     auto expr = top;
1734     while (expr->IsTSNonNullExpression()) {
1735         expr = expr->AsTSNonNullExpression()->Expr();
1736     }
1737     auto chainParent = expr->Parent();
1738 
1739     lexer::SourcePosition endLoc = expr->End();
1740     auto chain = AllocNode<ir::ChainExpression>(expr);
1741     ES2PANDA_ASSERT(chain != nullptr);
1742     chain->SetRange({startLoc, endLoc});
1743 
1744     if (expr == top) {
1745         return chain;
1746     }
1747     chainParent->AsTSNonNullExpression()->SetExpr(chain);
1748     chain->SetParent(chainParent);
1749     return top;
1750 }
1751 
ParseMemberExpression(bool ignoreCallExpression,ExpressionParseFlags flags)1752 ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, ExpressionParseFlags flags)
1753 {
1754     bool isAsync = lexer_->GetToken().IsAsyncModifier();
1755     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1756     ir::Expression *returnExpression = ParsePrimaryExpression(flags);
1757     if (lexer_->GetToken().NewLine() && returnExpression->IsArrowFunctionExpression()) {
1758         return returnExpression;
1759     }
1760 
1761     if (isAsync && !lexer_->GetToken().NewLine()) {
1762         context_.Status() |= ParserStatus::ASYNC_FUNCTION;
1763         ir::ArrowFunctionExpression *arrow = ParsePotentialArrowExpression(&returnExpression, startLoc);
1764 
1765         if (arrow != nullptr) {
1766             return arrow;
1767         }
1768     }
1769 
1770     bool isChainExpression;
1771     ir::Expression *prevExpression;
1772     do {
1773         isChainExpression = false;
1774         prevExpression = returnExpression;
1775         returnExpression =
1776             ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression);
1777 
1778         if (isChainExpression) {
1779             returnExpression = SetupChainExpr(returnExpression, startLoc);
1780         }
1781     } while (prevExpression != returnExpression);
1782 
1783     if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) {
1784         lexer::SourcePosition start = returnExpression->Start();
1785 
1786         ValidateUpdateExpression(returnExpression, isChainExpression);
1787 
1788         returnExpression = AllocNode<ir::UpdateExpression>(returnExpression, lexer_->GetToken().Type(), false);
1789 
1790         ES2PANDA_ASSERT(returnExpression != nullptr);
1791         returnExpression->SetRange({start, lexer_->GetToken().End()});
1792         lexer_->NextToken();
1793     }
1794 
1795     return returnExpression;
1796 }
1797 
1798 // NOLINTNEXTLINE(google-default-arguments)
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault)1799 ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault)
1800 {
1801     ir::Expression *returnNode = nullptr;
1802 
1803     switch (lexer_->GetToken().Type()) {
1804         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1805             returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1806             break;
1807         }
1808         case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
1809             if ((flags & ExpressionParseFlags::IN_REST) != 0) {
1810                 LogError(diagnostic::UNEXPECTED_TOKEN);
1811             }
1812             returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1813             break;
1814         }
1815         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1816             returnNode =
1817                 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
1818             break;
1819         }
1820         case lexer::TokenType::LITERAL_IDENT: {
1821             returnNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident(), Allocator());
1822             returnNode->SetRange(lexer_->GetToken().Loc());
1823             lexer_->NextToken();
1824             break;
1825         }
1826         default: {
1827             LogError(diagnostic::UNEXPECTED_TOKEN);
1828             returnNode = AllocBrokenExpression(Lexer()->GetToken().Loc());
1829         }
1830     }
1831 
1832     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1833         return returnNode;
1834     }
1835 
1836     ParsePatternElementErrorCheck(flags, allowDefault);
1837 
1838     ir::Expression *rightNode = ParseExpression();
1839     auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1840         ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1841     ES2PANDA_ASSERT(assignmentExpression != nullptr);
1842     assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
1843 
1844     return assignmentExpression;
1845 }
1846 
ParsePatternElementErrorCheck(const ExpressionParseFlags flags,const bool allowDefault)1847 void ParserImpl::ParsePatternElementErrorCheck(const ExpressionParseFlags flags, const bool allowDefault)
1848 {
1849     if ((flags & ExpressionParseFlags::IN_REST) != 0) {
1850         // unexpected_token_10.js
1851         LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
1852     }
1853 
1854     if (!allowDefault) {
1855         LogError(diagnostic::INVALID_DESTRUCTURING_TARGET);
1856     }
1857 
1858     lexer_->NextToken();
1859 
1860     if (context_.IsGenerator() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
1861         LogError(diagnostic::YIELD_IN_GENERATOR_PARAM);
1862     }
1863 
1864     if (context_.IsAsync() && lexer_->GetToken().Type() == lexer::TokenType::KEYW_AWAIT) {
1865         LogError(diagnostic::ILLEGAL_AWAIT_IN_ASYNC_FUN);
1866     }
1867 }
1868 
CheckPropertyKeyAsyncModifier(ParserStatus * methodStatus)1869 void ParserImpl::CheckPropertyKeyAsyncModifier(ParserStatus *methodStatus)
1870 {
1871     const auto asyncPos = lexer_->Save();
1872     lexer_->NextToken();
1873 
1874     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1875         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
1876         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1877         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1878         if (lexer_->GetToken().NewLine()) {
1879             LogError(diagnostic::ASYNC_METHOD_LINE_TERM);
1880         }
1881 
1882         *methodStatus |= ParserStatus::ASYNC_FUNCTION;
1883     } else {
1884         lexer_->Rewind(asyncPos);
1885     }
1886 }
1887 
IsAccessorDelimiter(char32_t cp)1888 static bool IsAccessorDelimiter(char32_t cp)
1889 {
1890     switch (cp) {
1891         case lexer::LEX_CHAR_LEFT_PAREN:
1892         case lexer::LEX_CHAR_COLON:
1893         case lexer::LEX_CHAR_COMMA:
1894         case lexer::LEX_CHAR_RIGHT_BRACE: {
1895             return true;
1896         }
1897         default: {
1898             return false;
1899         }
1900     }
1901 }
1902 
IsShorthandDelimiter(char32_t cp)1903 static bool IsShorthandDelimiter(char32_t cp)
1904 {
1905     switch (cp) {
1906         case lexer::LEX_CHAR_EQUALS:
1907         case lexer::LEX_CHAR_COMMA:
1908         case lexer::LEX_CHAR_RIGHT_BRACE: {
1909             return true;
1910         }
1911         default: {
1912             return false;
1913         }
1914     }
1915 }
1916 
ValidateAccessor(ExpressionParseFlags flags,lexer::TokenFlags currentTokenFlags)1917 void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags)
1918 {
1919     if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
1920         LogError(diagnostic::UNEXPECTED_TOKEN);
1921     }
1922 
1923     if ((currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) {
1924         LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS);
1925     }
1926 }
1927 
ParseShorthandProperty(const lexer::LexerPosition * startPos)1928 ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos)
1929 {
1930     char32_t nextCp = lexer_->Lookahead();
1931     lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
1932 
1933     /* Rewind the lexer to the beginning of the ident to reparse as common
1934      * identifier */
1935     lexer_->Rewind(*startPos);
1936     lexer_->NextToken();
1937     lexer::SourcePosition start = lexer_->GetToken().Start();
1938 
1939     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1940         // for now no tests are available since the func is called once
1941         // after checking the same token for the identifier
1942         LogExpectedToken(lexer::TokenType::LITERAL_IDENT);
1943     }
1944 
1945     const util::StringView &ident = lexer_->GetToken().Ident();
1946 
1947     auto *key = AllocNode<ir::Identifier>(ident, Allocator());
1948     ES2PANDA_ASSERT(key != nullptr);
1949     key->SetRange(lexer_->GetToken().Loc());
1950 
1951     ir::Expression *value = AllocNode<ir::Identifier>(ident, Allocator());
1952     value->SetRange(lexer_->GetToken().Loc());
1953 
1954     lexer::SourcePosition end;
1955 
1956     if (nextCp == lexer::LEX_CHAR_EQUALS) {
1957         CheckRestrictedBinding(keywordType);
1958 
1959         lexer_->NextToken();  // substitution
1960         lexer_->NextToken();  // eat substitution
1961 
1962         ir::Expression *rightNode = ParseExpression();
1963 
1964         auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1965             ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1966         ES2PANDA_ASSERT(assignmentExpression != nullptr);
1967         assignmentExpression->SetRange({value->Start(), rightNode->End()});
1968         end = rightNode->End();
1969         value = assignmentExpression;
1970     } else {
1971         end = lexer_->GetToken().End();
1972         lexer_->NextToken();
1973     }
1974 
1975     auto *returnProperty = AllocNode<ir::Property>(key, value);
1976     ES2PANDA_ASSERT(returnProperty != nullptr);
1977     returnProperty->SetRange({start, end});
1978 
1979     return returnProperty;
1980 }
1981 
ParsePropertyModifiers(ExpressionParseFlags flags,ir::PropertyKind * propertyKind,ParserStatus * methodStatus)1982 bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::PropertyKind *propertyKind,
1983                                         ParserStatus *methodStatus)
1984 {
1985     if (lexer_->GetToken().IsAsyncModifier()) {
1986         CheckPropertyKeyAsyncModifier(methodStatus);
1987     }
1988 
1989     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
1990         if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
1991             LogError(diagnostic::UNEXPECTED_TOKEN);
1992         }
1993 
1994         lexer_->NextToken();
1995         *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
1996     }
1997 
1998     lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags();
1999     char32_t nextCp = lexer_->Lookahead();
2000     lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
2001     // Parse getter property
2002     if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) {
2003         ValidateAccessor(flags, currentTokenFlags);
2004 
2005         *propertyKind = ir::PropertyKind::GET;
2006         lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2007 
2008         return false;
2009     }
2010 
2011     // Parse setter property
2012     if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) {
2013         ValidateAccessor(flags, currentTokenFlags);
2014 
2015         *propertyKind = ir::PropertyKind::SET;
2016         lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2017 
2018         return false;
2019     }
2020 
2021     // Parse shorthand property or assignment pattern
2022     return (IsShorthandDelimiter(nextCp) && (*methodStatus & ParserStatus::ASYNC_FUNCTION) == 0);
2023 }
2024 
ParseGeneratorPropertyModifier(ExpressionParseFlags flags,ParserStatus * methodStatus)2025 void ParserImpl::ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus)
2026 {
2027     if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) {
2028         LogError(diagnostic::UNEXPECTED_TOKEN);
2029     }
2030 
2031     lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2032     *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
2033 }
2034 
ParsePropertyKey(ExpressionParseFlags flags)2035 ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags)
2036 {
2037     ir::Expression *key = nullptr;
2038 
2039     switch (lexer_->GetToken().Type()) {
2040         case lexer::TokenType::LITERAL_IDENT: {
2041             const util::StringView &ident = lexer_->GetToken().Ident();
2042             key = AllocNode<ir::Identifier>(ident, Allocator());
2043             ES2PANDA_ASSERT(key != nullptr);
2044             key->SetRange(lexer_->GetToken().Loc());
2045             lexer_->NextToken();
2046             return key;
2047         }
2048         case lexer::TokenType::LITERAL_STRING: {
2049             const util::StringView &string = lexer_->GetToken().String();
2050             key = AllocNode<ir::StringLiteral>(string);
2051             ES2PANDA_ASSERT(key != nullptr);
2052             key->SetRange(lexer_->GetToken().Loc());
2053             lexer_->NextToken();
2054             return key;
2055         }
2056         case lexer::TokenType::LITERAL_NUMBER: {
2057             if ((lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) {
2058                 key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
2059             } else {
2060                 key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().GetNumber());
2061             }
2062             ES2PANDA_ASSERT(key != nullptr);
2063             key->SetRange(lexer_->GetToken().Loc());
2064             lexer_->NextToken();
2065             return key;
2066         }
2067         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
2068             lexer_->NextToken();  // eat left square bracket
2069 
2070             key = ParseExpression(flags | ExpressionParseFlags::ACCEPT_COMMA);
2071 
2072             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2073                 // the same test for ts, ets and js extension
2074                 // unexpected_token_52.ets
2075                 LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET);
2076             }
2077             lexer_->NextToken();
2078             return key;
2079         }
2080         default: {
2081             const auto &rangeToken = Lexer()->GetToken().Loc();
2082             LogError(diagnostic::UNEXPECTED_TOKEN);
2083             lexer_->NextToken();
2084             return AllocBrokenExpression(rangeToken);
2085         }
2086     }
2087 }
2088 
ParsePropertyValue(const ir::PropertyKind * propertyKind,const ParserStatus * methodStatus,ExpressionParseFlags flags)2089 ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyKind, const ParserStatus *methodStatus,
2090                                                ExpressionParseFlags flags)
2091 {
2092     bool isMethod = (*methodStatus & ParserStatus::FUNCTION) != 0;
2093     bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
2094 
2095     if (!isMethod && !ir::Property::IsAccessorKind(*propertyKind)) {
2096         // If the actual property is not getter/setter nor method, the following
2097         // token must be ':'
2098         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2099             if (lexer::Token::IsPunctuatorToken(lexer_->GetToken().Type())) {
2100                 LogExpectedToken(lexer::TokenType::PUNCTUATOR_COLON);
2101                 lexer_->NextToken();  // eat colon
2102             } else {
2103                 // we just missed ':'
2104                 LogError(diagnostic::UNEXPECTED_TOKEN);
2105             }
2106         } else {
2107             lexer_->NextToken();  // eat colon
2108         }
2109 
2110         if (!inPattern) {
2111             return ParseExpression(flags);
2112         }
2113 
2114         return ParsePatternElement();
2115     }
2116 
2117     if (inPattern) {
2118         LogError(diagnostic::OBJECT_PATTER_CONTAIN_METHODS);
2119     }
2120 
2121     ParserStatus newStatus = *methodStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2122 
2123     if (*propertyKind != ir::PropertyKind::SET) {
2124         newStatus |= ParserStatus::NEED_RETURN_TYPE;
2125     }
2126 
2127     ir::ScriptFunction *methodDefinitonNode = ParseFunction(newStatus);
2128     ES2PANDA_ASSERT(methodDefinitonNode != nullptr);
2129     methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD);
2130 
2131     size_t paramsSize = methodDefinitonNode->Params().size();
2132 
2133     auto *value = AllocNode<ir::FunctionExpression>(methodDefinitonNode);
2134     ES2PANDA_ASSERT(value != nullptr);
2135     value->SetRange(methodDefinitonNode->Range());
2136 
2137     if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) {
2138         LogError(diagnostic::SETTER_FORMAL_PARAMS);
2139     }
2140 
2141     if (*propertyKind == ir::PropertyKind::GET && paramsSize != 0) {
2142         LogError(diagnostic::GETTER_FORMAL_PARAMS);
2143     }
2144 
2145     return value;
2146 }
2147 
2148 // NOLINTNEXTLINE(google-default-arguments)
ParsePropertyDefinition(ExpressionParseFlags flags)2149 ir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionParseFlags flags)
2150 {
2151     ir::PropertyKind propertyKind = ir::PropertyKind::INIT;
2152     ParserStatus methodStatus = ParserStatus::NO_OPTS;
2153 
2154     const auto startPos = lexer_->Save();
2155     lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT);
2156     lexer::SourcePosition start = lexer_->GetToken().Start();
2157 
2158     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2159         return ParseSpreadElement(flags);
2160     }
2161 
2162     if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
2163         if (ParsePropertyModifiers(flags, &propertyKind, &methodStatus)) {
2164             return ParseShorthandProperty(&startPos);
2165         }
2166     } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2167         ParseGeneratorPropertyModifier(flags, &methodStatus);
2168     }
2169 
2170     bool isComputed = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET;
2171     ir::Expression *key = ParsePropertyKey(flags);
2172 
2173     // Parse method property
2174     if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
2175          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) &&
2176         !ir::Property::IsAccessorKind(propertyKind)) {
2177         methodStatus |= ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2178         propertyKind = ir::PropertyKind::INIT;
2179     } else if ((methodStatus & (ParserStatus::GENERATOR_FUNCTION | ParserStatus::ASYNC_FUNCTION)) != 0) {
2180         LogError(diagnostic::UNEXPECTED_ID);
2181     }
2182 
2183     ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags);
2184     ES2PANDA_ASSERT(value != nullptr);
2185     lexer::SourcePosition end = value->End();
2186 
2187     auto *returnProperty =
2188         AllocNode<ir::Property>(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed);
2189     ES2PANDA_ASSERT(returnProperty != nullptr);
2190     returnProperty->SetRange({start, end});
2191 
2192     return returnProperty;
2193 }
2194 
ParsePropertyEndErrorHendler()2195 void ParserImpl::ParsePropertyEndErrorHendler()
2196 {
2197     const auto pos = lexer_->Save();
2198     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2199         lexer_->NextToken();
2200         if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
2201             // {a. b} -> {a, b}
2202             lexer_->Rewind(pos);
2203             lexer_->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_COMMA);
2204         } else {
2205             lexer_->Rewind(pos);
2206             if (lexer::Token::IsPunctuatorToken(lexer_->GetToken().Type())) {
2207                 // {a, b) -> {a, b}
2208                 lexer_->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
2209             }
2210         }
2211     } else {
2212         lexer_->NextToken();  // {a b} -> we just skip the token
2213         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2214             lexer_->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE);
2215         }
2216     }
2217 }
2218 
ParsePropertyEnd()2219 bool ParserImpl::ParsePropertyEnd()
2220 {
2221     // Property definiton must end with ',' or '}' otherwise we report SyntaxError
2222     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
2223         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2224         // test_object_literal3.ts
2225         LogError(diagnostic::UNEXPECTED_TOKEN);
2226         ParsePropertyEndErrorHendler();
2227     }
2228 
2229     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
2230         lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) {
2231         lexer_->NextToken();
2232         return true;
2233     }
2234 
2235     return false;
2236 }
2237 
2238 // NOLINTNEXTLINE(google-default-arguments)
ParseObjectExpression(ExpressionParseFlags flags)2239 ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags flags)
2240 {
2241     ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
2242     lexer::SourcePosition start = lexer_->GetToken().Start();
2243     ArenaVector<ir::Expression *> properties(Allocator()->Adapter());
2244     bool trailingComma = false;
2245     bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0;
2246 
2247     if (lexer_->Lookahead() == lexer::LEX_CHAR_RIGHT_BRACE) {
2248         lexer_->NextToken();
2249     }
2250 
2251     while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE &&
2252            lexer_->GetToken().Type() != lexer::TokenType::EOS) {
2253         util::ErrorRecursionGuard infiniteLoopBlocker(lexer_);
2254         ir::Expression *property = ParsePropertyDefinition(flags | ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
2255         if (property != nullptr) {
2256             properties.push_back(property);
2257         }
2258 
2259         trailingComma = ParsePropertyEnd();
2260     }
2261 
2262     auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION;
2263     auto *objectExpression =
2264         AllocNode<ir::ObjectExpression>(nodeType, Allocator(), std::move(properties), trailingComma);
2265     ES2PANDA_ASSERT(objectExpression != nullptr);
2266     objectExpression->SetRange({start, lexer_->GetToken().End()});
2267     lexer_->NextToken();
2268 
2269     if (inPattern) {
2270         objectExpression->SetDeclaration();
2271     }
2272 
2273     if ((flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) == 0) {
2274         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
2275             !objectExpression->ConvertibleToObjectPattern()) {
2276             LogError(diagnostic::INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING, {}, objectExpression->Start());
2277         } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2278             ir::ValidationInfo info = objectExpression->ValidateExpression();
2279             if (info.Fail()) {
2280                 LogSyntaxError(info.msg.Utf8(), info.pos);
2281             }
2282         }
2283     }
2284 
2285     return objectExpression;
2286 }
2287 
ParseSequenceExpression(ir::Expression * startExpr,bool acceptRest)2288 ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *startExpr, bool acceptRest)
2289 {
2290     lexer::SourcePosition start = startExpr->Start();
2291 
2292     ArenaVector<ir::Expression *> sequence(Allocator()->Adapter());
2293     sequence.push_back(startExpr);
2294 
2295     while (lexer_->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COMMA)) {
2296         if (acceptRest && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2297             ir::SpreadElement *expr = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
2298             sequence.push_back(expr);
2299             break;
2300         }
2301 
2302         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && lexer_->CheckArrow()) {
2303             break;
2304         }
2305 
2306         auto expr = ParseExpression();
2307         sequence.push_back(expr);
2308     }
2309 
2310     lexer::SourcePosition end = sequence.back()->End();
2311     auto *sequenceNode = AllocNode<ir::SequenceExpression>(std::move(sequence));
2312     ES2PANDA_ASSERT(sequenceNode != nullptr);
2313     sequenceNode->SetRange({start, end});
2314 
2315     return sequenceNode;
2316 }
2317 
2318 // NOLINTNEXTLINE(google-default-arguments)
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)2319 ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
2320 {
2321     if (!lexer_->GetToken().IsUnary()) {
2322         return ParseLeftHandSideExpression(flags);
2323     }
2324 
2325     lexer::TokenType operatorType = lexer_->GetToken().Type();
2326     lexer::SourcePosition start = lexer_->GetToken().Start();
2327     lexer_->NextToken();
2328 
2329     ir::Expression *argument =
2330         lexer_->GetToken().IsUnary() ? ParseUnaryOrPrefixUpdateExpression() : ParseLeftHandSideExpression();
2331 
2332     if (lexer::Token::IsUpdateToken(operatorType)) {
2333         if (!argument->IsIdentifier() && !argument->IsMemberExpression() && !argument->IsTSNonNullExpression()) {
2334             LogError(diagnostic::INVALID_LEFT_IN_PREFIX);
2335         }
2336 
2337         if (argument->IsIdentifier()) {
2338             const util::StringView &argumentStr = argument->AsIdentifier()->Name();
2339 
2340             if (argumentStr.Is("eval")) {
2341                 LogError(diagnostic::ASSIGN_TO_EVAL_INVALID);
2342             } else if (argumentStr.Is("arguments")) {
2343                 LogError(diagnostic::ASSIGN_TO_ARGS_INVALID);
2344             }
2345         }
2346     }
2347 
2348     if (operatorType == lexer::TokenType::KEYW_DELETE) {
2349         if (argument->IsIdentifier()) {
2350             LogError(diagnostic::DELETING_LOCAL_VAR);
2351         }
2352 
2353         if (argument->IsMemberExpression() && argument->AsMemberExpression()->Property()->IsIdentifier() &&
2354             argument->AsMemberExpression()->Property()->AsIdentifier()->IsPrivateIdent()) {
2355             LogError(diagnostic::DELETING_PRIVATE_FIELDS);
2356         }
2357     }
2358 
2359     lexer::SourcePosition end = argument->End();
2360 
2361     ir::Expression *returnExpr = nullptr;
2362 
2363     if (lexer::Token::IsUpdateToken(operatorType)) {
2364         returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true);
2365     } else if (operatorType == lexer::TokenType::KEYW_AWAIT) {
2366         returnExpr = AllocNode<ir::AwaitExpression>(argument);
2367     } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) {
2368         returnExpr = AllocNode<ir::TypeofExpression>(argument);
2369     } else {
2370         returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType);
2371     }
2372 
2373     ES2PANDA_ASSERT(returnExpr != nullptr);
2374     returnExpr->SetRange({start, end});
2375 
2376     return returnExpr;
2377 }
2378 
ParseImportExpression()2379 ir::Expression *ParserImpl::ParseImportExpression()
2380 {
2381     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2382     lexer::SourcePosition endLoc = lexer_->GetToken().End();
2383     lexer_->NextToken();  // eat import
2384 
2385     // parse import.Meta
2386     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) {
2387         if (!context_.IsModule()) {
2388             LogError(diagnostic::IMPORT_META_ONLY_MODULE);
2389         } else if (GetOptions().IsDirectEval()) {
2390             LogError(diagnostic::IMPORT_META_DIRECT_EVAL);
2391         }
2392 
2393         lexer_->NextToken();  // eat dot
2394 
2395         if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT ||
2396             lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_META) {
2397             // js tests only: import_meta_1.js, import_meta_2.js, import_meta_3.js
2398             LogError(diagnostic::META_PROP_FOR_IMPORT);
2399 
2400             lexer_->GetToken().SetTokenType(lexer::TokenType::KEYW_META);
2401         }
2402 
2403         auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::IMPORT_META);
2404         ES2PANDA_ASSERT(metaProperty != nullptr);
2405         metaProperty->SetRange({startLoc, endLoc});
2406 
2407         lexer_->NextToken();
2408         return metaProperty;
2409     }
2410 
2411     ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
2412 
2413     ir::Expression *source = ParseExpression();
2414 
2415     lexer::SourcePosition endImportLoc = lexer_->GetToken().End();
2416     ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS);
2417 
2418     auto *importExpression = AllocNode<ir::ImportExpression>(source);
2419     ES2PANDA_ASSERT(importExpression != nullptr);
2420     importExpression->SetRange({startLoc, endImportLoc});
2421 
2422     return importExpression;
2423 }
2424 
IsNamedFunctionExpression()2425 bool ParserImpl::IsNamedFunctionExpression()
2426 {
2427     return lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS;
2428 }
2429 
ParseFunctionExpression(ParserStatus newStatus)2430 ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStatus)
2431 {
2432     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
2433     ir::Identifier *ident = nullptr;
2434 
2435     if ((newStatus & ParserStatus::ARROW_FUNCTION) == 0) {
2436         ParserStatus savedStatus = context_.Status();
2437         context_.Status() |= static_cast<ParserStatus>(newStatus & ParserStatus::ASYNC_FUNCTION);
2438 
2439         lexer_->NextToken();
2440 
2441         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2442             newStatus |= ParserStatus::GENERATOR_FUNCTION;
2443             lexer_->NextToken();
2444         }
2445 
2446         if (IsNamedFunctionExpression()) {
2447             CheckRestrictedBinding(lexer_->GetToken().KeywordType());
2448             ident = ExpectIdentifier(false, true);
2449         }
2450 
2451         context_.Status() = savedStatus;
2452     }
2453 
2454     ir::ScriptFunction *functionNode = ParseFunction(newStatus);
2455     ES2PANDA_ASSERT(functionNode != nullptr);
2456     functionNode->SetStart(startLoc);
2457 
2458     auto *funcExpr = AllocNode<ir::FunctionExpression>(ident, functionNode);
2459     ES2PANDA_ASSERT(funcExpr != nullptr);
2460     funcExpr->SetRange(functionNode->Range());
2461 
2462     return funcExpr;
2463 }
2464 }  // namespace ark::es2panda::parser
2465