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