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