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