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