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