• 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     CHECK_NOT_NULL(typeAnnotation);
140 
141     bool isConst = false;
142     if (typeAnnotation->IsTSTypeReference() && typeAnnotation->AsTSTypeReference()->TypeName()->IsIdentifier()) {
143         const util::StringView &refName = typeAnnotation->AsTSTypeReference()->TypeName()->AsIdentifier()->Name();
144         if (refName.Is("const")) {
145             isConst = true;
146         }
147     }
148 
149     lexer::SourcePosition startLoc = expr->Start();
150     auto *asExpr = AllocNode<ir::TSAsExpression>(expr, typeAnnotation, isConst);
151     asExpr->SetRange({startLoc, lexer_->GetToken().End()});
152 
153     if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
154         lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS &&
155         !(flags & ExpressionParseFlags::EXP_DISALLOW_AS)) {
156         // Prevent stack overflow caused by nesting too many as. For example: a as Int as Int...
157         CHECK_PARSER_RECURSIVE_DEPTH;
158         return ParseTsAsExpression(asExpr, flags);
159     }
160 
161     return asExpr;
162 }
163 
ParseTsSatisfiesExpression(ir::Expression * expr)164 ir::TSSatisfiesExpression *ParserImpl::ParseTsSatisfiesExpression(ir::Expression *expr)
165 {
166     lexer_->NextToken();  // eat 'satisfies'
167     TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
168     ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options);
169 
170     lexer::SourcePosition startLoc = expr->Start();
171     auto *satisfiesExpr = AllocNode<ir::TSSatisfiesExpression>(expr, typeAnnotation);
172     satisfiesExpr->SetRange({startLoc, lexer_->GetToken().End()});
173 
174     if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT &&
175         lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_SATISFIES) {
176         return ParseTsSatisfiesExpression(satisfiesExpr);
177     }
178 
179     return satisfiesExpr;
180 }
181 
ParseExpression(ExpressionParseFlags flags)182 ir::Expression *ParserImpl::ParseExpression(ExpressionParseFlags flags)
183 {
184     if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD && !(flags & ExpressionParseFlags::DISALLOW_YIELD)) {
185         ir::YieldExpression *yieldExpr = ParseYieldExpression();
186 
187         return ParsePotentialExpressionSequence(yieldExpr, flags);
188     }
189 
190     if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
191         const auto startPos = lexer_->Save();
192 
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     CHECK_NOT_NULL(lhsExpression);
744     lexer::TokenType tokenType = lexer_->GetToken().Type();
745     if (lhsExpression->IsGrouped() && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) {
746         if (lhsExpression->IsSequenceExpression()) {
747             for (auto *seq : lhsExpression->AsSequenceExpression()->Sequence()) {
748                 ValidateParenthesizedExpression(seq);
749             }
750         } else {
751             ValidateParenthesizedExpression(lhsExpression);
752         }
753     }
754 
755     switch (tokenType) {
756         case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: {
757             lexer_->NextToken();
758             ir::Expression *consequent = ParseExpression();
759 
760             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
761                 ThrowSyntaxError("Unexpected token, expected ':'");
762             }
763 
764             lexer_->NextToken();
765             ir::Expression *alternate = ParseExpression();
766 
767             auto *conditionalExpr = AllocNode<ir::ConditionalExpression>(lhsExpression, consequent, alternate);
768             conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()});
769             return conditionalExpr;
770         }
771         case lexer::TokenType::PUNCTUATOR_ARROW: {
772             if (lexer_->GetToken().NewLine()) {
773                 ThrowSyntaxError("Uncaught SyntaxError: expected expression, got '=>'");
774             }
775 
776             return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false);
777         }
778         case lexer::TokenType::KEYW_IN: {
779             if (flags & ExpressionParseFlags::STOP_AT_IN) {
780                 break;
781             }
782 
783             [[fallthrough]];
784         }
785         case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING:
786         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR:
787         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
788         case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
789         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR:
790         case lexer::TokenType::PUNCTUATOR_BITWISE_AND:
791         case lexer::TokenType::PUNCTUATOR_EQUAL:
792         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
793         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
794         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
795         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
796         case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
797         case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
798         case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
799         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
800         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
801         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
802         case lexer::TokenType::PUNCTUATOR_PLUS:
803         case lexer::TokenType::PUNCTUATOR_MINUS:
804         case lexer::TokenType::PUNCTUATOR_MULTIPLY:
805         case lexer::TokenType::PUNCTUATOR_DIVIDE:
806         case lexer::TokenType::PUNCTUATOR_MOD:
807         case lexer::TokenType::KEYW_INSTANCEOF:
808         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
809             ir::Expression *binaryExpression = ParseBinaryExpression(lhsExpression);
810 
811             return ParseAssignmentExpression(binaryExpression);
812         }
813         case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: {
814             ValidateAssignmentTarget(flags, lhsExpression);
815 
816             lexer_->NextToken();
817             ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
818 
819             auto *binaryAssignmentExpression =
820                 AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
821 
822             binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
823             return binaryAssignmentExpression;
824         }
825         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL:
826         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL:
827         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL:
828         case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL:
829         case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL:
830         case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL:
831         case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL:
832         case lexer::TokenType::PUNCTUATOR_MOD_EQUAL:
833         case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL:
834         case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL:
835         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL:
836         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL:
837         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL:
838         case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL:
839         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: {
840             ValidateLvalueAssignmentTarget(lhsExpression);
841 
842             lexer_->NextToken();
843             ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags));
844 
845             auto *binaryAssignmentExpression =
846                 AllocNode<ir::AssignmentExpression>(lhsExpression, assignmentExpression, tokenType);
847 
848             binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()});
849             return binaryAssignmentExpression;
850         }
851         case lexer::TokenType::LITERAL_IDENT: {
852             lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
853             if (Extension() == ScriptExtension::TS && keywordType == lexer::TokenType::KEYW_AS &&
854                 !(flags & ExpressionParseFlags::EXP_DISALLOW_AS) && !lexer_->GetToken().NewLine()) {
855                 ir::Expression *asExpression = ParseTsAsExpression(lhsExpression, flags);
856                 return ParseAssignmentExpression(asExpression);
857             } else if (Extension() == ScriptExtension::TS && keywordType == lexer::TokenType::KEYW_SATISFIES &&
858                 !lexer_->GetToken().NewLine()) {
859                 ir::Expression *satisfiesExpression = ParseTsSatisfiesExpression(lhsExpression);
860                 return ParseAssignmentExpression(satisfiesExpression);
861             }
862             break;
863         }
864         default:
865             break;
866     }
867 
868     return lhsExpression;
869 }
870 
ParseTemplateLiteral(bool isTaggedTemplate)871 ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral(bool isTaggedTemplate)
872 {
873     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
874 
875     ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter());
876     ArenaVector<ir::Expression *> expressions(Allocator()->Adapter());
877 
878     while (true) {
879         lexer_->ResetTokenEnd();
880         const auto startPos = lexer_->Save();
881         if (isTaggedTemplate) {
882             lexer_->AssignTokenTaggedTemplate();
883         }
884         lexer_->ScanString<LEX_CHAR_BACK_TICK>();
885         util::StringView cooked = lexer_->GetToken().String();
886         bool escapeError = lexer_->GetToken().EscapeError();
887 
888         lexer_->Rewind(startPos);
889         auto [raw, end, scanExpression] = lexer_->ScanTemplateString();
890 
891         auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked);
892         element->SetEscapeError(escapeError);
893         element->SetRange({lexer::SourcePosition {startPos.iterator.Index(), startPos.line},
894                            lexer::SourcePosition {end, lexer_->Line()}});
895         quasis.push_back(element);
896 
897         if (!scanExpression) {
898             lexer_->ScanTemplateStringEnd();
899             break;
900         }
901 
902         ir::Expression *expression = nullptr;
903 
904         {
905             lexer::TemplateLiteralParserContext ctx(lexer_);
906             lexer_->PushTemplateContext(&ctx);
907             lexer_->NextToken();
908             expression = ParseExpression();
909         }
910 
911         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
912             ThrowSyntaxError("Unexpected token, expected '}'.");
913         }
914 
915         expressions.push_back(expression);
916     }
917 
918     auto *templateNode = AllocNode<ir::TemplateLiteral>(std::move(quasis), std::move(expressions));
919     templateNode->SetRange({startLoc, lexer_->GetToken().End()});
920 
921     lexer_->NextToken();
922 
923     return templateNode;
924 }
925 
ParseNewExpression()926 ir::NewExpression *ParserImpl::ParseNewExpression()
927 {
928     lexer::SourcePosition start = lexer_->GetToken().Start();
929 
930     lexer_->NextToken();  // eat new
931 
932     // parse callee part of NewExpression
933     ir::Expression *callee = ParseMemberExpression(true);
934     if (callee->IsImportExpression() && !callee->IsGrouped()) {
935         ThrowSyntaxError("Cannot use new with import(...)");
936     }
937 
938     // parse type params of NewExpression
939     lexer::SourcePosition endLoc = callee->End();
940     ir::TSTypeParameterInstantiation *typeParamInst = nullptr;
941     if (Extension() == ScriptExtension::TS) {
942         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
943             lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
944         }
945         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
946             typeParamInst = ParseTsTypeParameterInstantiation();
947             if (typeParamInst != nullptr) {
948                 endLoc = typeParamInst->End();
949             }
950         }
951     }
952 
953     ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
954 
955     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
956         auto *newExprNode = AllocNode<ir::NewExpression>(callee, typeParamInst, std::move(arguments));
957         newExprNode->SetRange({start, endLoc});
958 
959         return newExprNode;
960     }
961 
962     lexer_->NextToken();  // eat left pranthesis
963 
964     // parse argument part of NewExpression
965     while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
966         ir::Expression *argument = nullptr;
967 
968         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
969             argument = ParseSpreadElement();
970         } else {
971             argument = ParseExpression();
972         }
973 
974         arguments.push_back(argument);
975 
976         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
977             lexer_->NextToken();  // eat comma
978         }
979 
980         if (lexer_->GetToken().Type() == lexer::TokenType::EOS) {
981             ThrowSyntaxError("Unexpected token in argument parsing");
982         }
983     }
984 
985     auto *newExprNode = AllocNode<ir::NewExpression>(callee, typeParamInst, std::move(arguments));
986     newExprNode->SetRange({start, lexer_->GetToken().End()});
987 
988     lexer_->NextToken();
989 
990     return newExprNode;
991 }
992 
ParseLeftHandSideExpression(ExpressionParseFlags flags)993 ir::Expression *ParserImpl::ParseLeftHandSideExpression(ExpressionParseFlags flags)
994 {
995     return ParseMemberExpression(false, flags);
996 }
997 
ParsePotentialNewTarget()998 ir::MetaProperty *ParserImpl::ParsePotentialNewTarget()
999 {
1000     lexer::SourceRange loc = lexer_->GetToken().Loc();
1001 
1002     if (lexer_->Lookahead() == LEX_CHAR_DOT) {
1003         lexer_->NextToken();
1004         lexer_->NextToken();
1005 
1006         if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && lexer_->GetToken().Ident().Is("target")) {
1007             if (!(context_.Status() & ParserStatus::ALLOW_NEW_TARGET)) {
1008                 ThrowSyntaxError("'new.Target' is not allowed here");
1009             }
1010 
1011             if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) {
1012                 ThrowSyntaxError("'new.Target' must not contain escaped characters");
1013             }
1014 
1015             auto *metaProperty = AllocNode<ir::MetaProperty>(ir::MetaProperty::MetaPropertyKind::NEW_TARGET);
1016             metaProperty->SetRange(loc);
1017             lexer_->NextToken();
1018             return metaProperty;
1019         }
1020     }
1021 
1022     return nullptr;
1023 }
1024 
ParsePrimaryExpression(ExpressionParseFlags flags)1025 ir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags)
1026 {
1027     switch (lexer_->GetToken().Type()) {
1028         case lexer::TokenType::KEYW_IMPORT: {
1029             return ParseImportExpression();
1030         }
1031         case lexer::TokenType::LITERAL_IDENT: {
1032             auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1033             identNode->SetReference();
1034             identNode->SetRange(lexer_->GetToken().Loc());
1035 
1036             lexer_->NextToken();
1037 
1038             if (Extension() == ScriptExtension::TS && (flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN) &&
1039                 lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
1040                 context_.Status() |= ParserStatus::FUNCTION_PARAM;
1041                 ParsePotentialTsFunctionParameter(ExpressionParseFlags::NO_OPTS, identNode);
1042             }
1043 
1044             return identNode;
1045         }
1046         case lexer::TokenType::LITERAL_TRUE: {
1047             auto *trueNode = AllocNode<ir::BooleanLiteral>(true);
1048             trueNode->SetRange(lexer_->GetToken().Loc());
1049 
1050             lexer_->NextToken();
1051             return trueNode;
1052         }
1053         case lexer::TokenType::LITERAL_FALSE: {
1054             auto *falseNode = AllocNode<ir::BooleanLiteral>(false);
1055             falseNode->SetRange(lexer_->GetToken().Loc());
1056 
1057             lexer_->NextToken();
1058             return falseNode;
1059         }
1060         case lexer::TokenType::LITERAL_NULL: {
1061             auto *nullNode = AllocNode<ir::NullLiteral>();
1062             nullNode->SetRange(lexer_->GetToken().Loc());
1063 
1064             lexer_->NextToken();
1065             return nullNode;
1066         }
1067         case lexer::TokenType::LITERAL_NUMBER: {
1068             ir::Expression *numberNode = nullptr;
1069 
1070             if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
1071                 numberNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
1072             } else {
1073                 numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
1074             }
1075 
1076             numberNode->SetRange(lexer_->GetToken().Loc());
1077 
1078             lexer_->NextToken();
1079             return numberNode;
1080         }
1081         case lexer::TokenType::LITERAL_STRING: {
1082             auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String());
1083             stringNode->SetRange(lexer_->GetToken().Loc());
1084 
1085             lexer_->NextToken();
1086             return stringNode;
1087         }
1088         case lexer::TokenType::PUNCTUATOR_DIVIDE:
1089         case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: {
1090             lexer_->ResetTokenEnd();
1091             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL) {
1092                 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_DIVIDE, 1);
1093             }
1094             auto regexp = lexer_->ScanRegExp();
1095 
1096             lexer::RegExpParser reParser(regexp, Allocator());
1097 
1098             try {
1099                 reParser.ParsePattern();
1100             } catch (lexer::RegExpError &e) {
1101                 ThrowSyntaxError(e.message.c_str());
1102             }
1103 
1104             auto *regexpNode = AllocNode<ir::RegExpLiteral>(regexp.patternStr, regexp.flagsStr);
1105             regexpNode->SetRange(lexer_->GetToken().Loc());
1106 
1107             lexer_->NextToken();
1108             return regexpNode;
1109         }
1110         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1111             // Prevent stack overflow caused by nesting too many '['. For example: [[[...
1112             CHECK_PARSER_RECURSIVE_DEPTH;
1113             return ParseArrayExpression(CarryAllowTsParamAndPatternFlags(flags));
1114         }
1115         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1116             return ParseCoverParenthesizedExpressionAndArrowParameterList();
1117         }
1118         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1119             return ParseObjectExpression(CarryAllowTsParamAndPatternFlags(flags));
1120         }
1121         case lexer::TokenType::KEYW_FUNCTION: {
1122             return ParseFunctionExpression();
1123         }
1124         case lexer::TokenType::KEYW_CLASS: {
1125             lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1126             ir::ClassDefinition *classDefinition = ParseClassDefinition(false);
1127 
1128             auto *classExpr = AllocNode<ir::ClassExpression>(classDefinition);
1129             classExpr->SetRange({startLoc, classDefinition->End()});
1130 
1131             return classExpr;
1132         }
1133         case lexer::TokenType::KEYW_THIS: {
1134             auto *thisExprNode = AllocNode<ir::ThisExpression>();
1135             thisExprNode->SetRange(lexer_->GetToken().Loc());
1136 
1137             lexer_->NextToken();  // eat this
1138             return thisExprNode;
1139         }
1140         case lexer::TokenType::KEYW_SUPER: {
1141             auto *superExprNode = AllocNode<ir::SuperExpression>();
1142             superExprNode->SetRange(lexer_->GetToken().Loc());
1143 
1144             lexer_->NextToken();  // eat super
1145 
1146             if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD ||
1147                  lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) &&
1148                 (context_.Status() & ParserStatus::ALLOW_SUPER)) {
1149                 return superExprNode;
1150             }
1151 
1152             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1153                 (context_.Status() & ParserStatus::ALLOW_SUPER_CALL)) {
1154                 return superExprNode;
1155             }
1156 
1157             ThrowSyntaxError("Unexpected super keyword");
1158         }
1159         case lexer::TokenType::KEYW_NEW: {
1160             ir::MetaProperty *newTarget = ParsePotentialNewTarget();
1161 
1162             if (newTarget) {
1163                 return newTarget;
1164             }
1165 
1166             return ParseNewExpression();
1167         }
1168         case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1169             return ParseTemplateLiteral();
1170         }
1171         default: {
1172             break;
1173         }
1174     }
1175 
1176     ThrowSyntaxError("Primary expression expected");
1177     return nullptr;
1178 }
1179 
GetOperatorPrecedence(lexer::TokenType operatorType)1180 static size_t GetOperatorPrecedence(lexer::TokenType operatorType)
1181 {
1182     ASSERT(lexer::Token::IsBinaryToken(operatorType));
1183 
1184     switch (operatorType) {
1185         case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: {
1186             constexpr auto precedence = 1;
1187             return precedence;
1188         }
1189         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: {
1190             constexpr auto precedence = 2;
1191             return precedence;
1192         }
1193         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
1194         case lexer::TokenType::PUNCTUATOR_BITWISE_OR: {
1195             constexpr auto precedence = 3;
1196             return precedence;
1197         }
1198         case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: {
1199             constexpr auto precedence = 4;
1200             return precedence;
1201         }
1202         case lexer::TokenType::PUNCTUATOR_BITWISE_AND: {
1203             constexpr auto precedence = 5;
1204             return precedence;
1205         }
1206         case lexer::TokenType::PUNCTUATOR_EQUAL:
1207         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
1208         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
1209         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
1210             constexpr auto precedence = 6;
1211             return precedence;
1212         }
1213         case lexer::TokenType::PUNCTUATOR_LESS_THAN:
1214         case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
1215         case lexer::TokenType::PUNCTUATOR_GREATER_THAN:
1216         case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL:
1217         case lexer::TokenType::KEYW_INSTANCEOF:
1218         case lexer::TokenType::KEYW_IN: {
1219             constexpr auto precedence = 7;
1220             return precedence;
1221         }
1222         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1223         case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
1224         case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: {
1225             constexpr auto precedence = 8;
1226             return precedence;
1227         }
1228         case lexer::TokenType::PUNCTUATOR_PLUS:
1229         case lexer::TokenType::PUNCTUATOR_MINUS: {
1230             constexpr auto precedence = 9;
1231             return precedence;
1232         }
1233         case lexer::TokenType::PUNCTUATOR_MULTIPLY:
1234         case lexer::TokenType::PUNCTUATOR_DIVIDE:
1235         case lexer::TokenType::PUNCTUATOR_MOD: {
1236             const auto precedence = 10;
1237             return precedence;
1238         }
1239         case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
1240             constexpr auto precedence = 11;
1241             return precedence;
1242         }
1243         default: {
1244             UNREACHABLE();
1245         }
1246     }
1247 }
1248 
ShouldBinaryExpressionBeAmended(ir::BinaryExpression * binaryExpression,lexer::TokenType operatorType)1249 static inline bool ShouldBinaryExpressionBeAmended(ir::BinaryExpression *binaryExpression,
1250                                                    lexer::TokenType operatorType)
1251 {
1252     return GetOperatorPrecedence(binaryExpression->OperatorType()) <= GetOperatorPrecedence(operatorType) &&
1253            !binaryExpression->IsGrouped() &&
1254            (operatorType != lexer::TokenType::PUNCTUATOR_EXPONENTIATION ||
1255             binaryExpression->OperatorType() != lexer::TokenType::PUNCTUATOR_EXPONENTIATION);
1256 }
1257 
ParseBinaryExpression(ir::Expression * left)1258 ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left)
1259 {
1260     lexer::TokenType operatorType = lexer_->GetToken().Type();
1261     ASSERT(lexer::Token::IsBinaryToken(operatorType));
1262 
1263     if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) {
1264         if (left->IsUnaryExpression() && !left->IsGrouped()) {
1265             ThrowSyntaxError(
1266                 "Illegal expression. Wrap left hand side or entire "
1267                 "exponentiation in parentheses.");
1268         }
1269     }
1270 
1271     lexer_->NextToken();
1272 
1273     ir::Expression *rightExprNode = ParseExpression(ExpressionParseFlags::DISALLOW_YIELD);
1274 
1275     ir::Expression *rightExpr = rightExprNode;
1276     ir::ConditionalExpression *conditionalExpr = nullptr;
1277 
1278     if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) {
1279         conditionalExpr = rightExpr->AsConditionalExpression();
1280         rightExpr = conditionalExpr->Test();
1281     }
1282 
1283     if (rightExpr->IsBinaryExpression() &&
1284         ShouldBinaryExpressionBeAmended(rightExpr->AsBinaryExpression(), operatorType)) {
1285         if ((operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR ||
1286              operatorType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) &&
1287             rightExpr->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING) {
1288             ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1289         }
1290 
1291         bool shouldBeAmended = true;
1292 
1293         ir::BinaryExpression *binaryExpression = rightExpr->AsBinaryExpression();
1294         ir::BinaryExpression *parentExpression = nullptr;
1295 
1296         while (binaryExpression->Left()->IsBinaryExpression() && shouldBeAmended) {
1297             parentExpression = binaryExpression;
1298             parentExpression->SetStart(left->Start());
1299             binaryExpression = binaryExpression->Left()->AsBinaryExpression();
1300             shouldBeAmended = ShouldBinaryExpressionBeAmended(binaryExpression, operatorType);
1301         }
1302 
1303         if (shouldBeAmended) {
1304             auto *leftExprNode = AllocNode<ir::BinaryExpression>(left, binaryExpression->Left(), operatorType);
1305             leftExprNode->SetRange({left->Start(), binaryExpression->Left()->End()});
1306 
1307             binaryExpression->SetLeft(leftExprNode);
1308         } else {
1309             // Transfer the parent's left ownership to right_node
1310             ir::Expression *rightNode = parentExpression->Left();
1311 
1312             auto *binaryOrLogicalExpressionNode = AllocNode<ir::BinaryExpression>(left, rightNode, operatorType);
1313             binaryOrLogicalExpressionNode->SetRange({left->Start(), rightNode->End()});
1314 
1315             parentExpression->SetLeft(binaryOrLogicalExpressionNode);
1316         }
1317     } else {
1318         if (operatorType == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && rightExpr->IsBinaryExpression() &&
1319             rightExpr->AsBinaryExpression()->IsLogical() && !rightExpr->IsGrouped()) {
1320             ThrowSyntaxError("Nullish coalescing operator ?? requires parens when mixing with logical operators.");
1321         }
1322         const lexer::SourcePosition &endPos = rightExpr->End();
1323         rightExpr = AllocNode<ir::BinaryExpression>(left, rightExpr, operatorType);
1324         rightExpr->SetRange({left->Start(), endPos});
1325     }
1326 
1327     if (conditionalExpr != nullptr) {
1328         conditionalExpr->SetStart(rightExpr->Start());
1329         conditionalExpr->SetTest(rightExpr);
1330         return conditionalExpr;
1331     }
1332 
1333     return rightExpr;
1334 }
1335 
ParseCallExpression(ir::Expression * callee,bool isOptionalChain,bool isAsync)1336 ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool isOptionalChain, bool isAsync)
1337 {
1338     ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS);
1339 
1340     while (true) {
1341         lexer_->NextToken();
1342         ArenaVector<ir::Expression *> arguments(Allocator()->Adapter());
1343 
1344         while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1345             ir::Expression *argument = nullptr;
1346             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
1347                 argument = ParseSpreadElement();
1348             } else {
1349                 argument = ParseExpression(isAsync ? ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN
1350                                                    : ExpressionParseFlags::NO_OPTS);
1351             }
1352 
1353             arguments.push_back(argument);
1354 
1355             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
1356                 lexer_->NextToken();
1357             } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) {
1358                 ThrowSyntaxError("Expected a ')'");
1359             }
1360         }
1361 
1362         auto *callExpr = AllocNode<ir::CallExpression>(callee, std::move(arguments), nullptr, isOptionalChain);
1363         callExpr->SetRange({callee->Start(), lexer_->GetToken().End()});
1364         isOptionalChain = false;
1365 
1366         lexer_->NextToken();
1367 
1368         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1369             return callExpr;
1370         }
1371 
1372         callee = callExpr;
1373     }
1374 
1375     UNREACHABLE();
1376     return nullptr;
1377 }
1378 
ParseOptionalChain(ir::Expression * leftSideExpr)1379 ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr)
1380 {
1381     lexer::TokenType tokenType = lexer_->GetToken().Type();
1382     ir::Expression *returnExpression = nullptr;
1383 
1384     switch (tokenType) {
1385         case lexer::TokenType::PUNCTUATOR_HASH_MARK:
1386         case lexer::TokenType::LITERAL_IDENT:
1387         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1388             returnExpression = ParseOptionalMemberExpression(leftSideExpr);
1389             break;
1390         }
1391         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1392             returnExpression = ParseCallExpression(leftSideExpr, true);
1393             break;
1394         }
1395         case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1396             if (Extension() != ScriptExtension::TS) {
1397                 ThrowSyntaxError("Unexpected token");
1398             }
1399 
1400             ir::TSTypeParameterInstantiation *typeParams = ParseTsTypeParameterInstantiation(true);
1401 
1402             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1403                 ThrowSyntaxError("Expected '('");
1404             }
1405 
1406             returnExpression = ParseCallExpression(leftSideExpr, true);
1407             returnExpression->AsCallExpression()->SetTypeParams(typeParams);
1408             break;
1409         }
1410         case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1411             ThrowSyntaxError("Tagged Template Literals are not allowed in optionalChain");
1412         }
1413         default: {
1414             ThrowSyntaxError("Unexpected token");
1415         }
1416     }
1417 
1418     // Static semantic
1419     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1420         ThrowSyntaxError("Tagged Template Literals are not allowed in optionalChain");
1421     }
1422 
1423     return returnExpression;
1424 }
1425 
ParseOptionalMemberExpression(ir::Expression * object)1426 ir::Expression *ParserImpl::ParseOptionalMemberExpression(ir::Expression *object)
1427 {
1428     ir::Expression *property = nullptr;
1429     bool computed = false;
1430     auto kind = ir::MemberExpression::MemberExpressionKind::PROPERTY_ACCESS;
1431 
1432     lexer::SourcePosition end;
1433     lexer::TokenType tokenType = lexer_->GetToken().Type();
1434     ASSERT(tokenType == lexer::TokenType::PUNCTUATOR_HASH_MARK || tokenType == lexer::TokenType::LITERAL_IDENT ||
1435         tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET);
1436 
1437     if (tokenType == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1438         property = ParsePrivateIdentifier();
1439         end = property->End();
1440     } else if (tokenType == lexer::TokenType::LITERAL_IDENT) {
1441         property = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1442         property->AsIdentifier()->SetReference();
1443         property->SetRange(lexer_->GetToken().Loc());
1444         end = lexer_->GetToken().End();
1445         lexer_->NextToken();
1446     } else {
1447         computed = true;
1448         kind = ir::MemberExpression::MemberExpressionKind::ELEMENT_ACCESS;
1449         lexer_->NextToken();  // eat '['
1450         property = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1451 
1452         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1453             ThrowSyntaxError("Expected ']'");
1454         }
1455         end = lexer_->GetToken().End();
1456         lexer_->NextToken();
1457     }
1458 
1459     auto *memberExpr = AllocNode<ir::MemberExpression>(object, property, kind, computed, true);
1460     memberExpr->SetRange({object->Start(), end});
1461     return memberExpr;
1462 }
1463 
ParsePotentialArrowExpression(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1464 ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expression **returnExpression,
1465                                                                        const lexer::SourcePosition &startLoc,
1466                                                                        bool ignoreCallExpression)
1467 {
1468     ir::TSTypeParameterDeclaration *typeParamDecl = nullptr;
1469 
1470     const auto savedPos = lexer_->Save();
1471 
1472     switch (lexer_->GetToken().Type()) {
1473         case lexer::TokenType::KEYW_FUNCTION: {
1474             *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION);
1475             (*returnExpression)->SetStart(startLoc);
1476             break;
1477         }
1478         case lexer::TokenType::LITERAL_IDENT: {
1479             if (!lexer_->CheckArrow()) {
1480                 return nullptr;
1481             }
1482 
1483             ir::Expression *identRef = ParsePrimaryExpression();
1484             ASSERT(identRef->IsIdentifier());
1485 
1486             ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true);
1487             arrowFuncExpr->SetStart(startLoc);
1488 
1489             return arrowFuncExpr;
1490         }
1491         case lexer::TokenType::PUNCTUATOR_ARROW: {
1492             ir::ArrowFunctionExpression *arrowFuncExpr =
1493                 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true);
1494             arrowFuncExpr->SetStart(startLoc);
1495             return arrowFuncExpr;
1496         }
1497         case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: {
1498             if (Extension() == ScriptExtension::TS) {
1499                 return nullptr;
1500             }
1501 
1502             break;
1503         }
1504         case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1505             if (Extension() != ScriptExtension::TS) {
1506                 return nullptr;
1507             }
1508 
1509             typeParamDecl = ParseTsTypeParameterDeclaration(false);
1510             if (!typeParamDecl) {
1511                 lexer_->Rewind(savedPos);
1512                 return nullptr;
1513             }
1514 
1515             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1516                 ThrowSyntaxError("'(' expected");
1517             }
1518 
1519             [[fallthrough]];
1520         }
1521         case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1522             if (ignoreCallExpression) {
1523                 lexer_->Rewind(savedPos);
1524                 break;
1525             }
1526             ir::CallExpression *callExpression = ParseCallExpression(*returnExpression, false, true);
1527 
1528             ir::Expression *returnTypeAnnotation = nullptr;
1529             if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1530                 lexer_->NextToken();  // eat ':'
1531                 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1532                 returnTypeAnnotation = ParseTsTypeAnnotation(&options);
1533             }
1534 
1535             if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) {
1536                 ir::ArrowFunctionExpression *arrowFuncExpr =
1537                     ParseArrowFunctionExpression(callExpression, typeParamDecl, returnTypeAnnotation, true);
1538                 arrowFuncExpr->SetStart(startLoc);
1539 
1540                 return arrowFuncExpr;
1541             }
1542 
1543             if (Extension() == ScriptExtension::TS && (returnTypeAnnotation || typeParamDecl)) {
1544                 ThrowSyntaxError("'=>' expected");
1545             }
1546 
1547             *returnExpression = callExpression;
1548             break;
1549         }
1550         default: {
1551             break;
1552         }
1553     }
1554 
1555     return nullptr;
1556 }
1557 
IsGenericInstantiation()1558 bool ParserImpl::IsGenericInstantiation()
1559 {
1560     switch (lexer_->GetToken().Type()) {
1561         case lexer::TokenType::EOS:
1562         case lexer::TokenType::PUNCTUATOR_SEMI_COLON:
1563         case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS:
1564         case lexer::TokenType::PUNCTUATOR_RIGHT_BRACE:
1565         case lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET:
1566         case lexer::TokenType::PUNCTUATOR_EQUAL:
1567         case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL:
1568         case lexer::TokenType::PUNCTUATOR_NOT_EQUAL:
1569         case lexer::TokenType::PUNCTUATOR_QUESTION_MARK:
1570         case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL:
1571         case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL:
1572         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND:
1573         case lexer::TokenType::PUNCTUATOR_SUBSTITUTION:
1574         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR:
1575         case lexer::TokenType::PUNCTUATOR_COMMA:
1576         case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING:
1577         case lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL:
1578         case lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL:
1579         case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: {
1580             return true;
1581         }
1582         default: {
1583             return false;
1584         }
1585     }
1586 }
1587 
ParsePotentialTsGenericFunctionCall(ir::Expression ** returnExpression,const lexer::SourcePosition & startLoc,bool ignoreCallExpression)1588 bool ParserImpl::ParsePotentialTsGenericFunctionCall(ir::Expression **returnExpression,
1589                                                      const lexer::SourcePosition &startLoc, bool ignoreCallExpression)
1590 {
1591     if (Extension() != ScriptExtension::TS || lexer_->Lookahead() == LEX_CHAR_LESS_THAN) {
1592         return true;
1593     }
1594 
1595     const auto savedPos = lexer_->Save();
1596 
1597     bool isLeftShift = false;
1598     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) {
1599         lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1);
1600         isLeftShift = true;
1601     }
1602 
1603     ir::TSTypeParameterInstantiation *typeParams;
1604     try {
1605         typeParams = ParseTsTypeParameterInstantiation(false);
1606     } catch (const Error &e) {
1607         if (!isLeftShift) {
1608             throw e;
1609         }
1610         typeParams = nullptr;
1611     }
1612 
1613     if (!typeParams) {
1614         lexer_->Rewind(savedPos);
1615         return true;
1616     }
1617 
1618     if (IsGenericInstantiation() || lexer_->GetToken().NewLine()) {
1619         *returnExpression = AllocNode<ir::TypeArgumentsExpression>(*returnExpression, typeParams);
1620         lexer::SourcePosition endLoc = typeParams->End();
1621         (*returnExpression)->SetRange({startLoc, endLoc});
1622         return false;
1623     }
1624 
1625     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) {
1626         if (!ignoreCallExpression) {
1627             *returnExpression = ParseCallExpression(*returnExpression, false);
1628             (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams);
1629             return false;
1630         }
1631     }
1632 
1633     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) {
1634         ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(true);
1635         lexer::SourcePosition endLoc = propertyNode->End();
1636 
1637         *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams);
1638         (*returnExpression)->SetRange({startLoc, endLoc});
1639         return false;
1640     }
1641 
1642     lexer_->Rewind(savedPos);
1643     return true;
1644 }
1645 
ParsePostPrimaryExpression(ir::Expression * primaryExpr,lexer::SourcePosition startLoc,bool ignoreCallExpression,bool * isChainExpression)1646 ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc,
1647                                                        bool ignoreCallExpression, bool *isChainExpression)
1648 {
1649     ir::Expression *returnExpression = primaryExpr;
1650 
1651     while (true) {
1652         switch (lexer_->GetToken().Type()) {
1653             case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: {
1654                 *isChainExpression = true;
1655                 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat ?.
1656                 returnExpression = ParseOptionalChain(returnExpression);
1657                 continue;
1658             }
1659             case lexer::TokenType::PUNCTUATOR_PERIOD: {
1660                 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);  // eat period
1661 
1662                 ir::Expression *property;
1663                 if (program_.TargetApiVersion() > 10 &&
1664                     lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1665                     if (returnExpression->IsSuperExpression()) {
1666                         ThrowSyntaxError("Unexpected private property access in super keyword");
1667                     }
1668                     property = ParsePrivateIdentifier();
1669                 } else {
1670                     bool isPrivate = false;
1671                     lexer::SourcePosition memberStart = lexer_->GetToken().Start();
1672                     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_HASH_MARK) {
1673                         if (!(context_.Status() & ParserStatus::IN_CLASS_BODY)) {
1674                             ThrowSyntaxError("Private identifiers are not allowed outside class bodies.");
1675                         }
1676                         isPrivate = true;
1677                         lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
1678                     }
1679 
1680                     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
1681                         ThrowSyntaxError("Expected an identifier");
1682                     }
1683                     auto *identNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1684                     identNode->SetRange(lexer_->GetToken().Loc());
1685                     lexer_->NextToken();
1686 
1687                     if (isPrivate) {
1688                         property = AllocNode<ir::TSPrivateIdentifier>(identNode, nullptr, nullptr);
1689                         property->SetRange({memberStart, identNode->End()});
1690                     } else {
1691                         property = identNode;
1692                     }
1693                 }
1694                 const lexer::SourcePosition &startPos = returnExpression->Start();
1695                 returnExpression = AllocNode<ir::MemberExpression>(
1696                     returnExpression, property, ir::MemberExpression::MemberExpressionKind::PROPERTY_ACCESS, false,
1697                     false);
1698                 returnExpression->SetRange({startPos, property->End()});
1699                 continue;
1700             }
1701             case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1702                 if (context_.Status() & ParserStatus::IN_DECORATOR) {
1703                     break;
1704                 }
1705 
1706                 lexer_->NextToken();  // eat '['
1707                 ir::Expression *propertyNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA);
1708 
1709                 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
1710                     ThrowSyntaxError("Unexpected token");
1711                 }
1712 
1713                 const lexer::SourcePosition &startPos = returnExpression->Start();
1714                 returnExpression = AllocNode<ir::MemberExpression>(
1715                     returnExpression, propertyNode, ir::MemberExpression::MemberExpressionKind::ELEMENT_ACCESS, true,
1716                     false);
1717                 returnExpression->SetRange({startPos, lexer_->GetToken().End()});
1718                 lexer_->NextToken();
1719                 continue;
1720             }
1721             case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
1722             case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
1723                 bool shouldBreak =
1724                     ParsePotentialTsGenericFunctionCall(&returnExpression, startLoc, ignoreCallExpression);
1725                 if (shouldBreak) {
1726                     break;
1727                 }
1728 
1729                 continue;
1730             }
1731             case lexer::TokenType::PUNCTUATOR_BACK_TICK: {
1732                 ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(true);
1733                 lexer::SourcePosition endLoc = propertyNode->End();
1734 
1735                 returnExpression = AllocNode<ir::TaggedTemplateExpression>(returnExpression, propertyNode, nullptr);
1736                 returnExpression->SetRange({startLoc, endLoc});
1737                 continue;
1738             }
1739             case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: {
1740                 if (!ignoreCallExpression) {
1741                     returnExpression = ParseCallExpression(returnExpression, false);
1742                     continue;
1743                 }
1744                 break;
1745             }
1746             case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
1747                 if (Extension() != ScriptExtension::TS || !returnExpression || lexer_->GetToken().NewLine()) {
1748                     break;
1749                 }
1750 
1751                 returnExpression = AllocNode<ir::TSNonNullExpression>(returnExpression);
1752                 returnExpression->SetRange({startLoc, lexer_->GetToken().End()});
1753                 lexer_->NextToken();
1754                 continue;
1755             }
1756             default: {
1757                 break;
1758             }
1759         }
1760 
1761         break;
1762     }
1763 
1764     return returnExpression;
1765 }
1766 
ValidateUpdateExpression(ir::Expression * returnExpression,bool isChainExpression)1767 void ParserImpl::ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression)
1768 {
1769     if (returnExpression->IsTSAsExpression()) {
1770         ValidateUpdateExpression(returnExpression->AsTSAsExpression()->Expr(), isChainExpression);
1771         return;
1772     }
1773     if (returnExpression->IsTSTypeAssertion()) {
1774         ValidateUpdateExpression(returnExpression->AsTSTypeAssertion()->GetExpression(), isChainExpression);
1775         return;
1776     }
1777 
1778     if ((!returnExpression->IsMemberExpression() && !returnExpression->IsIdentifier() &&
1779          !returnExpression->IsTSNonNullExpression()) ||
1780         isChainExpression) {
1781         ThrowSyntaxError("Invalid left-hand side operator.");
1782     }
1783 
1784     if (returnExpression->IsIdentifier()) {
1785         const util::StringView &returnExpressionStr = returnExpression->AsIdentifier()->Name();
1786 
1787         if (returnExpressionStr.Is("eval")) {
1788             ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid");
1789         }
1790 
1791         if (returnExpressionStr.Is("arguments")) {
1792             ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid");
1793         }
1794     }
1795 }
1796 
ParseMemberExpression(bool ignoreCallExpression,ExpressionParseFlags flags)1797 ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, ExpressionParseFlags flags)
1798 {
1799     bool isAsync = lexer_->GetToken().IsAsyncModifier();
1800     lexer::SourcePosition startLoc = lexer_->GetToken().Start();
1801     ir::Expression *returnExpression = ParsePrimaryExpression(flags);
1802 
1803     if (lexer_->GetToken().NewLine() && returnExpression->IsArrowFunctionExpression()) {
1804         return returnExpression;
1805     }
1806 
1807     if (isAsync && !lexer_->GetToken().NewLine()) {
1808         ir::ArrowFunctionExpression *arrow = ParsePotentialArrowExpression(&returnExpression, startLoc,
1809                                                                            ignoreCallExpression);
1810 
1811         if (arrow) {
1812             return arrow;
1813         }
1814     }
1815 
1816     bool isChainExpression = false;
1817     returnExpression = ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression);
1818 
1819     if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) {
1820         lexer::SourcePosition start = returnExpression->Start();
1821 
1822         ValidateUpdateExpression(returnExpression, isChainExpression);
1823 
1824         returnExpression = AllocNode<ir::UpdateExpression>(returnExpression, lexer_->GetToken().Type(), false);
1825 
1826         returnExpression->SetRange({start, lexer_->GetToken().End()});
1827         lexer_->NextToken();
1828     }
1829 
1830     if (isChainExpression) {
1831         lexer::SourcePosition endLoc = returnExpression->End();
1832         returnExpression = AllocNode<ir::ChainExpression>(returnExpression);
1833         returnExpression->SetRange({startLoc, endLoc});
1834     }
1835 
1836     return returnExpression;
1837 }
1838 
ParsePotentialTsFunctionParameter(ExpressionParseFlags flags,ir::Expression * returnNode,bool isDeclare)1839 void ParserImpl::ParsePotentialTsFunctionParameter(ExpressionParseFlags flags, ir::Expression *returnNode,
1840                                                    bool isDeclare)
1841 {
1842     if (Extension() != ScriptExtension::TS || !(context_.Status() & ParserStatus::FUNCTION_PARAM)) {
1843         return;
1844     }
1845 
1846     bool isOptional = false;
1847 
1848     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) {
1849         if (flags & ExpressionParseFlags::IN_REST) {
1850             ThrowSyntaxError("A rest parameter cannot be optional");
1851         }
1852 
1853         ASSERT(returnNode->IsIdentifier() || returnNode->IsObjectPattern() || returnNode->IsArrayPattern());
1854         if (returnNode->IsIdentifier()) {
1855             returnNode->AsIdentifier()->SetOptional(true);
1856         } else if (returnNode->IsObjectPattern()) {
1857             returnNode->AsObjectPattern()->SetOptional(true);
1858         } else if (returnNode->IsArrayPattern()) {
1859             returnNode->AsArrayPattern()->SetOptional(true);
1860         }
1861 
1862         isOptional = true;
1863         lexer_->NextToken();  // eat '?'
1864     }
1865 
1866     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) {
1867         lexer_->NextToken();  // eat ':'
1868         TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR;
1869         returnNode->SetTsTypeAnnotation(ParseTsTypeAnnotation(&options));
1870     }
1871 
1872     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1873         return;
1874     }
1875 
1876     if (flags & ExpressionParseFlags::IN_REST) {
1877         ThrowSyntaxError("A rest parameter cannot have an initializer");
1878     }
1879 
1880     if (returnNode->IsIdentifier() && isOptional) {
1881         ThrowSyntaxError("Parameter cannot have question mark and initializer");
1882     }
1883 }
1884 
ParsePatternElement(ExpressionParseFlags flags,bool allowDefault,bool isDeclare)1885 ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault, bool isDeclare)
1886 {
1887     ir::Expression *returnNode = nullptr;
1888 
1889     switch (lexer_->GetToken().Type()) {
1890         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
1891             returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN);
1892             break;
1893         }
1894         case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: {
1895             if (flags & ExpressionParseFlags::IN_REST) {
1896                 ThrowSyntaxError("Unexpected token");
1897             }
1898 
1899             returnNode = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
1900             break;
1901         }
1902         case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: {
1903             returnNode =
1904                 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN);
1905             break;
1906         }
1907         case lexer::TokenType::LITERAL_IDENT: {
1908             returnNode = AllocNode<ir::Identifier>(lexer_->GetToken().Ident());
1909             returnNode->AsIdentifier()->SetReference();
1910             returnNode->SetRange(lexer_->GetToken().Loc());
1911             lexer_->NextToken();
1912             break;
1913         }
1914         default: {
1915             ThrowSyntaxError("Unexpected token, expected an identifier.");
1916         }
1917     }
1918 
1919     ParsePotentialTsFunctionParameter(flags, returnNode, isDeclare);
1920 
1921     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
1922         return returnNode;
1923     }
1924 
1925     if (flags & ExpressionParseFlags::IN_REST) {
1926         ThrowSyntaxError("Unexpected token, expected ')'");
1927     }
1928 
1929     if (!allowDefault) {
1930         ThrowSyntaxError("Invalid destructuring assignment target");
1931     }
1932 
1933     lexer_->NextToken();
1934 
1935     if ((context_.Status() & ParserStatus::GENERATOR_FUNCTION) &&
1936         lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD) {
1937         ThrowSyntaxError("Yield is not allowed in generator parameters");
1938     }
1939 
1940     ir::Expression *rightNode = ParseExpression();
1941 
1942     auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
1943         ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
1944     assignmentExpression->SetRange({returnNode->Start(), rightNode->End()});
1945 
1946     return assignmentExpression;
1947 }
1948 
CheckPropertyKeyAsycModifier(ParserStatus * methodStatus)1949 void ParserImpl::CheckPropertyKeyAsycModifier(ParserStatus *methodStatus)
1950 {
1951     const auto asyncPos = lexer_->Save();
1952     lexer_->NextToken();
1953 
1954     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS &&
1955         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON &&
1956         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
1957         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
1958         if (lexer_->GetToken().NewLine()) {
1959             ThrowSyntaxError(
1960                 "Async methods cannot have a line terminator between "
1961                 "'async' and the property name");
1962         }
1963 
1964         *methodStatus |= ParserStatus::ASYNC_FUNCTION;
1965     } else {
1966         lexer_->Rewind(asyncPos);
1967     }
1968 }
1969 
IsAccessorDelimiter(char32_t cp)1970 static bool IsAccessorDelimiter(char32_t cp)
1971 {
1972     switch (cp) {
1973         case LEX_CHAR_LEFT_PAREN:
1974         case LEX_CHAR_COLON:
1975         case LEX_CHAR_COMMA:
1976         case LEX_CHAR_RIGHT_BRACE: {
1977             return true;
1978         }
1979         default: {
1980             return false;
1981         }
1982     }
1983 }
1984 
IsShorthandDelimiter(char32_t cp)1985 static bool IsShorthandDelimiter(char32_t cp)
1986 {
1987     switch (cp) {
1988         case LEX_CHAR_EQUALS:
1989         case LEX_CHAR_COMMA:
1990         case LEX_CHAR_RIGHT_BRACE: {
1991             return true;
1992         }
1993         default: {
1994             return false;
1995         }
1996     }
1997 }
1998 
ValidateAccessor(ExpressionParseFlags flags,lexer::TokenFlags currentTokenFlags)1999 void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags)
2000 {
2001     if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
2002         ThrowSyntaxError("Unexpected token");
2003     }
2004 
2005     if (currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) {
2006         ThrowSyntaxError("Keyword must not contain escaped characters");
2007     }
2008 }
2009 
ParseShorthandProperty(const lexer::LexerPosition * startPos)2010 ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos)
2011 {
2012     char32_t nextCp = lexer_->Lookahead();
2013     lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
2014 
2015     /* Rewind the lexer to the beginning of the ident to repase as common
2016      * identifier */
2017     lexer_->Rewind(*startPos);
2018     lexer_->NextToken();
2019     lexer::SourcePosition start = lexer_->GetToken().Start();
2020 
2021     if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) {
2022         ThrowSyntaxError("Expected an identifier");
2023     }
2024 
2025     if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_PRIVATE &&
2026         lexer_->GetToken().KeywordType() <= lexer::TokenType::KEYW_DECLARE) {
2027         ThrowSyntaxError(" Unexpected reserved word", lexer_->GetToken().Start());
2028     }
2029 
2030     const util::StringView &ident = lexer_->GetToken().Ident();
2031 
2032     auto *key = AllocNode<ir::Identifier>(ident);
2033     key->SetRange(lexer_->GetToken().Loc());
2034 
2035     ir::Expression *value = AllocNode<ir::Identifier>(ident);
2036     value->AsIdentifier()->SetReference();
2037     value->SetRange(lexer_->GetToken().Loc());
2038 
2039     lexer::SourcePosition end;
2040 
2041     if (nextCp == LEX_CHAR_EQUALS) {
2042         if (keywordType == lexer::TokenType::KEYW_EVAL) {
2043             ThrowSyntaxError("eval can't be defined or assigned to in strict mode code");
2044         }
2045 
2046         lexer_->NextToken();  // substitution
2047         lexer_->NextToken();  // eat substitution
2048 
2049         ir::Expression *rightNode = ParseExpression();
2050 
2051         auto *assignmentExpression = AllocNode<ir::AssignmentExpression>(
2052             ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION);
2053         assignmentExpression->SetRange({value->Start(), rightNode->End()});
2054         end = rightNode->End();
2055         value = assignmentExpression;
2056     } else {
2057         end = lexer_->GetToken().End();
2058         lexer_->NextToken();
2059     }
2060 
2061     auto *returnProperty = AllocNode<ir::Property>(key, value);
2062     returnProperty->SetRange({start, end});
2063 
2064     return returnProperty;
2065 }
2066 
ParsePropertyModifiers(ExpressionParseFlags flags,ir::PropertyKind * propertyKind,ParserStatus * methodStatus)2067 bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::PropertyKind *propertyKind,
2068                                         ParserStatus *methodStatus)
2069 {
2070     if (lexer_->GetToken().IsAsyncModifier()) {
2071         CheckPropertyKeyAsycModifier(methodStatus);
2072     }
2073 
2074     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2075         if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
2076             ThrowSyntaxError("Unexpected token");
2077         }
2078 
2079         lexer_->NextToken();
2080         *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
2081     }
2082 
2083     lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags();
2084     char32_t nextCp = lexer_->Lookahead();
2085     lexer::TokenType keywordType = lexer_->GetToken().KeywordType();
2086     // Parse getter property
2087     if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) {
2088         ValidateAccessor(flags, currentTokenFlags);
2089 
2090         *propertyKind = ir::PropertyKind::GET;
2091         lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2092 
2093         return false;
2094     }
2095 
2096     // Parse setter property
2097     if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) {
2098         ValidateAccessor(flags, currentTokenFlags);
2099 
2100         *propertyKind = ir::PropertyKind::SET;
2101         lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2102 
2103         return false;
2104     }
2105 
2106     // Parse shorthand property or assignment pattern
2107     return (IsShorthandDelimiter(nextCp) && !(*methodStatus & ParserStatus::ASYNC_FUNCTION));
2108 }
2109 
ParseGeneratorPropertyModifier(ExpressionParseFlags flags,ParserStatus * methodStatus)2110 void ParserImpl::ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus)
2111 {
2112     if (flags & ExpressionParseFlags::MUST_BE_PATTERN) {
2113         ThrowSyntaxError("Unexpected token");
2114     }
2115 
2116     lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2117     *methodStatus |= ParserStatus::GENERATOR_FUNCTION;
2118 }
2119 
ParsePropertyKey(ExpressionParseFlags flags)2120 ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags)
2121 {
2122     ir::Expression *key = nullptr;
2123 
2124     switch (lexer_->GetToken().Type()) {
2125         case lexer::TokenType::LITERAL_IDENT: {
2126             const util::StringView &ident = lexer_->GetToken().Ident();
2127             key = AllocNode<ir::Identifier>(ident);
2128             key->SetRange(lexer_->GetToken().Loc());
2129             break;
2130         }
2131         case lexer::TokenType::LITERAL_STRING: {
2132             const util::StringView &string = lexer_->GetToken().String();
2133             key = AllocNode<ir::StringLiteral>(string);
2134             key->SetRange(lexer_->GetToken().Loc());
2135             break;
2136         }
2137         case lexer::TokenType::LITERAL_NUMBER: {
2138             if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) {
2139                 key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt());
2140             } else {
2141                 key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String());
2142             }
2143 
2144             key->SetRange(lexer_->GetToken().Loc());
2145             break;
2146         }
2147         case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: {
2148             lexer_->NextToken();  // eat left square bracket
2149 
2150             key = ParseExpression(flags | ExpressionParseFlags::ACCEPT_COMMA);
2151 
2152             if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) {
2153                 ThrowSyntaxError("Unexpected token, expected ']'");
2154             }
2155             break;
2156         }
2157         default: {
2158             ThrowSyntaxError("Unexpected token in property key");
2159         }
2160     }
2161 
2162     lexer_->NextToken();
2163     return key;
2164 }
2165 
ParsePropertyValue(const ir::PropertyKind * propertyKind,const ParserStatus * methodStatus,ExpressionParseFlags flags)2166 ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyKind, const ParserStatus *methodStatus,
2167                                                ExpressionParseFlags flags)
2168 {
2169     bool isMethod = *methodStatus & ParserStatus::FUNCTION;
2170     bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
2171 
2172     if (!isMethod && !ir::Property::IsAccessorKind(*propertyKind)) {
2173         // If the actual property is not getter/setter nor method, the following
2174         // token must be ':'
2175         if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) {
2176             ThrowSyntaxError("Unexpected token, expected ':'");
2177         }
2178 
2179         lexer_->NextToken();  // eat colon
2180 
2181         if (!inPattern) {
2182             return ParseExpression(flags);
2183         }
2184 
2185         return ParsePatternElement();
2186     }
2187 
2188     if (inPattern) {
2189         ThrowSyntaxError("Object pattern can't contain methods");
2190     }
2191 
2192     ir::ScriptFunction *methodDefinitonNode =
2193         ParseFunction(*methodStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER);
2194     lexer_->NextToken();
2195     methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD);
2196 
2197     size_t paramsSize = methodDefinitonNode->Params().size();
2198 
2199     auto *value = AllocNode<ir::FunctionExpression>(methodDefinitonNode);
2200     value->SetRange(methodDefinitonNode->Range());
2201 
2202     if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) {
2203         ThrowSyntaxError("Setter must have exactly one formal parameter");
2204     }
2205 
2206     if (*propertyKind == ir::PropertyKind::GET && paramsSize != 0) {
2207         ThrowSyntaxError("Getter must not have formal parameters");
2208     }
2209 
2210     return value;
2211 }
2212 
ParsePropertyDefinition(ExpressionParseFlags flags)2213 ir::Expression *ParserImpl::ParsePropertyDefinition(ExpressionParseFlags flags)
2214 {
2215     ir::PropertyKind propertyKind = ir::PropertyKind::INIT;
2216     ParserStatus methodStatus = ParserStatus::NO_OPTS;
2217 
2218     const auto startPos = lexer_->Save();
2219     lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT);
2220     lexer::SourcePosition start = lexer_->GetToken().Start();
2221 
2222     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2223         return ParseSpreadElement(flags);
2224     }
2225 
2226     if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) {
2227         if (ParsePropertyModifiers(flags, &propertyKind, &methodStatus)) {
2228             return ParseShorthandProperty(&startPos);
2229         }
2230     } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) {
2231         ParseGeneratorPropertyModifier(flags, &methodStatus);
2232     }
2233 
2234     bool isComputed = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET;
2235     ir::Expression *key = ParsePropertyKey(flags);
2236 
2237     // Parse method property
2238     if ((lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS ||
2239          lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) &&
2240         !ir::Property::IsAccessorKind(propertyKind)) {
2241         methodStatus |= ParserStatus::FUNCTION | ParserStatus::ALLOW_SUPER;
2242         propertyKind = ir::PropertyKind::INIT;
2243     } else if (methodStatus & (ParserStatus::GENERATOR_FUNCTION | ParserStatus::ASYNC_FUNCTION)) {
2244         ThrowSyntaxError("Unexpected identifier");
2245     }
2246 
2247     ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags);
2248     lexer::SourcePosition end = value->End();
2249 
2250     ASSERT(key);
2251     ASSERT(value);
2252 
2253     auto *returnProperty =
2254         AllocNode<ir::Property>(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed);
2255     returnProperty->SetRange({start, end});
2256 
2257     return returnProperty;
2258 }
2259 
ParsePropertyEnd()2260 bool ParserImpl::ParsePropertyEnd()
2261 {
2262     // Property definiton must end with ',' or '}' otherwise we throw SyntaxError
2263     if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA &&
2264         lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2265         ThrowSyntaxError("Unexpected token, expected ',' or '}'");
2266     }
2267 
2268     if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA &&
2269         lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE) {
2270         lexer_->NextToken();
2271         return true;
2272     }
2273 
2274     return false;
2275 }
2276 
ParseObjectExpression(ExpressionParseFlags flags)2277 ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags flags)
2278 {
2279     ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE);
2280     lexer::SourcePosition start = lexer_->GetToken().Start();
2281     ArenaVector<ir::Expression *> properties(Allocator()->Adapter());
2282     bool trailingComma = false;
2283     bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN);
2284 
2285     if (lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE) {
2286         lexer_->NextToken();
2287     }
2288 
2289     while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) {
2290         ir::Expression *property = ParsePropertyDefinition(flags | ExpressionParseFlags::POTENTIALLY_IN_PATTERN);
2291         properties.push_back(property);
2292         trailingComma = ParsePropertyEnd();
2293     }
2294 
2295     auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION;
2296     auto *objectExpression = AllocNode<ir::ObjectExpression>(nodeType, std::move(properties), trailingComma);
2297     objectExpression->SetRange({start, lexer_->GetToken().End()});
2298     lexer_->NextToken();
2299 
2300     if (inPattern) {
2301         objectExpression->SetDeclaration();
2302     }
2303 
2304     if (Extension() == ScriptExtension::TS && (flags & ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN) &&
2305         lexer::Token::IsTsParamToken(lexer_->GetToken().Type(), lexer_->Lookahead())) {
2306         context_.Status() |= ParserStatus::FUNCTION_PARAM;
2307         ParsePotentialTsFunctionParameter(ExpressionParseFlags::NO_OPTS, objectExpression);
2308     }
2309 
2310     if (!(flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN)) {
2311         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION &&
2312             !objectExpression->ConvertibleToObjectPattern()) {
2313             ThrowSyntaxError("Invalid left-hand side in array destructuring pattern", objectExpression->Start());
2314         } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) {
2315             ir::ValidationInfo info = objectExpression->ValidateExpression();
2316             if (info.Fail()) {
2317                 ThrowSyntaxError(info.msg.Utf8(), info.pos);
2318             }
2319         }
2320     }
2321 
2322     return objectExpression;
2323 }
2324 
ParseSequenceExpression(ir::Expression * startExpr,bool acceptRest,bool acceptTsParam,bool acceptPattern)2325 ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *startExpr, bool acceptRest,
2326                                                             bool acceptTsParam, bool acceptPattern)
2327 {
2328     lexer::SourcePosition start = startExpr->Start();
2329 
2330     ArenaVector<ir::Expression *> sequence(Allocator()->Adapter());
2331     sequence.push_back(startExpr);
2332 
2333     while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) {
2334         lexer_->NextToken();
2335 
2336         if (acceptRest && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) {
2337             ir::SpreadElement *expr = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN);
2338             sequence.push_back(expr);
2339             break;
2340         }
2341 
2342         if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS && lexer_->CheckArrow()) {
2343             break;
2344         }
2345 
2346         ExpressionParseFlags flags = acceptTsParam ? ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN
2347                                                    : ExpressionParseFlags::NO_OPTS;
2348 
2349         sequence.push_back(ParseExpression(acceptPattern ? (ExpressionParseFlags::POTENTIALLY_IN_PATTERN | flags)
2350                                                          : flags));
2351     }
2352 
2353     lexer::SourcePosition end = sequence.back()->End();
2354     auto *sequenceNode = AllocNode<ir::SequenceExpression>(std::move(sequence));
2355     sequenceNode->SetRange({start, end});
2356 
2357     return sequenceNode;
2358 }
2359 
ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)2360 ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags)
2361 {
2362     if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) {
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