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