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