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