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