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