1/** 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "TSparser.h" 17 18#include "parserFlags.h" 19#include "util/helpers.h" 20#include "varbinder/privateBinding.h" 21#include "varbinder/scope.h" 22#include "varbinder/tsBinding.h" 23#include "lexer/TSLexer.h" 24#include "ir/base/spreadElement.h" 25#include "ir/base/decorator.h" 26#include "ir/base/classElement.h" 27#include "ir/base/classDefinition.h" 28#include "ir/base/methodDefinition.h" 29#include "ir/base/scriptFunction.h" 30#include "ir/module/importDefaultSpecifier.h" 31#include "ir/module/exportDefaultDeclaration.h" 32#include "ir/module/exportAllDeclaration.h" 33#include "ir/module/exportNamedDeclaration.h" 34#include "ir/module/importDeclaration.h" 35#include "ir/expressions/memberExpression.h" 36#include "ir/expressions/sequenceExpression.h" 37#include "ir/expressions/templateLiteral.h" 38#include "ir/expressions/taggedTemplateExpression.h" 39#include "ir/expressions/callExpression.h" 40#include "ir/expressions/functionExpression.h" 41#include "ir/expressions/arrowFunctionExpression.h" 42#include "ir/expressions/yieldExpression.h" 43#include "ir/expressions/assignmentExpression.h" 44#include "ir/expressions/identifier.h" 45#include "ir/expressions/objectExpression.h" 46#include "ir/expressions/arrayExpression.h" 47#include "ir/expressions/literals/bigIntLiteral.h" 48#include "ir/expressions/literals/booleanLiteral.h" 49#include "ir/expressions/literals/nullLiteral.h" 50#include "ir/expressions/literals/numberLiteral.h" 51#include "ir/expressions/literals/stringLiteral.h" 52#include "ir/statements/emptyStatement.h" 53#include "ir/statements/blockStatement.h" 54#include "ir/statements/ifStatement.h" 55#include "ir/statements/doWhileStatement.h" 56#include "ir/statements/whileStatement.h" 57#include "ir/statements/tryStatement.h" 58#include "ir/statements/breakStatement.h" 59#include "ir/statements/continueStatement.h" 60#include "ir/statements/throwStatement.h" 61#include "ir/statements/switchStatement.h" 62#include "ir/statements/returnStatement.h" 63#include "ir/statements/debuggerStatement.h" 64#include "ir/statements/classDeclaration.h" 65#include "ir/statements/labelledStatement.h" 66#include "ir/statements/variableDeclarator.h" 67#include "ir/statements/functionDeclaration.h" 68#include "ir/ts/tsLiteralType.h" 69#include "ir/ts/tsMappedType.h" 70#include "ir/ts/tsImportType.h" 71#include "ir/ts/tsThisType.h" 72#include "ir/ts/tsConditionalType.h" 73#include "ir/ts/tsTypeOperator.h" 74#include "ir/ts/tsInferType.h" 75#include "ir/ts/tsTupleType.h" 76#include "ir/ts/tsNamedTupleMember.h" 77#include "ir/ts/tsQualifiedName.h" 78#include "ir/ts/tsIndexedAccessType.h" 79#include "ir/ts/tsTypeQuery.h" 80#include "ir/ts/tsTypeReference.h" 81#include "ir/ts/tsTypePredicate.h" 82#include "ir/ts/tsTypeLiteral.h" 83#include "ir/ts/tsArrayType.h" 84#include "ir/ts/tsUnionType.h" 85#include "ir/ts/tsIntersectionType.h" 86#include "ir/ts/tsAnyKeyword.h" 87#include "ir/ts/tsUndefinedKeyword.h" 88#include "ir/ts/tsVoidKeyword.h" 89#include "ir/ts/tsNumberKeyword.h" 90#include "ir/ts/tsStringKeyword.h" 91#include "ir/ts/tsBooleanKeyword.h" 92#include "ir/ts/tsBigintKeyword.h" 93#include "ir/ts/tsUnknownKeyword.h" 94#include "ir/ts/tsNullKeyword.h" 95#include "ir/ts/tsNeverKeyword.h" 96#include "ir/ts/tsObjectKeyword.h" 97#include "ir/ts/tsFunctionType.h" 98#include "ir/ts/tsConstructorType.h" 99#include "ir/ts/tsParenthesizedType.h" 100#include "ir/ts/tsTypeAssertion.h" 101#include "ir/ts/tsAsExpression.h" 102#include "ir/ts/tsNonNullExpression.h" 103#include "ir/ts/tsEnumDeclaration.h" 104#include "ir/ts/tsInterfaceDeclaration.h" 105#include "ir/ts/tsTypeAliasDeclaration.h" 106#include "ir/ts/tsModuleDeclaration.h" 107#include "ir/ts/tsTypeParameterInstantiation.h" 108#include "ir/ts/tsInterfaceHeritage.h" 109#include "ir/base/tsSignatureDeclaration.h" 110#include "ir/base/tsIndexSignature.h" 111#include "ir/base/tsMethodSignature.h" 112#include "ir/base/tsPropertySignature.h" 113#include "ir/ts/tsParameterProperty.h" 114#include "ir/ts/tsClassImplements.h" 115#include "ir/ts/tsImportEqualsDeclaration.h" 116#include "ir/ts/tsExternalModuleReference.h" 117 118namespace ark::es2panda::parser { 119ir::Expression *TSParser::ParsePotentialAsExpression(ir::Expression *expr) 120{ 121 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_AS) { 122 return nullptr; 123 } 124 125 Lexer()->NextToken(); // eat 'as' 126 TypeAnnotationParsingOptions options = 127 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ALLOW_CONST; 128 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 129 130 bool isConst = false; 131 if (typeAnnotation->IsTSTypeReference() && typeAnnotation->AsTSTypeReference()->TypeName()->IsIdentifier()) { 132 const util::StringView &refName = typeAnnotation->AsTSTypeReference()->TypeName()->AsIdentifier()->Name(); 133 if (refName.Is("const")) { 134 isConst = true; 135 } 136 } 137 138 lexer::SourcePosition startLoc = expr->Start(); 139 auto *asExpr = AllocNode<ir::TSAsExpression>(expr, typeAnnotation, isConst); 140 asExpr->SetRange({startLoc, Lexer()->GetToken().End()}); 141 142 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) { 143 return ParsePotentialAsExpression(asExpr); 144 } 145 146 return asExpr; 147} 148 149ir::AnnotatedExpression *TSParser::ParsePatternElementGetReturnNode(ExpressionParseFlags &flags, bool &isOptional) 150{ 151 switch (Lexer()->GetToken().Type()) { 152 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 153 ir::AnnotatedExpression *returnNode = ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN); 154 isOptional = returnNode->AsArrayPattern()->IsOptional(); 155 return returnNode; 156 } 157 case lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD: { 158 if ((flags & ExpressionParseFlags::IN_REST) != 0) { 159 ThrowSyntaxError("Unexpected token"); 160 } 161 162 return ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN); 163 } 164 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 165 ir::AnnotatedExpression *returnNode = 166 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN); 167 isOptional = returnNode->AsObjectPattern()->IsOptional(); 168 return returnNode; 169 } 170 case lexer::TokenType::LITERAL_IDENT: { 171 ir::AnnotatedExpression *returnNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 172 returnNode->AsIdentifier()->SetReference(); 173 174 if (returnNode->AsIdentifier()->Decorators().empty()) { 175 returnNode->SetRange(Lexer()->GetToken().Loc()); 176 } else { 177 returnNode->SetRange( 178 {returnNode->AsIdentifier()->Decorators().front()->Start(), Lexer()->GetToken().End()}); 179 } 180 181 Lexer()->NextToken(); 182 183 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 184 isOptional = true; 185 186 if ((flags & ExpressionParseFlags::IN_REST) != 0) { 187 ThrowSyntaxError("A rest parameter cannot be optional"); 188 } 189 190 returnNode->AsIdentifier()->SetOptional(true); 191 Lexer()->NextToken(); 192 } 193 194 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 195 Lexer()->NextToken(); // eat ':' 196 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 197 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); 198 } 199 return returnNode; 200 } 201 default: { 202 ThrowSyntaxError("Unexpected token, expected an identifier."); 203 } 204 } 205} 206// NOLINTNEXTLINE(google-default-arguments) 207ir::Expression *TSParser::ParsePatternElement(ExpressionParseFlags flags, bool allowDefault) 208{ 209 bool isOptional = false; 210 ir::AnnotatedExpression *returnNode = ParsePatternElementGetReturnNode(flags, isOptional); 211 212 if ((returnNode->IsObjectPattern() || returnNode->IsArrayPattern()) && !InAmbientContext() && 213 ((GetContext().Status() & ParserStatus::FUNCTION) != 0) && isOptional) { 214 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature."); 215 } 216 217 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 218 return returnNode; 219 } 220 221 if ((flags & ExpressionParseFlags::IN_REST) != 0) { 222 ThrowSyntaxError("A rest parameter cannot have an initializer."); 223 } 224 225 if (!allowDefault) { 226 ThrowSyntaxError("Invalid destructuring assignment target"); 227 } 228 229 if (isOptional) { 230 ThrowSyntaxError("Parameter cannot have question mark and initializer"); 231 } 232 233 Lexer()->NextToken(); 234 235 if (((GetContext().Status() & ParserStatus::GENERATOR_FUNCTION) != 0) && 236 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD) { 237 ThrowSyntaxError("Yield is not allowed in generator parameters"); 238 } 239 240 ir::Expression *rightNode = ParseExpression(); 241 242 auto *assignmentExpression = AllocNode<ir::AssignmentExpression>( 243 ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); 244 assignmentExpression->SetRange({returnNode->Start(), rightNode->End()}); 245 246 return assignmentExpression; 247} 248 249ir::TSParameterProperty *TSParser::CreateParameterProperty(ir::Expression *parameter, ir::ModifierFlags modifiers) 250{ 251 auto accessibilityOption = ir::AccessibilityOption::NO_OPTS; 252 bool readonly = false; 253 bool isStatic = false; 254 bool isExport = false; 255 256 if ((modifiers & ir::ModifierFlags::PRIVATE) != 0) { 257 accessibilityOption = ir::AccessibilityOption::PRIVATE; 258 } else if ((modifiers & ir::ModifierFlags::PUBLIC) != 0) { 259 accessibilityOption = ir::AccessibilityOption::PUBLIC; 260 } else if ((modifiers & ir::ModifierFlags::PROTECTED) != 0) { 261 accessibilityOption = ir::AccessibilityOption::PROTECTED; 262 } 263 264 if ((modifiers & ir::ModifierFlags::READONLY) != 0) { 265 readonly = true; 266 } 267 268 if ((modifiers & ir::ModifierFlags::STATIC) != 0) { 269 isStatic = true; 270 } 271 272 // NOTE(Csaba Repasi): Handle export property of TSParameterProperty 273 274 return AllocNode<ir::TSParameterProperty>(accessibilityOption, parameter, readonly, isStatic, isExport); 275} 276 277ir::Expression *TSParser::ParseFunctionParameter() 278{ 279 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS) { 280 Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); 281 } 282 283 lexer::SourcePosition parameterStart = Lexer()->GetToken().Start(); 284 ir::ModifierFlags modifiers = ParseModifiers(); 285 // NOTE(Csaba Repasi): throw error if using strick mode reserved keyword here 286 if (((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) == 0) && modifiers != ir::ModifierFlags::NONE) { 287 ThrowSyntaxError("A parameter property is only allowed in a constructor implementation.", parameterStart); 288 } 289 290 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 291 CheckRestrictedBinding(); 292 } 293 294 ir::Expression *functionParameter = ParsePatternElement(ExpressionParseFlags::NO_OPTS, true); 295 296 if (modifiers != ir::ModifierFlags::NONE && functionParameter->IsRestElement()) { 297 ThrowSyntaxError("A parameter property cannot be declared using a rest parameter.", parameterStart); 298 } 299 300 if (modifiers != ir::ModifierFlags::NONE && 301 (functionParameter->IsArrayPattern() || functionParameter->IsObjectPattern() || 302 (functionParameter->IsAssignmentPattern() && 303 (functionParameter->AsAssignmentPattern()->Left()->IsArrayPattern() || 304 functionParameter->AsAssignmentPattern()->Left()->IsObjectPattern())))) { 305 ThrowSyntaxError("A parameter property may not be declared using a binding pattern.", parameterStart); 306 } 307 308 if (modifiers != ir::ModifierFlags::NONE) { 309 functionParameter = CreateParameterProperty(functionParameter, modifiers); 310 functionParameter->SetRange({parameterStart, functionParameter->AsTSParameterProperty()->Parameter()->End()}); 311 } 312 313 return functionParameter; 314} 315 316ir::Expression *TSParser::ParseModuleReference() 317{ 318 ir::Expression *result = nullptr; 319 320 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_REQUIRE && 321 Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN) { 322 lexer::SourcePosition start = Lexer()->GetToken().Start(); 323 Lexer()->NextToken(); // eat 'require' 324 Lexer()->NextToken(); // eat '(' 325 326 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) { 327 ThrowSyntaxError("String literal expected."); 328 } 329 330 result = AllocNode<ir::StringLiteral>(Lexer()->GetToken().String()); 331 result->SetRange(Lexer()->GetToken().Loc()); 332 Lexer()->NextToken(); 333 334 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 335 ThrowSyntaxError("')' expected."); 336 } 337 338 result = AllocNode<ir::TSExternalModuleReference>(result); 339 result->SetRange({start, Lexer()->GetToken().End()}); 340 Lexer()->NextToken(); // eat ')' 341 } else { 342 result = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 343 result->SetRange(Lexer()->GetToken().Loc()); 344 Lexer()->NextToken(); 345 346 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 347 result = ParseQualifiedReference(result); 348 } 349 } 350 351 return result; 352} 353 354ir::TSTypeReference *TSParser::ParseConstExpression() 355{ 356 auto *identRef = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 357 identRef->SetReference(); 358 identRef->SetRange(Lexer()->GetToken().Loc()); 359 360 auto *typeReference = AllocNode<ir::TSTypeReference>(identRef, nullptr); 361 typeReference->SetRange(Lexer()->GetToken().Loc()); 362 363 Lexer()->NextToken(); 364 365 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 366 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 367 Lexer()->GetToken().Type() != lexer::TokenType::EOS && 368 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET && 369 ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) == 0)) { 370 ThrowSyntaxError("Unexpected token."); 371 } 372 373 return typeReference; 374} 375 376bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc) 377{ 378 if (returnExpression == nullptr || Lexer()->GetToken().NewLine()) { 379 return true; 380 } 381 382 *returnExpression = AllocNode<ir::TSNonNullExpression>(*returnExpression); 383 (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); 384 Lexer()->NextToken(); 385 return false; 386} 387 388// NOLINTNEXTLINE(google-default-arguments) 389ir::ObjectExpression *TSParser::ParseObjectExpression(ExpressionParseFlags flags) 390{ 391 ir::ObjectExpression *objExpression = ParserImpl::ParseObjectExpression(flags); 392 ParsePotentialOptionalFunctionParameter(objExpression); 393 return objExpression; 394} 395 396// NOLINTNEXTLINE(google-default-arguments) 397ir::ArrayExpression *TSParser::ParseArrayExpression(ExpressionParseFlags flags) 398{ 399 ir::ArrayExpression *arrayExpression = ParserImpl::ParseArrayExpression(flags); 400 ParsePotentialOptionalFunctionParameter(arrayExpression); 401 return arrayExpression; 402} 403class TSParser::ParsePotentialArrowExpressionHelper { 404 friend ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression, 405 const lexer::SourcePosition &startLoc); 406 407private: 408 static ir::ArrowFunctionExpression *CreateCallExpression(TSParser *parser, lexer::Lexer *lexer, 409 ir::Expression **returnExpression, 410 ir::TSTypeParameterDeclaration *typeParamDecl, 411 const lexer::SourcePosition &startLoc) 412 { 413 ir::CallExpression *callExpression = parser->ParseCallExpression(*returnExpression, false); 414 415 ir::TypeNode *returnTypeAnnotation = nullptr; 416 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 417 lexer->NextToken(); // eat ':' 418 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 419 returnTypeAnnotation = parser->ParseTypeAnnotation(&options); 420 } 421 422 if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) { 423 ir::ArrowFunctionExpression *arrowFuncExpr = 424 parser->ParseArrowFunctionExpression(callExpression, typeParamDecl, returnTypeAnnotation, true); 425 arrowFuncExpr->SetStart(startLoc); 426 427 return arrowFuncExpr; 428 } 429 430 if (returnTypeAnnotation != nullptr || typeParamDecl != nullptr) { 431 parser->ThrowSyntaxError("'=>' expected"); 432 } 433 434 *returnExpression = callExpression; 435 return nullptr; 436 } 437}; 438 439ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression, 440 const lexer::SourcePosition &startLoc) 441{ 442 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 443 444 switch (Lexer()->GetToken().Type()) { 445 case lexer::TokenType::KEYW_FUNCTION: { 446 *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); 447 (*returnExpression)->SetStart(startLoc); 448 break; 449 } 450 case lexer::TokenType::LITERAL_IDENT: { 451 ir::Expression *identRef = ParsePrimaryExpression(); 452 ASSERT(identRef->IsIdentifier()); 453 454 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 455 ThrowSyntaxError("Unexpected token, expected '=>'"); 456 } 457 458 ir::ArrowFunctionExpression *arrowFuncExpr = ParseArrowFunctionExpression(identRef, nullptr, nullptr, true); 459 arrowFuncExpr->SetStart(startLoc); 460 461 return arrowFuncExpr; 462 } 463 case lexer::TokenType::PUNCTUATOR_ARROW: { 464 ir::ArrowFunctionExpression *arrowFuncExpr = 465 ParseArrowFunctionExpression(*returnExpression, nullptr, nullptr, true); 466 arrowFuncExpr->SetStart(startLoc); 467 return arrowFuncExpr; 468 } 469 case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 470 const auto savedPos = Lexer()->Save(); 471 472 auto options = TypeAnnotationParsingOptions::NO_OPTS; 473 typeParamDecl = ParseTypeParameterDeclaration(&options); 474 if (typeParamDecl == nullptr) { 475 Lexer()->Rewind(savedPos); 476 return nullptr; 477 } 478 479 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 480 ThrowSyntaxError("'(' expected"); 481 } 482 483 [[fallthrough]]; 484 } 485 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 486 return ParsePotentialArrowExpressionHelper::CreateCallExpression(this, Lexer(), returnExpression, 487 typeParamDecl, startLoc); 488 } 489 default: { 490 break; 491 } 492 } 493 494 return nullptr; 495} 496 497ir::AnnotatedExpression *TSParser::ParseVariableDeclaratorKey(VariableParsingFlags flags) 498{ 499 ir::AnnotatedExpression *init = ParserImpl::ParseVariableDeclaratorKey(flags); 500 501 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 502 Lexer()->NextToken(); // eat ':' 503 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 504 init->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); 505 } 506 507 return init; 508} 509 510void TSParser::ParseOptionalFunctionParameter(ir::AnnotatedExpression *returnNode, bool isRest) 511{ 512 bool isOptional = false; 513 514 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 515 if (isRest) { 516 ThrowSyntaxError("A rest parameter cannot be optional"); 517 } 518 519 switch (returnNode->Type()) { 520 case ir::AstNodeType::IDENTIFIER: { 521 returnNode->AsIdentifier()->SetOptional(true); 522 break; 523 } 524 case ir::AstNodeType::OBJECT_PATTERN: 525 case ir::AstNodeType::ARRAY_PATTERN: { 526 if (!InAmbientContext() && ((GetContext().Status() & ParserStatus::FUNCTION) != 0)) { 527 ThrowSyntaxError("A binding pattern parameter cannot be optional in an implementation signature."); 528 } 529 530 if (returnNode->IsObjectPattern()) { 531 returnNode->AsObjectPattern()->SetOptional(true); 532 break; 533 } 534 535 returnNode->AsArrayPattern()->SetOptional(true); 536 break; 537 } 538 case ir::AstNodeType::REST_ELEMENT: { 539 returnNode->AsRestElement()->SetOptional(true); 540 break; 541 } 542 default: { 543 UNREACHABLE(); 544 } 545 } 546 547 isOptional = true; 548 Lexer()->NextToken(); // eat '?' 549 } 550 551 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 552 Lexer()->NextToken(); // eat ':' 553 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 554 returnNode->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); 555 } 556 557 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 558 return; 559 } 560 561 if (isRest) { 562 ThrowSyntaxError("A rest parameter cannot have an initializer"); 563 } 564 565 if (returnNode->IsIdentifier() && isOptional) { 566 ThrowSyntaxError("Parameter cannot have question mark and initializer"); 567 } 568} 569 570void TSParser::ValidateArrowFunctionRestParameter(ir::SpreadElement *restElement) 571{ 572 ParseOptionalFunctionParameter(restElement, true); 573 574 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 575 ThrowSyntaxError("')' expected"); 576 } 577} 578 579ir::Expression *TSParser::ParseArrowFunctionRestParameter(lexer::SourcePosition start) 580{ 581 ir::SpreadElement *restElement = ParseSpreadElement(ExpressionParseFlags::MUST_BE_PATTERN); 582 583 restElement->SetGrouped(); 584 restElement->SetStart(start); 585 586 ValidateArrowFunctionRestParameter(restElement); 587 588 Lexer()->NextToken(); 589 590 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 591 ir::TypeNode *returnTypeAnnotation = nullptr; 592 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 593 Lexer()->NextToken(); // eat ':' 594 returnTypeAnnotation = ParseTypeAnnotation(&options); 595 } 596 597 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 598 ThrowSyntaxError("Unexpected token"); 599 } 600 601 return ParseArrowFunctionExpression(restElement, nullptr, returnTypeAnnotation, false); 602} 603 604ir::Expression *TSParser::ParseArrowFunctionNoParameter(lexer::SourcePosition start) 605{ 606 Lexer()->NextToken(); 607 608 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 609 ir::TypeNode *returnTypeAnnotation = nullptr; 610 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 611 Lexer()->NextToken(); // eat ':' 612 returnTypeAnnotation = ParseTypeAnnotation(&options); 613 } 614 615 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 616 ThrowSyntaxError("Unexpected token"); 617 } 618 619 auto *arrowExpr = ParseArrowFunctionExpression(nullptr, nullptr, returnTypeAnnotation, false); 620 arrowExpr->SetStart(start); 621 arrowExpr->AsArrowFunctionExpression()->Function()->SetStart(start); 622 623 return arrowExpr; 624} 625 626// NOLINTNEXTLINE(google-default-arguments) 627ir::Expression *TSParser::ParseCoverParenthesizedExpressionAndArrowParameterList( 628 [[maybe_unused]] ExpressionParseFlags flags) 629{ 630 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 631 lexer::SourcePosition start = Lexer()->GetToken().Start(); 632 Lexer()->NextToken(); 633 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 634 635 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 636 return ParseArrowFunctionRestParameter(start); 637 } 638 639 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 640 return ParseArrowFunctionNoParameter(start); 641 } 642 643 ir::Expression *expr = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA | ExpressionParseFlags::ACCEPT_REST | 644 ExpressionParseFlags::POTENTIALLY_IN_PATTERN); 645 646 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 647 ThrowSyntaxError("Unexpected token, expected ')'"); 648 } 649 650 expr->SetGrouped(); 651 expr->SetRange({start, Lexer()->GetToken().End()}); 652 Lexer()->NextToken(); 653 654 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 655 auto savedPos = Lexer()->Save(); 656 Lexer()->NextToken(); // eat ':' 657 options = TypeAnnotationParsingOptions::NO_OPTS; 658 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options); 659 660 if (returnTypeAnnotation == nullptr) { 661 Lexer()->Rewind(savedPos); 662 return expr; 663 } 664 665 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 666 Lexer()->Rewind(savedPos); 667 return expr; 668 } 669 670 return ParseArrowFunctionExpression(expr, nullptr, returnTypeAnnotation, false); 671 } 672 673 return expr; 674} 675 676} // namespace ark::es2panda::parser