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