1/** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "TSparser.h" 17 18#include "parser/parserStatusContext.h" 19#include "macros.h" 20#include "parserFlags.h" 21#include "util/helpers.h" 22#include "varbinder/privateBinding.h" 23#include "varbinder/scope.h" 24#include "varbinder/tsBinding.h" 25#include "lexer/TSLexer.h" 26#include "ir/base/spreadElement.h" 27#include "ir/base/decorator.h" 28#include "ir/base/classElement.h" 29#include "ir/base/classDefinition.h" 30#include "ir/base/methodDefinition.h" 31#include "ir/base/scriptFunction.h" 32#include "ir/module/importDefaultSpecifier.h" 33#include "ir/module/exportDefaultDeclaration.h" 34#include "ir/module/exportAllDeclaration.h" 35#include "ir/module/exportNamedDeclaration.h" 36#include "ir/module/importDeclaration.h" 37#include "ir/expressions/memberExpression.h" 38#include "ir/expressions/sequenceExpression.h" 39#include "ir/expressions/templateLiteral.h" 40#include "ir/expressions/taggedTemplateExpression.h" 41#include "ir/expressions/callExpression.h" 42#include "ir/expressions/functionExpression.h" 43#include "ir/expressions/arrowFunctionExpression.h" 44#include "ir/expressions/yieldExpression.h" 45#include "ir/expressions/assignmentExpression.h" 46#include "ir/expressions/identifier.h" 47#include "ir/expressions/objectExpression.h" 48#include "ir/expressions/arrayExpression.h" 49#include "ir/expressions/literals/bigIntLiteral.h" 50#include "ir/expressions/literals/booleanLiteral.h" 51#include "ir/expressions/literals/nullLiteral.h" 52#include "ir/expressions/literals/numberLiteral.h" 53#include "ir/expressions/literals/stringLiteral.h" 54#include "ir/statements/emptyStatement.h" 55#include "ir/statements/blockStatement.h" 56#include "ir/statements/ifStatement.h" 57#include "ir/statements/doWhileStatement.h" 58#include "ir/statements/whileStatement.h" 59#include "ir/statements/tryStatement.h" 60#include "ir/statements/breakStatement.h" 61#include "ir/statements/continueStatement.h" 62#include "ir/statements/throwStatement.h" 63#include "ir/statements/switchStatement.h" 64#include "ir/statements/returnStatement.h" 65#include "ir/statements/debuggerStatement.h" 66#include "ir/statements/classDeclaration.h" 67#include "ir/statements/labelledStatement.h" 68#include "ir/statements/variableDeclarator.h" 69#include "ir/statements/functionDeclaration.h" 70#include "ir/ts/tsLiteralType.h" 71#include "ir/ts/tsMappedType.h" 72#include "ir/ts/tsImportType.h" 73#include "ir/ts/tsThisType.h" 74#include "ir/ts/tsConditionalType.h" 75#include "ir/ts/tsTypeOperator.h" 76#include "ir/ts/tsInferType.h" 77#include "ir/ts/tsTupleType.h" 78#include "ir/ts/tsNamedTupleMember.h" 79#include "ir/ts/tsQualifiedName.h" 80#include "ir/ts/tsIndexedAccessType.h" 81#include "ir/ts/tsTypeQuery.h" 82#include "ir/ts/tsTypeReference.h" 83#include "ir/ts/tsTypePredicate.h" 84#include "ir/ts/tsTypeLiteral.h" 85#include "ir/ts/tsArrayType.h" 86#include "ir/ts/tsUnionType.h" 87#include "ir/ts/tsIntersectionType.h" 88#include "ir/ts/tsAnyKeyword.h" 89#include "ir/ts/tsUndefinedKeyword.h" 90#include "ir/ts/tsVoidKeyword.h" 91#include "ir/ts/tsNumberKeyword.h" 92#include "ir/ts/tsStringKeyword.h" 93#include "ir/ts/tsBooleanKeyword.h" 94#include "ir/ts/tsBigintKeyword.h" 95#include "ir/ts/tsUnknownKeyword.h" 96#include "ir/ts/tsNullKeyword.h" 97#include "ir/ts/tsNeverKeyword.h" 98#include "ir/ts/tsObjectKeyword.h" 99#include "ir/ts/tsFunctionType.h" 100#include "ir/ts/tsConstructorType.h" 101#include "ir/ts/tsParenthesizedType.h" 102#include "ir/ts/tsTypeAssertion.h" 103#include "ir/ts/tsAsExpression.h" 104#include "ir/ts/tsNonNullExpression.h" 105#include "ir/ts/tsEnumDeclaration.h" 106#include "ir/ts/tsInterfaceDeclaration.h" 107#include "ir/ts/tsTypeAliasDeclaration.h" 108#include "ir/ts/tsModuleDeclaration.h" 109#include "ir/ts/tsTypeParameterInstantiation.h" 110#include "ir/ts/tsInterfaceHeritage.h" 111#include "ir/base/tsSignatureDeclaration.h" 112#include "ir/base/tsIndexSignature.h" 113#include "ir/base/tsMethodSignature.h" 114#include "ir/base/tsPropertySignature.h" 115#include "ir/ts/tsParameterProperty.h" 116#include "ir/ts/tsClassImplements.h" 117#include "ir/ts/tsImportEqualsDeclaration.h" 118#include "ir/ts/tsExternalModuleReference.h" 119 120namespace ark::es2panda::parser { 121std::unique_ptr<lexer::Lexer> TSParser::InitLexer(const SourceFile &sourceFile) 122{ 123 GetProgram()->SetSource(sourceFile); 124 auto lexer = std::make_unique<lexer::TSLexer>(&GetContext()); 125 SetLexer(lexer.get()); 126 return lexer; 127} 128 129ir::Decorator *TSParser::ParseDecorator() 130{ 131 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT); 132 133 lexer::SourcePosition start = Lexer()->GetToken().Start(); 134 Lexer()->NextToken(); // eat '@' 135 136 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 137 ThrowSyntaxError("Identifier expected"); 138 } 139 140 ir::Expression *expr = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 141 expr->SetRange(Lexer()->GetToken().Loc()); 142 Lexer()->NextToken(); 143 144 while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 145 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 146 147 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 148 ThrowSyntaxError("Identifier expected"); 149 } 150 151 auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 152 identNode->SetRange(Lexer()->GetToken().Loc()); 153 154 expr = 155 AllocNode<ir::MemberExpression>(expr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); 156 Lexer()->NextToken(); 157 } 158 159 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 160 expr = ParseCallExpression(expr); 161 } 162 163 auto *result = AllocNode<ir::Decorator>(expr); 164 result->SetRange({start, expr->End()}); 165 166 return result; 167} 168 169void TSParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators) 170{ 171 if (decorators.empty()) { 172 return; 173 } 174 175 if (!node->CanHaveDecorator(true)) { 176 ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start()); 177 } 178 179 node->AddDecorators(std::move(decorators)); 180} 181 182ir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration() 183{ 184 ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE); 185 lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); 186 Lexer()->NextToken(); // eat type keyword 187 188 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 189 ThrowSyntaxError("Identifier expected"); 190 } 191 192 if (Lexer()->GetToken().IsReservedTypeName()) { 193 std::string errMsg("Type alias name cannot be '"); 194 errMsg.append(TokenToString(Lexer()->GetToken().KeywordType())); 195 errMsg.append("'"); 196 ThrowSyntaxError(errMsg.c_str()); 197 } 198 199 const util::StringView &ident = Lexer()->GetToken().Ident(); 200 201 auto *id = AllocNode<ir::Identifier>(ident, Allocator()); 202 id->SetRange(Lexer()->GetToken().Loc()); 203 Lexer()->NextToken(); 204 205 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 206 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 207 auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 208 typeParamDecl = ParseTypeParameterDeclaration(&options); 209 } 210 211 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 212 ThrowSyntaxError("'=' expected"); 213 } 214 215 Lexer()->NextToken(); // eat '=' 216 217 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 218 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 219 220 auto *typeAliasDecl = 221 AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext()); 222 typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()}); 223 224 return typeAliasDecl; 225} 226 227bool TSParser::CurrentLiteralIsBasicType() const 228{ 229 switch (Lexer()->GetToken().KeywordType()) { 230 case lexer::TokenType::KEYW_ANY: 231 case lexer::TokenType::KEYW_BOOLEAN: 232 case lexer::TokenType::KEYW_NUMBER: 233 case lexer::TokenType::KEYW_STRING: 234 case lexer::TokenType::KEYW_UNKNOWN: 235 case lexer::TokenType::KEYW_UNDEFINED: 236 case lexer::TokenType::KEYW_NEVER: 237 case lexer::TokenType::KEYW_OBJECT: 238 case lexer::TokenType::KEYW_BIGINT: { 239 return true; 240 } 241 default: { 242 break; 243 } 244 } 245 246 return false; 247} 248 249bool TSParser::CurrentIsBasicType() 250{ 251 switch (Lexer()->GetToken().Type()) { 252 case lexer::TokenType::LITERAL_NUMBER: 253 case lexer::TokenType::LITERAL_STRING: 254 case lexer::TokenType::LITERAL_FALSE: 255 case lexer::TokenType::LITERAL_TRUE: 256 case lexer::TokenType::LITERAL_NULL: 257 case lexer::TokenType::KEYW_THIS: 258 case lexer::TokenType::KEYW_VOID: { 259 return true; 260 } 261 case lexer::TokenType::LITERAL_IDENT: { 262 return CurrentLiteralIsBasicType(); 263 } 264 default: { 265 break; 266 } 267 } 268 269 return false; 270} 271 272ir::TypeNode *TSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) 273{ 274 ir::TypeNode *typeAnnotation = nullptr; 275 276 while (true) { 277 ir::TypeNode *element = ParseTypeAnnotationElement(typeAnnotation, options); 278 279 *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 280 281 if (element == nullptr) { 282 break; 283 } 284 285 typeAnnotation = element; 286 287 if ((((*options) & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) != 0) && Lexer()->GetToken().NewLine()) { 288 break; 289 } 290 } 291 292 return typeAnnotation; 293} 294 295ir::TypeNode *TSParser::ParseIdentifierReference() 296{ 297 if (CurrentLiteralIsBasicType() && Lexer()->Lookahead() != lexer::LEX_CHAR_DOT) { 298 return ParseBasicType(); 299 } 300 301 return ParseTypeReferenceOrQuery(); 302} 303 304bool TSParser::IsStartOfMappedType() const 305{ 306 auto pos = Lexer()->Save(); 307 Lexer()->NextToken(); 308 bool result = false; 309 310 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 311 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 312 Lexer()->NextToken(); 313 result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY; 314 Lexer()->Rewind(pos); 315 return result; 316 } 317 318 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 319 Lexer()->NextToken(); 320 } 321 322 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 323 Lexer()->Rewind(pos); 324 return false; 325 } 326 327 Lexer()->NextToken(); 328 329 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 330 Lexer()->Rewind(pos); 331 return false; 332 } 333 334 Lexer()->NextToken(); 335 336 result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IN; 337 338 Lexer()->Rewind(pos); 339 return result; 340} 341 342bool TSParser::IsStartOfTypePredicate() const 343{ 344 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 345 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS); 346 347 auto pos = Lexer()->Save(); 348 bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 349 if (isAsserts) { 350 Lexer()->NextToken(); 351 } 352 353 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && 354 Lexer()->GetToken().Type() != lexer::TokenType::KEYW_THIS) { 355 Lexer()->Rewind(pos); 356 return false; 357 } 358 359 if (isAsserts) { 360 Lexer()->Rewind(pos); 361 return true; 362 } 363 364 Lexer()->NextToken(); 365 366 bool result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS; 367 Lexer()->Rewind(pos); 368 return result; 369} 370 371bool TSParser::IsStartOfAbstractConstructorType() const 372{ 373 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) { 374 return false; 375 } 376 377 lexer::LexerPosition pos = Lexer()->Save(); 378 Lexer()->NextToken(); // eat 'abstract' 379 bool result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW; 380 381 Lexer()->Rewind(pos); 382 383 return result; 384} 385 386ir::TSImportType *TSParser::ParseImportType(const lexer::SourcePosition &startLoc, bool isTypeof) 387{ 388 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT); 389 390 Lexer()->NextToken(); 391 392 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 393 ThrowSyntaxError("'(' expected"); 394 } 395 396 Lexer()->NextToken(); 397 398 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 399 ir::TypeNode *param = ParseTypeAnnotation(&options); 400 401 if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) { 402 ThrowSyntaxError("String literal expected"); 403 } 404 405 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 406 ThrowSyntaxError("')' expected"); 407 } 408 409 Lexer()->NextToken(); 410 411 ir::Expression *qualifier = nullptr; 412 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 413 Lexer()->NextToken(); 414 qualifier = ParseQualifiedName(); 415 } 416 417 ir::TSTypeParameterInstantiation *typeParams = nullptr; 418 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || 419 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 420 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 421 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 422 } 423 424 typeParams = ParseTypeParameterInstantiation(&options); 425 } 426 427 auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof); 428 429 importType->SetRange({startLoc, Lexer()->GetToken().End()}); 430 431 return importType; 432} 433 434ir::TypeNode *TSParser::ParseThisType(bool throwError) 435{ 436 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS); 437 438 if (throwError && ((GetContext().Status() & ParserStatus::ALLOW_THIS_TYPE) == 0)) { 439 ThrowSyntaxError( 440 "A 'this' type is available only in a non-static member " 441 "of a class or interface."); 442 } 443 444 auto *returnType = AllocNode<ir::TSThisType>(); 445 returnType->SetRange(Lexer()->GetToken().Loc()); 446 447 Lexer()->NextToken(); 448 449 return returnType; 450} 451 452ir::TypeNode *TSParser::ParseConditionalType(ir::Expression *checkType, bool restrictExtends) 453{ 454 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 455 if (restrictExtends) { 456 ThrowSyntaxError("'?' expected."); 457 } 458 459 lexer::SourcePosition startLoc = checkType->Start(); 460 461 Lexer()->NextToken(); // eat 'extends' 462 463 ParserStatus savedStatus = GetContext().Status(); 464 GetContext().Status() |= ParserStatus::IN_EXTENDS; 465 466 TypeAnnotationParsingOptions options = 467 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 468 auto *extendsType = ParseTypeAnnotation(&options); 469 470 GetContext().Status() = savedStatus; 471 472 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 473 ThrowSyntaxError("'?' expected."); 474 } 475 476 Lexer()->NextToken(); // eat '?' 477 478 options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 479 auto *trueType = ParseTypeAnnotation(&options); 480 481 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 482 ThrowSyntaxError("':' expected."); 483 } 484 485 Lexer()->NextToken(); // eat ':' 486 487 auto *falseType = ParseTypeAnnotation(&options); 488 489 lexer::SourcePosition endLoc = falseType->End(); 490 491 auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType); 492 493 conditionalType->SetRange({startLoc, endLoc}); 494 495 return conditionalType; 496} 497 498ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() 499{ 500 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 501 502 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 503 lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start(); 504 Lexer()->NextToken(); 505 506 ir::TypeNode *type = ParseTypeAnnotation(&options); 507 508 if (!type->IsTSArrayType() && !type->IsTSTupleType()) { 509 ThrowSyntaxError( 510 "'readonly' type modifier is only permitted on array " 511 "and tuple literal types."); 512 } 513 514 auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY); 515 516 typeOperator->SetRange({typeOperatorStart, type->End()}); 517 518 return typeOperator; 519 } 520 521 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) { 522 lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start(); 523 Lexer()->NextToken(); 524 525 ir::TypeNode *type = ParseTypeAnnotation(&options); 526 527 auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF); 528 529 typeOperator->SetRange({typeOperatorStart, type->End()}); 530 531 return typeOperator; 532 } 533 534 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) { 535 if ((GetContext().Status() & ParserStatus::IN_EXTENDS) == 0) { 536 ThrowSyntaxError( 537 "'infer' declarations are only permitted in the " 538 "'extends' clause of a conditional type."); 539 } 540 541 lexer::SourcePosition inferStart = Lexer()->GetToken().Start(); 542 Lexer()->NextToken(); 543 544 ir::TSTypeParameter *typeParam = ParseTypeParameter(&options); 545 546 auto *inferType = AllocNode<ir::TSInferType>(typeParam); 547 548 inferType->SetRange({inferStart, Lexer()->GetToken().End()}); 549 550 return inferType; 551 } 552 553 return ParseIdentifierReference(); 554} 555 556ir::TypeNode *TSParser::ParseTupleElement(ir::TSTupleKind *kind, bool *seenOptional) 557{ 558 lexer::SourcePosition elementStart = Lexer()->GetToken().Start(); 559 ir::TypeNode *element = nullptr; 560 bool isOptional = false; 561 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 562 563 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !CurrentLiteralIsBasicType()) { 564 auto *elementIdent = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 565 elementIdent->SetRange(Lexer()->GetToken().Loc()); 566 567 if (Lexer()->Lookahead() == lexer::LEX_CHAR_COLON || Lexer()->Lookahead() == lexer::LEX_CHAR_QUESTION) { 568 if (*kind == ir::TSTupleKind::DEFAULT) { 569 ThrowSyntaxError("Tuple members must all have names or all not have names"); 570 } 571 572 Lexer()->NextToken(); // eat ident 573 574 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 575 Lexer()->NextToken(); // eat '?' 576 isOptional = true; 577 *seenOptional = true; 578 } else if (*seenOptional) { 579 ThrowSyntaxError("A required element cannot follow an optional element"); 580 } 581 582 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 583 ThrowSyntaxError("':' expected"); 584 } 585 586 Lexer()->NextToken(); // eat ':' 587 auto *elementType = ParseTypeAnnotation(&options); 588 *kind = ir::TSTupleKind::NAMED; 589 590 element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional); 591 } else { 592 element = ParseTypeReferenceOrQuery(); 593 } 594 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 595 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 596 element = ParseTypeAnnotationElement(element, &options); 597 } 598 } else { 599 if (*kind == ir::TSTupleKind::NAMED) { 600 ThrowSyntaxError("Tuple members must all have names or all not have names"); 601 } 602 603 *kind = ir::TSTupleKind::DEFAULT; 604 element = ParseTypeAnnotation(&options); 605 } 606 607 if (element != nullptr) { 608 element->SetRange({elementStart, Lexer()->GetToken().End()}); 609 } 610 return element; 611} 612 613ir::TSTupleType *TSParser::ParseTupleType() 614{ 615 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 616 lexer::SourcePosition tupleStart = Lexer()->GetToken().Start(); 617 ArenaVector<ir::TypeNode *> elements(Allocator()->Adapter()); 618 ir::TSTupleKind kind = ir::TSTupleKind::NONE; 619 bool seenOptional = false; 620 621 Lexer()->NextToken(); // eat '[' 622 623 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 624 ir::TypeNode *element = ParseTupleElement(&kind, &seenOptional); 625 elements.push_back(element); 626 627 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 628 break; 629 } 630 631 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) { 632 ThrowSyntaxError("',' expected."); 633 } 634 635 Lexer()->NextToken(); // eat ',' 636 } 637 638 lexer::SourcePosition tupleEnd = Lexer()->GetToken().End(); 639 Lexer()->NextToken(); // eat ']' 640 641 auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements)); 642 tupleType->SetRange({tupleStart, tupleEnd}); 643 return tupleType; 644} 645 646ir::TypeNode *TSParser::ParseIndexAccessType(ir::TypeNode *typeName) 647{ 648 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 649 650 do { 651 Lexer()->NextToken(); // eat '[' 652 653 ir::TypeNode *indexType = ParseTypeAnnotation(&options); 654 655 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 656 ThrowSyntaxError("']' expected"); 657 } 658 659 Lexer()->NextToken(); // eat ']' 660 661 typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType); 662 typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), Lexer()->GetToken().End()}); 663 } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 664 Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE); 665 666 return typeName; 667} 668 669ir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery) 670{ 671 lexer::SourcePosition referenceStartLoc = Lexer()->GetToken().Start(); 672 673 if (parseQuery) { 674 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF); 675 Lexer()->NextToken(); // eat 'typeof' 676 677 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) { 678 lexer::SourcePosition &startLoc = referenceStartLoc; 679 return ParseImportType(startLoc, true); 680 } 681 682 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 683 ThrowSyntaxError("Identifier expected."); 684 } 685 } 686 687 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 688 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 689 690 ir::Expression *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 691 typeName->SetRange(Lexer()->GetToken().Loc()); 692 typeName->AsIdentifier()->SetReference(); 693 694 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { 695 Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 696 } else { 697 Lexer()->NextToken(); 698 } 699 700 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 701 typeName = ParseQualifiedReference(typeName); 702 } 703 704 ir::TSTypeParameterInstantiation *typeParamInst = nullptr; 705 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 706 if (parseQuery) { 707 ThrowSyntaxError("Unexpected token."); 708 } 709 710 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 711 typeParamInst = ParseTypeParameterInstantiation(&options); 712 } 713 714 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 715 Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE) { 716 ir::TypeNode *typeRef = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode() 717 : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode(); 718 719 typeRef->SetRange({referenceStartLoc, Lexer()->GetToken().End()}); 720 721 return ParseIndexAccessType(typeRef); 722 } 723 724 ir::TypeNode *returnNode = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode() 725 : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode(); 726 727 returnNode->SetRange({referenceStartLoc, typeName->End()}); 728 729 return returnNode; 730} 731 732ir::TSTypeParameter *TSParser::ParseMappedTypeParameter() 733{ 734 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 735 736 auto *paramName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 737 paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); 738 739 Lexer()->NextToken(); 740 741 Lexer()->NextToken(); // eat 'in' 742 743 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 744 ir::TypeNode *constraint = ParseTypeAnnotation(&options); 745 746 lexer::SourcePosition endLoc = constraint->End(); 747 748 auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr); 749 750 typeParameter->SetRange({startLoc, endLoc}); 751 752 return typeParameter; 753} 754 755ir::MappedOption TSParser::ParseMappedOption(lexer::TokenType tokenType) 756{ 757 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS && 758 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS && 759 Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) { 760 return ir::MappedOption::NO_OPTS; 761 } 762 763 auto result = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS 764 : ir::MappedOption::PLUS; 765 766 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 767 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 768 Lexer()->NextToken(); 769 } 770 771 if (Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) { 772 ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."}); 773 } 774 775 Lexer()->NextToken(); 776 777 return result; 778} 779 780ir::TSMappedType *TSParser::ParseMappedType() 781{ 782 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); 783 784 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 785 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat '{' 786 787 ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY); 788 789 Lexer()->NextToken(); // eat '[' 790 791 ir::TSTypeParameter *typeParameter = ParseMappedTypeParameter(); 792 793 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 794 ThrowSyntaxError("']' expected"); 795 } 796 797 Lexer()->NextToken(); // eat ']' 798 799 ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK); 800 801 ir::TypeNode *typeAnnotation = nullptr; 802 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 803 Lexer()->NextToken(); // eat ':' 804 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 805 typeAnnotation = ParseTypeAnnotation(&options); 806 } 807 808 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 809 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 810 ThrowSyntaxError("';' expected"); 811 } 812 813 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 814 Lexer()->NextToken(); // eat ';' 815 } 816 817 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 818 ThrowSyntaxError("'}' expected"); 819 } 820 821 auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, typeAnnotation, readonly, optional); 822 823 mappedType->SetRange({startLoc, Lexer()->GetToken().End()}); 824 825 Lexer()->NextToken(); // eat '}' 826 827 return mappedType; 828} 829 830ir::TSTypePredicate *TSParser::ParseTypePredicate() 831{ 832 auto pos = Lexer()->Save(); 833 lexer::SourcePosition startPos = Lexer()->GetToken().Start(); 834 bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 835 if (isAsserts) { 836 Lexer()->NextToken(); // eat 'asserts' 837 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) { 838 isAsserts = false; 839 Lexer()->Rewind(pos); 840 } 841 } 842 843 ir::Expression *parameterName = nullptr; 844 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 845 parameterName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 846 } else { 847 parameterName = AllocNode<ir::TSThisType>(); 848 } 849 850 parameterName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); 851 852 Lexer()->NextToken(); 853 854 ir::TypeNode *typeAnnotation = nullptr; 855 lexer::SourcePosition endPos; 856 ir::TSTypePredicate *result = nullptr; 857 858 if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) { 859 endPos = parameterName->End(); 860 result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 861 result->SetRange({startPos, endPos}); 862 return result; 863 } 864 865 Lexer()->NextToken(); // eat 'is' 866 867 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 868 typeAnnotation = ParseTypeAnnotation(&options); 869 endPos = typeAnnotation->End(); 870 871 result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 872 873 result->SetRange({startPos, endPos}); 874 875 return result; 876} 877 878ir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotation) 879{ 880 if (typeAnnotation != nullptr) { 881 return nullptr; 882 } 883 884 if (IsStartOfMappedType()) { 885 return ParseMappedType(); 886 } 887 888 lexer::SourcePosition bodyStart = Lexer()->GetToken().Start(); 889 auto members = ParseTypeLiteralOrInterface(); 890 lexer::SourcePosition bodyEnd = Lexer()->GetToken().End(); 891 Lexer()->NextToken(); 892 893 auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members)); 894 auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType); 895 literalType->SetVariable(typeVar); 896 literalType->SetRange({bodyStart, bodyEnd}); 897 return literalType; 898} 899 900ir::TypeNode *TSParser::ParseTypeReferenceOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate) 901{ 902 if (typeAnnotation != nullptr) { 903 return nullptr; 904 } 905 906 if (canBeTsTypePredicate && IsStartOfTypePredicate()) { 907 return ParseTypePredicate(); 908 } 909 910 return ParseTypeOperatorOrTypeReference(); 911} 912 913ir::TypeNode *TSParser::ParseThisTypeOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate, 914 bool throwError) 915{ 916 if (typeAnnotation != nullptr) { 917 return nullptr; 918 } 919 920 if (canBeTsTypePredicate && IsStartOfTypePredicate()) { 921 return ParseTypePredicate(); 922 } 923 924 return ParseThisType(throwError); 925} 926 927ir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType) 928{ 929 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 930 Lexer()->NextToken(); // eat '[' 931 932 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 933 ThrowSyntaxError("']' expected"); 934 } 935 936 lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 937 Lexer()->NextToken(); // eat ']' 938 939 lexer::SourcePosition startLoc = elementType->Start(); 940 auto *arrayType = AllocNode<ir::TSArrayType>(elementType); 941 arrayType->SetRange({startLoc, endLoc}); 942 943 return arrayType; 944} 945 946ir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExtends) 947{ 948 ArenaVector<ir::TypeNode *> types(Allocator()->Adapter()); 949 lexer::SourcePosition startLoc; 950 951 TypeAnnotationParsingOptions options = 952 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_UNION; 953 954 if (restrictExtends) { 955 options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 956 } 957 958 if (type != nullptr) { 959 startLoc = type->Start(); 960 types.push_back(type); 961 } else { 962 startLoc = Lexer()->GetToken().Start(); 963 } 964 965 while (true) { 966 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) { 967 break; 968 } 969 970 Lexer()->NextToken(); // eat '|' 971 972 types.push_back(ParseTypeAnnotation(&options)); 973 } 974 975 lexer::SourcePosition endLoc = types.back()->End(); 976 977 auto *unionType = AllocNode<ir::TSUnionType>(std::move(types)); 978 auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType); 979 unionType->SetVariable(typeVar); 980 unionType->SetRange({startLoc, endLoc}); 981 982 return unionType; 983} 984 985ir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends) 986{ 987 ArenaVector<ir::Expression *> types(Allocator()->Adapter()); 988 lexer::SourcePosition startLoc; 989 990 TypeAnnotationParsingOptions options = 991 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION; 992 993 if (restrictExtends) { 994 options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 995 } 996 997 if (inUnion) { 998 options |= TypeAnnotationParsingOptions::IN_UNION; 999 } 1000 1001 if (type != nullptr) { 1002 startLoc = type->Start(); 1003 types.push_back(type); 1004 } else { 1005 startLoc = Lexer()->GetToken().Start(); 1006 } 1007 1008 while (true) { 1009 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) { 1010 break; 1011 } 1012 1013 Lexer()->NextToken(); // eat '&' 1014 1015 types.push_back(ParseTypeAnnotation(&options)); 1016 } 1017 1018 lexer::SourcePosition endLoc = types.back()->End(); 1019 1020 auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types)); 1021 auto *typeVar = 1022 varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType); 1023 intersectionType->SetVariable(typeVar); 1024 intersectionType->SetRange({startLoc, endLoc}); 1025 1026 return intersectionType; 1027} 1028 1029class TSParser::ParseBasicTypeHelper { 1030 friend ir::TypeNode *TSParser::ParseBasicType(); 1031 1032private: 1033 static ir::TypeNode *GetTypeAnnotationFromLiteral(TSParser *parser, lexer::Lexer *lexer) 1034 { 1035 switch (lexer->GetToken().KeywordType()) { 1036 case lexer::TokenType::LITERAL_NUMBER: { 1037 if ((lexer->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { 1038 auto *bigintNode = parser->AllocNode<ir::BigIntLiteral>(lexer->GetToken().BigInt()); 1039 bigintNode->SetRange(lexer->GetToken().Loc()); 1040 1041 return parser->AllocNode<ir::TSLiteralType>(bigintNode); 1042 } 1043 auto *numberNode = parser->AllocNode<ir::NumberLiteral>(lexer->GetToken().GetNumber()); 1044 numberNode->SetRange(lexer->GetToken().Loc()); 1045 1046 return parser->AllocNode<ir::TSLiteralType>(numberNode); 1047 } 1048 case lexer::TokenType::LITERAL_STRING: { 1049 auto *stringNode = parser->AllocNode<ir::StringLiteral>(lexer->GetToken().String()); 1050 stringNode->SetRange(lexer->GetToken().Loc()); 1051 1052 return parser->AllocNode<ir::TSLiteralType>(stringNode); 1053 } 1054 case lexer::TokenType::LITERAL_TRUE: { 1055 auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(true); 1056 booleanLiteral->SetRange(lexer->GetToken().Loc()); 1057 1058 return parser->AllocNode<ir::TSLiteralType>(booleanLiteral); 1059 } 1060 case lexer::TokenType::LITERAL_FALSE: { 1061 auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(false); 1062 booleanLiteral->SetRange(lexer->GetToken().Loc()); 1063 1064 return parser->AllocNode<ir::TSLiteralType>(booleanLiteral); 1065 } 1066 case lexer::TokenType::LITERAL_NULL: { 1067 return parser->AllocNode<ir::TSNullKeyword>(); 1068 } 1069 default: { 1070 return nullptr; 1071 } 1072 } 1073 } 1074 1075 static ir::TypeNode *GetTypeAnnotation(TSParser *parser, lexer::Lexer *lexer) 1076 { 1077 switch (lexer->GetToken().KeywordType()) { 1078 case lexer::TokenType::LITERAL_NUMBER: 1079 case lexer::TokenType::LITERAL_STRING: 1080 case lexer::TokenType::LITERAL_TRUE: 1081 case lexer::TokenType::LITERAL_FALSE: 1082 case lexer::TokenType::LITERAL_NULL: { 1083 return GetTypeAnnotationFromLiteral(parser, lexer); 1084 } 1085 case lexer::TokenType::KEYW_ANY: { 1086 return parser->AllocNode<ir::TSAnyKeyword>(); 1087 } 1088 case lexer::TokenType::KEYW_BOOLEAN: { 1089 return parser->AllocNode<ir::TSBooleanKeyword>(); 1090 } 1091 case lexer::TokenType::KEYW_NUMBER: { 1092 return parser->AllocNode<ir::TSNumberKeyword>(); 1093 } 1094 case lexer::TokenType::KEYW_STRING: { 1095 return parser->AllocNode<ir::TSStringKeyword>(); 1096 } 1097 case lexer::TokenType::KEYW_UNKNOWN: { 1098 return parser->AllocNode<ir::TSUnknownKeyword>(); 1099 } 1100 case lexer::TokenType::KEYW_VOID: { 1101 return parser->AllocNode<ir::TSVoidKeyword>(); 1102 } 1103 case lexer::TokenType::KEYW_UNDEFINED: { 1104 return parser->AllocNode<ir::TSUndefinedKeyword>(); 1105 } 1106 case lexer::TokenType::KEYW_NEVER: { 1107 return parser->AllocNode<ir::TSNeverKeyword>(); 1108 } 1109 case lexer::TokenType::KEYW_OBJECT: { 1110 return parser->AllocNode<ir::TSObjectKeyword>(); 1111 } 1112 case lexer::TokenType::KEYW_BIGINT: { 1113 return parser->AllocNode<ir::TSBigintKeyword>(); 1114 } 1115 default: { 1116 parser->ThrowSyntaxError("Unexpected type"); 1117 } 1118 } 1119 } 1120}; 1121ir::TypeNode *TSParser::ParseBasicType() 1122{ 1123 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) { 1124 Lexer()->NextToken(); 1125 1126 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) { 1127 ThrowSyntaxError("Type expected"); 1128 } 1129 } 1130 1131 ir::TypeNode *typeAnnotation = ParseBasicTypeHelper::GetTypeAnnotation(this, Lexer()); 1132 1133 typeAnnotation->SetRange(Lexer()->GetToken().Loc()); 1134 1135 Lexer()->NextToken(); 1136 return typeAnnotation; 1137} 1138 1139ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError) 1140{ 1141 if (typeAnnotation != nullptr) { 1142 return nullptr; 1143 } 1144 1145 lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); 1146 1147 bool abstractConstructor = false; 1148 1149 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) { 1150 abstractConstructor = true; 1151 Lexer()->NextToken(); // eat 'abstract' 1152 } 1153 1154 bool isConstructionType = false; 1155 1156 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW) { 1157 Lexer()->NextToken(); // eat 'new' 1158 isConstructionType = true; 1159 1160 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 1161 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1162 ThrowSyntaxError("'(' expected"); 1163 } 1164 } 1165 1166 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) { 1167 return ParseFunctionType(typeStart, isConstructionType, throwError, abstractConstructor); 1168 } 1169 1170 const auto startPos = Lexer()->Save(); 1171 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 1172 Lexer()->NextToken(); // eat '(' 1173 1174 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 1175 ir::TypeNode *type = ParseTypeAnnotation(&options); 1176 1177 if (type == nullptr) { 1178 Lexer()->Rewind(startPos); 1179 return ParseFunctionType(typeStart, false, throwError); 1180 } 1181 1182 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || 1183 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK || 1184 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1185 Lexer()->Rewind(startPos); 1186 return ParseFunctionType(typeStart, false, throwError); 1187 } 1188 1189 if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1190 ThrowSyntaxError("')' expected"); 1191 } 1192 1193 lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 1194 Lexer()->NextToken(); // eat ')' 1195 1196 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) { 1197 Lexer()->Rewind(startPos); 1198 1199 return ParseFunctionType(typeStart, false, throwError); 1200 } 1201 1202 auto *result = AllocNode<ir::TSParenthesizedType>(type); 1203 result->SetRange({typeStart, endLoc}); 1204 1205 return result; 1206} 1207 1208ir::TypeNode *TSParser::ParseFunctionType(lexer::SourcePosition startLoc, bool isConstructionType, bool throwError, 1209 bool abstractConstructor) 1210{ 1211 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 1212 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1213 auto options = throwError ? TypeAnnotationParsingOptions::REPORT_ERROR : TypeAnnotationParsingOptions::NO_OPTS; 1214 typeParamDecl = ParseTypeParameterDeclaration(&options); 1215 1216 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1217 if (!throwError) { 1218 return nullptr; 1219 } 1220 1221 ThrowSyntaxError("'(' expected"); 1222 } 1223 } 1224 1225 auto params = ParseFunctionParams(); 1226 1227 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 1228 ThrowSyntaxError("'=>' expected"); 1229 } 1230 1231 Lexer()->NextToken(); // eat '=>' 1232 1233 TypeAnnotationParsingOptions options = 1234 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 1235 ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options); 1236 1237 ir::TypeNode *funcType = nullptr; 1238 1239 ir::FunctionSignature signature(typeParamDecl, std::move(params), returnTypeAnnotation); 1240 1241 if (isConstructionType) { 1242 funcType = AllocNode<ir::TSConstructorType>(std::move(signature), abstractConstructor); 1243 } else { 1244 funcType = AllocNode<ir::TSFunctionType>(std::move(signature)); 1245 } 1246 1247 funcType->SetRange({startLoc, returnTypeAnnotation->End()}); 1248 1249 return funcType; 1250} 1251 1252class TSParser::ParseTypeAnnotationElementHelper { 1253 friend ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, 1254 TypeAnnotationParsingOptions *options); 1255 1256private: 1257 static ir::TypeNode *ParseKeywordTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation, 1258 TypeAnnotationParsingOptions *options) 1259 { 1260 switch (lexer->GetToken().Type()) { 1261 case lexer::TokenType::KEYW_NEW: { 1262 return parser->ParseParenthesizedOrFunctionType( 1263 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 1264 } 1265 case lexer::TokenType::KEYW_TYPEOF: { 1266 if (typeAnnotation != nullptr) { 1267 break; 1268 } 1269 1270 return parser->ParseTypeReferenceOrQuery(true); 1271 } 1272 case lexer::TokenType::KEYW_IMPORT: { 1273 if (typeAnnotation != nullptr) { 1274 break; 1275 } 1276 return parser->ParseImportType(lexer->GetToken().Start()); 1277 } 1278 case lexer::TokenType::KEYW_CONST: { 1279 if (((*options) & TypeAnnotationParsingOptions::ALLOW_CONST) == 0) { 1280 break; 1281 } 1282 1283 (*options) &= ~TypeAnnotationParsingOptions::ALLOW_CONST; 1284 return parser->ParseConstExpression(); 1285 } 1286 case lexer::TokenType::KEYW_EXTENDS: { 1287 if (((*options) & 1288 (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) { 1289 break; 1290 } 1291 1292 if (typeAnnotation == nullptr) { 1293 return parser->ParseIdentifierReference(); 1294 } 1295 1296 return parser->ParseConditionalType(typeAnnotation, 1297 ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 1298 } 1299 case lexer::TokenType::KEYW_THIS: { 1300 return parser->ParseThisTypeOrTypePredicate( 1301 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0, 1302 ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 1303 } 1304 default: { 1305 break; 1306 } 1307 } 1308 return nullptr; 1309 } 1310 1311 static ir::TypeNode *ParsePunctuatorTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation, 1312 TypeAnnotationParsingOptions *options) 1313 { 1314 switch (lexer->GetToken().Type()) { 1315 case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { 1316 if (((*options) & 1317 (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) { 1318 break; 1319 } 1320 1321 return parser->ParseUnionType(typeAnnotation, 1322 ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 1323 } 1324 case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { 1325 if (((*options) & TypeAnnotationParsingOptions::IN_INTERSECTION) != 0) { 1326 break; 1327 } 1328 1329 return parser->ParseIntersectionType( 1330 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::IN_UNION) != 0, 1331 ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 1332 } 1333 case lexer::TokenType::PUNCTUATOR_LESS_THAN: 1334 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 1335 return parser->ParseParenthesizedOrFunctionType( 1336 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 1337 } 1338 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 1339 if (typeAnnotation != nullptr) { 1340 if (lexer->Lookahead() == lexer::LEX_CHAR_RIGHT_SQUARE) { 1341 return parser->ParseArrayType(typeAnnotation); 1342 } 1343 1344 return parser->ParseIndexAccessType(typeAnnotation); 1345 } 1346 1347 return parser->ParseTupleType(); 1348 } 1349 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 1350 return parser->ParseTypeLiteralOrMappedType(typeAnnotation); 1351 } 1352 default: { 1353 break; 1354 } 1355 } 1356 1357 return nullptr; 1358 } 1359}; 1360 1361ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, TypeAnnotationParsingOptions *options) 1362{ 1363 switch (Lexer()->GetToken().Type()) { 1364 case lexer::TokenType::PUNCTUATOR_MINUS: 1365 case lexer::TokenType::LITERAL_NUMBER: 1366 case lexer::TokenType::LITERAL_STRING: 1367 case lexer::TokenType::LITERAL_FALSE: 1368 case lexer::TokenType::LITERAL_TRUE: 1369 case lexer::TokenType::LITERAL_NULL: 1370 case lexer::TokenType::KEYW_VOID: { 1371 if (typeAnnotation != nullptr) { 1372 break; 1373 } 1374 1375 return ParseBasicType(); 1376 } 1377 case lexer::TokenType::LITERAL_IDENT: { 1378 if (IsStartOfAbstractConstructorType()) { 1379 return ParseParenthesizedOrFunctionType(typeAnnotation, 1380 ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 1381 } 1382 1383 return ParseTypeReferenceOrTypePredicate( 1384 typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0); 1385 } 1386 default: { 1387 ir::TypeNode *parsedValue = 1388 ParseTypeAnnotationElementHelper::ParseKeywordTokens(this, Lexer(), typeAnnotation, options); 1389 if (parsedValue != nullptr) { 1390 return parsedValue; 1391 } 1392 1393 parsedValue = 1394 ParseTypeAnnotationElementHelper::ParsePunctuatorTokens(this, Lexer(), typeAnnotation, options); 1395 if (parsedValue != nullptr) { 1396 return parsedValue; 1397 } 1398 1399 break; 1400 } 1401 } 1402 1403 if (typeAnnotation == nullptr && (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0)) { 1404 ThrowSyntaxError("Type expected"); 1405 } 1406 1407 return nullptr; 1408} 1409 1410bool TSParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression, 1411 const lexer::SourcePosition &startLoc, bool ignoreCallExpression) 1412{ 1413 if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN || 1414 (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) { 1415 return true; 1416 } 1417 1418 const auto savedPos = Lexer()->Save(); 1419 1420 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 1421 Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 1422 } 1423 1424 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 1425 ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options); 1426 1427 if (typeParams == nullptr) { 1428 Lexer()->Rewind(savedPos); 1429 return true; 1430 } 1431 1432 if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) { 1433 ThrowSyntaxError("'(' or '`' expected"); 1434 } 1435 1436 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1437 if (!ignoreCallExpression) { 1438 *returnExpression = ParseCallExpression(*returnExpression, false); 1439 (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams); 1440 return false; 1441 } 1442 1443 return true; 1444 } 1445 1446 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) { 1447 ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); 1448 lexer::SourcePosition endLoc = propertyNode->End(); 1449 1450 *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams); 1451 (*returnExpression)->SetRange({startLoc, endLoc}); 1452 return false; 1453 } 1454 1455 Lexer()->Rewind(savedPos); 1456 return true; 1457} 1458 1459bool TSParser::IsNamedFunctionExpression() 1460{ 1461 return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 1462 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN; 1463} 1464 1465ir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) 1466{ 1467 auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 1468 identNode->SetReference(); 1469 identNode->SetRange(Lexer()->GetToken().Loc()); 1470 1471 Lexer()->NextToken(); 1472 1473 ParsePotentialOptionalFunctionParameter(identNode); 1474 1475 return identNode; 1476} 1477 1478ir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature) 1479{ 1480 lexer::SourcePosition memberStartLoc = Lexer()->GetToken().Start(); 1481 1482 if (!isCallSignature) { 1483 Lexer()->NextToken(); // eat 'new' keyword 1484 } 1485 1486 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 1487 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1488 auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 1489 typeParamDecl = ParseTypeParameterDeclaration(&options); 1490 1491 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1492 ThrowSyntaxError("'(' expected"); 1493 } 1494 } 1495 1496 FunctionParameterContext funcParamContext(&GetContext()); 1497 auto params = ParseFunctionParams(); 1498 1499 ir::TypeNode *typeAnnotation = nullptr; 1500 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1501 Lexer()->NextToken(); // eat ':' 1502 TypeAnnotationParsingOptions options = 1503 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 1504 typeAnnotation = ParseTypeAnnotation(&options); 1505 } 1506 1507 auto kind = isCallSignature ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE 1508 : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE; 1509 auto *signatureMember = AllocNode<ir::TSSignatureDeclaration>( 1510 kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation)); 1511 signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()}); 1512 1513 return signatureMember; 1514} 1515 1516bool TSParser::IsPotentiallyIndexSignature() 1517{ 1518 const auto savedPos = Lexer()->Save(); 1519 1520 Lexer()->NextToken(); // eat '[' 1521 1522 bool isIndexSignature = 1523 Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON; 1524 1525 Lexer()->Rewind(savedPos); 1526 1527 return isIndexSignature; 1528} 1529 1530// NOLINTNEXTLINE(google-default-arguments) 1531ir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly) 1532{ 1533 Lexer()->NextToken(); // eat '[' 1534 1535 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); 1536 auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 1537 key->SetRange(Lexer()->GetToken().Loc()); 1538 1539 Lexer()->NextToken(); // eat key 1540 1541 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON); 1542 1543 Lexer()->NextToken(); // eat ':' 1544 1545 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 1546 ir::TypeNode *keyType = ParseTypeAnnotation(&options); 1547 1548 if (!keyType->IsTSNumberKeyword() && !keyType->IsTSStringKeyword()) { 1549 ThrowSyntaxError( 1550 "An index signature parameter type must be either " 1551 "'string' or 'number'"); 1552 } 1553 1554 key->SetTsTypeAnnotation(keyType); 1555 1556 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1557 ThrowSyntaxError("']' expected."); 1558 } 1559 1560 Lexer()->NextToken(); // eat ']' 1561 1562 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 1563 ThrowSyntaxError("An index signature must have a type annotation."); 1564 } 1565 1566 Lexer()->NextToken(); // eat ':' 1567 1568 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 1569 1570 auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly); 1571 indexSignature->SetRange({startLoc, Lexer()->GetToken().End()}); 1572 return indexSignature; 1573} 1574 1575std::tuple<ir::Expression *, bool> TSParser::ParseInterfacePropertyKey() 1576{ 1577 ir::Expression *key = nullptr; 1578 bool isComputed = false; 1579 1580 switch (Lexer()->GetToken().Type()) { 1581 case lexer::TokenType::LITERAL_IDENT: { 1582 const util::StringView &ident = Lexer()->GetToken().Ident(); 1583 key = AllocNode<ir::Identifier>(ident, Allocator()); 1584 key->SetRange(Lexer()->GetToken().Loc()); 1585 break; 1586 } 1587 case lexer::TokenType::LITERAL_STRING: { 1588 const util::StringView &string = Lexer()->GetToken().String(); 1589 key = AllocNode<ir::StringLiteral>(string); 1590 key->SetRange(Lexer()->GetToken().Loc()); 1591 break; 1592 } 1593 case lexer::TokenType::LITERAL_NUMBER: { 1594 if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { 1595 key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt()); 1596 } else { 1597 key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber()); 1598 } 1599 1600 key->SetRange(Lexer()->GetToken().Loc()); 1601 break; 1602 } 1603 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 1604 Lexer()->NextToken(); // eat left square bracket 1605 1606 key = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 1607 isComputed = true; 1608 1609 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1610 ThrowSyntaxError("Unexpected token, expected ']'"); 1611 } 1612 break; 1613 } 1614 default: { 1615 ThrowSyntaxError("Unexpected token in property key"); 1616 } 1617 } 1618 1619 Lexer()->NextToken(); 1620 return {key, isComputed}; 1621} 1622 1623void TSParser::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, varbinder::VariableFlags flags) 1624{ 1625 varbinder::Variable *propVar = nullptr; 1626 bool isMethod = (flags & varbinder::VariableFlags::METHOD) != 0; 1627 util::StringView propName = "__computed"; 1628 1629 switch (key->Type()) { 1630 case ir::AstNodeType::IDENTIFIER: { 1631 propName = key->AsIdentifier()->Name(); 1632 break; 1633 } 1634 case ir::AstNodeType::NUMBER_LITERAL: { 1635 propName = key->AsNumberLiteral()->Str(); 1636 flags |= varbinder::VariableFlags::NUMERIC_NAME; 1637 break; 1638 } 1639 case ir::AstNodeType::STRING_LITERAL: { 1640 propName = key->AsStringLiteral()->Str(); 1641 break; 1642 } 1643 default: { 1644 flags |= varbinder::VariableFlags::COMPUTED; 1645 break; 1646 } 1647 } 1648 1649 propVar = isMethod ? varbinder::Scope::CreateVar<varbinder::MethodDecl>(Allocator(), propName, flags, node) 1650 : varbinder::Scope::CreateVar<varbinder::PropertyDecl>(Allocator(), propName, flags, node); 1651 1652 node->SetVariable(propVar); 1653} 1654 1655ir::AstNode *TSParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly) 1656{ 1657 auto [key, isComputed] = ParseInterfacePropertyKey(); 1658 varbinder::VariableFlags flags = isReadonly ? varbinder::VariableFlags::READONLY : varbinder::VariableFlags::NONE; 1659 1660 bool isOptional = false; 1661 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 1662 isOptional = true; 1663 flags |= varbinder::VariableFlags::OPTIONAL; 1664 Lexer()->NextToken(); // eat '?' 1665 } 1666 1667 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 1668 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1669 if (isReadonly) { 1670 ThrowSyntaxError("'readonly' modifier can only appear on a property declaration or index signature.", 1671 startLoc); 1672 } 1673 1674 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 1675 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1676 auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 1677 typeParamDecl = ParseTypeParameterDeclaration(&options); 1678 } 1679 1680 ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, false); 1681 1682 FunctionParameterContext funcParamContext(&GetContext()); 1683 auto params = ParseFunctionParams(); 1684 1685 ir::TypeNode *returnType = nullptr; 1686 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1687 Lexer()->NextToken(); // eat ':' 1688 TypeAnnotationParsingOptions options = 1689 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 1690 returnType = ParseTypeAnnotation(&options); 1691 } 1692 1693 auto *methodSignature = AllocNode<ir::TSMethodSignature>( 1694 key, ir::FunctionSignature(typeParamDecl, std::move(params), returnType), isComputed, isOptional); 1695 CreateTSVariableForProperty(methodSignature, key, flags | varbinder::VariableFlags::METHOD); 1696 methodSignature->SetRange({startLoc, Lexer()->GetToken().End()}); 1697 return methodSignature; 1698 } 1699 1700 ir::TypeNode *typeAnnotation = nullptr; 1701 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1702 Lexer()->NextToken(); // eat ':' 1703 TypeAnnotationParsingOptions options = 1704 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 1705 typeAnnotation = ParseTypeAnnotation(&options); 1706 } 1707 1708 auto *propertySignature = 1709 AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, isOptional, isReadonly); 1710 CreateTSVariableForProperty(propertySignature, key, flags | varbinder::VariableFlags::PROPERTY); 1711 propertySignature->SetRange({startLoc, Lexer()->GetToken().End()}); 1712 return propertySignature; 1713} 1714 1715ir::AstNode *TSParser::ParseTypeLiteralOrInterfaceMember() 1716{ 1717 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { 1718 ThrowSyntaxError("Decorators are not allowed here"); 1719 } 1720 1721 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 1722 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1723 return ParseSignatureMember(true); 1724 } 1725 1726 char32_t nextCp = Lexer()->Lookahead(); 1727 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW && 1728 (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN)) { 1729 return ParseSignatureMember(false); 1730 } 1731 1732 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 1733 bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY && 1734 nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON && 1735 nextCp != lexer::LEX_CHAR_COMMA; 1736 if (isReadonly) { 1737 Lexer()->NextToken(); // eat 'readonly" 1738 } 1739 1740 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 1741 IsPotentiallyIndexSignature()) { 1742 return ParseIndexSignature(startLoc, isReadonly); 1743 } 1744 1745 return ParsePropertyOrMethodSignature(startLoc, isReadonly); 1746} 1747 1748void TSParser::ValidateFunctionParam(const ArenaVector<ir::Expression *> ¶ms, const ir::Expression *parameter, 1749 bool *seenOptional) 1750{ 1751 if (!parameter->IsIdentifier()) { 1752 GetContext().Status() |= ParserStatus::HAS_COMPLEX_PARAM; 1753 if (!parameter->IsRestElement()) { 1754 return; 1755 } 1756 1757 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1758 ThrowSyntaxError("A rest parameter must be last in parameter list"); 1759 } 1760 return; 1761 } 1762 1763 bool currentIsOptional = parameter->AsIdentifier()->IsOptional(); 1764 if (*seenOptional && !currentIsOptional) { 1765 ThrowSyntaxError("A required parameter cannot follow an optional parameter"); 1766 } 1767 1768 *seenOptional |= currentIsOptional; 1769 const util::StringView ¶mName = parameter->AsIdentifier()->Name(); 1770 1771 if (paramName.Is("this")) { 1772 if (!params.empty()) { 1773 ThrowSyntaxError("A 'this' parameter must be the first parameter"); 1774 } 1775 1776 if ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0) { 1777 ThrowSyntaxError("A constructor cannot have a 'this' parameter"); 1778 } 1779 1780 if ((GetContext().Status() & ParserStatus::ARROW_FUNCTION) != 0) { 1781 ThrowSyntaxError("An arrow function cannot have a 'this' parameter"); 1782 } 1783 1784 if ((GetContext().Status() & ParserStatus::ACCESSOR_FUNCTION) != 0) { 1785 ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters"); 1786 } 1787 } 1788 1789 if (paramName.Is("constructor") && ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0)) { 1790 ThrowSyntaxError("'constructor' cannot be used as a parameter property name"); 1791 } 1792} 1793 1794ArenaVector<ir::Expression *> TSParser::ParseFunctionParams() 1795{ 1796 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 1797 Lexer()->NextToken(); 1798 1799 ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 1800 bool seenOptional = false; 1801 1802 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1803 ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter()); 1804 1805 ParseDecorators(decorators); 1806 1807 if (!decorators.empty() && ((GetContext().Status() & ParserStatus::IN_CLASS_BODY) == 0)) { 1808 ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start()); 1809 } 1810 1811 ir::Expression *parameter = ParseFunctionParameter(); 1812 ValidateFunctionParam(params, parameter, &seenOptional); 1813 1814 if (!decorators.empty()) { 1815 parameter->AddDecorators(std::move(decorators)); 1816 } 1817 1818 params.push_back(parameter); 1819 1820 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 1821 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1822 ThrowSyntaxError(", expected"); 1823 } 1824 1825 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 1826 Lexer()->NextToken(); 1827 } 1828 } 1829 1830 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); 1831 Lexer()->NextToken(); 1832 1833 return params; 1834} 1835 1836ir::TypeNode *TSParser::ParseClassKeyAnnotation() 1837{ 1838 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1839 Lexer()->NextToken(); // eat ':' 1840 TypeAnnotationParsingOptions options = 1841 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 1842 return ParseTypeAnnotation(&options); 1843 } 1844 1845 return nullptr; 1846} 1847 1848void TSParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation) 1849{ 1850 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) { 1851 ThrowSyntaxError("A method cannot be named with a private identifier"); 1852 } 1853 1854 if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 1855 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) { 1856 if (((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY)) != 0)) { 1857 ThrowSyntaxError("Class method can not be declare nor readonly"); 1858 } 1859 desc->classMethod = true; 1860 } else { 1861 if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) { 1862 ThrowSyntaxError("Expected '('"); 1863 } 1864 desc->classField = true; 1865 1866 if (desc->invalidComputedProperty) { 1867 ThrowSyntaxError( 1868 "Computed property name must refer to a symbol or " 1869 "literal expression whose value is " 1870 "number or string"); 1871 } 1872 } 1873 1874 if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) { 1875 desc->newStatus |= ParserStatus::ASYNC_FUNCTION; 1876 } 1877 1878 if (desc->isGenerator) { 1879 desc->newStatus |= ParserStatus::GENERATOR_FUNCTION; 1880 } 1881} 1882 1883ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, 1884 const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, 1885 lexer::SourcePosition *propEnd) 1886{ 1887 if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) { 1888 desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION; 1889 } 1890 1891 desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION; 1892 1893 if (InAmbientContext() && (desc->newStatus & ParserStatus::ASYNC_FUNCTION) != 0) { 1894 ThrowSyntaxError("'async' modifier cannot be used in an ambient context."); 1895 } 1896 1897 if (InAmbientContext() && desc->isGenerator) { 1898 ThrowSyntaxError("Generators are not allowed in an ambient context."); 1899 } 1900 1901 if (desc->methodKind != ir::MethodDefinitionKind::SET && 1902 ((desc->newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) == 0)) { 1903 desc->newStatus |= ParserStatus::NEED_RETURN_TYPE; 1904 } 1905 1906 ir::ScriptFunction *func = ParseFunction(desc->newStatus); 1907 1908 if (func->IsOverload() && !desc->decorators.empty()) { 1909 ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.", 1910 desc->decorators.front()->Start()); 1911 } 1912 1913 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 1914 funcExpr->SetRange(func->Range()); 1915 1916 if (desc->methodKind == ir::MethodDefinitionKind::SET) { 1917 ValidateClassSetter(desc, properties, propName, func); 1918 } else if (desc->methodKind == ir::MethodDefinitionKind::GET) { 1919 ValidateClassGetter(desc, properties, propName, func); 1920 } 1921 1922 *propEnd = func->End(); 1923 func->AddFlag(ir::ScriptFunctionFlags::METHOD); 1924 auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), 1925 desc->isComputed); 1926 method->SetRange(funcExpr->Range()); 1927 1928 return method; 1929} 1930 1931void TSParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, 1932 ir::Expression *propName, ir::ScriptFunction *func) 1933{ 1934 if (func->Params().size() != 1) { 1935 ThrowSyntaxError("Setter must have exactly one formal parameter"); 1936 } 1937 1938 if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) { 1939 ir::ModifierFlags access = GetAccessability(desc->modifiers); 1940 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access); 1941 } 1942} 1943 1944void TSParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, 1945 ir::Expression *propName, ir::ScriptFunction *func) 1946{ 1947 if (!func->Params().empty()) { 1948 ThrowSyntaxError("Getter must not have formal parameters"); 1949 } 1950 1951 if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) { 1952 ir::ModifierFlags access = GetAccessability(desc->modifiers); 1953 1954 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access); 1955 } 1956} 1957 1958void TSParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation) 1959{ 1960 if (typeAnnotation == nullptr) { 1961 ThrowSyntaxError("An index signature must have a type annotation"); 1962 } 1963} 1964 1965bool TSParser::IsModifierKind(const lexer::Token &token) 1966{ 1967 switch (token.KeywordType()) { 1968 case lexer::TokenType::KEYW_PUBLIC: 1969 case lexer::TokenType::KEYW_PRIVATE: 1970 case lexer::TokenType::KEYW_PROTECTED: 1971 case lexer::TokenType::KEYW_STATIC: 1972 case lexer::TokenType::KEYW_ASYNC: 1973 case lexer::TokenType::KEYW_ABSTRACT: 1974 case lexer::TokenType::KEYW_DECLARE: 1975 case lexer::TokenType::KEYW_READONLY: 1976 return true; 1977 default: 1978 break; 1979 } 1980 1981 return false; 1982} 1983 1984void TSParser::CheckIfTypeParameterNameIsReserved() 1985{ 1986 if (Lexer()->GetToken().IsReservedTypeName()) { 1987 ThrowSyntaxError("Invalid type parameter name"); 1988 } 1989} 1990 1991void TSParser::ThrowErrorIfStaticConstructor(ir::ModifierFlags flags) 1992{ 1993 if ((flags & ir::ModifierFlags::STATIC) != 0) { 1994 ThrowSyntaxError("Static modifier can not appear on a constructor"); 1995 } 1996} 1997 1998std::tuple<bool, bool, bool> TSParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName) 1999{ 2000 Lexer()->NextToken(); // eat left square bracket 2001 2002 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && 2003 Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) { 2004 auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 2005 id->SetRange(Lexer()->GetToken().Loc()); 2006 2007 Lexer()->NextToken(); // eat param 2008 2009 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 2010 ThrowSyntaxError("':' expected"); 2011 } 2012 2013 Lexer()->NextToken(); // eat ':' 2014 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 2015 ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 2016 2017 if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { 2018 ThrowSyntaxError( 2019 "An index signature parameter type must be either " 2020 "'string' or 'number'"); 2021 } 2022 2023 id->SetTsTypeAnnotation(typeAnnotation); 2024 2025 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 2026 ThrowSyntaxError("']' expected"); 2027 } 2028 2029 *propName = id; 2030 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 2031 2032 return {false, false, true}; 2033 } 2034 2035 *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 2036 2037 bool invalidComputedProperty = 2038 !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() && 2039 !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() && 2040 (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol")); 2041 2042 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 2043 ThrowSyntaxError("Unexpected token, expected ']'"); 2044 } 2045 2046 return {true, invalidComputedProperty, false}; 2047} 2048 2049ir::TypeNode *TSParser::ParseFunctionReturnType([[maybe_unused]] ParserStatus status) 2050{ 2051 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 2052 Lexer()->NextToken(); // eat ':' 2053 TypeAnnotationParsingOptions options = 2054 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 2055 return ParseTypeAnnotation(&options); 2056 } 2057 2058 return nullptr; 2059} 2060 2061void TSParser::ValidateFunctionOverloadParams(const ArenaVector<ir::Expression *> ¶ms) 2062{ 2063 for (auto *it : params) { 2064 if (it->IsAssignmentPattern()) { 2065 ThrowSyntaxError( 2066 "A parameter initializer is only allowed in a function " 2067 "or constructor implementation.", 2068 it->Start()); 2069 } 2070 } 2071} 2072 2073std::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> TSParser::ParseFunctionBody( 2074 const ArenaVector<ir::Expression *> ¶ms, ParserStatus newStatus, ParserStatus contextStatus) 2075{ 2076 bool isDeclare = InAmbientContext(); 2077 bool isOverload = false; 2078 bool letDeclare = true; 2079 ir::BlockStatement *body = nullptr; 2080 lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 2081 2082 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 2083 if ((newStatus & ParserStatus::FUNCTION_DECLARATION) != 0) { 2084 ValidateFunctionOverloadParams(params); 2085 } else if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) { 2086 ThrowSyntaxError("Unexpected token, expected '{'"); 2087 } else { 2088 letDeclare = false; 2089 } 2090 2091 isOverload = true; 2092 } else if (isDeclare) { 2093 ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); 2094 } else { 2095 body = ParseBlockStatement(); 2096 endLoc = body->End(); 2097 } 2098 2099 return {letDeclare, body, endLoc, isOverload}; 2100} 2101 2102ir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers) 2103{ 2104 ir::Identifier *local = ParseNamedImport(Lexer()->GetToken()); 2105 Lexer()->NextToken(); // eat local name 2106 2107 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 2108 Lexer()->NextToken(); // eat substitution 2109 if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 2110 ThrowSyntaxError("identifier expected"); 2111 } 2112 2113 auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(local, ParseModuleReference(), false); 2114 2115 return importEqualsDecl; 2116 } 2117 2118 auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local); 2119 specifier->SetRange(specifier->Local()->Range()); 2120 specifiers->push_back(specifier); 2121 2122 Lexer()->NextToken(); // eat specifier name 2123 2124 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 2125 Lexer()->NextToken(); // eat comma 2126 } 2127 2128 return nullptr; 2129} 2130 2131void TSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param) 2132{ 2133 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 2134 Lexer()->NextToken(); // eat ':' 2135 2136 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 2137 param->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); 2138 } 2139 2140 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 2141 ThrowSyntaxError("Catch clause variable cannot have an initializer"); 2142 } 2143} 2144 2145void TSParser::ThrowPossibleOutOfBoundaryJumpError(bool allowBreak) 2146{ 2147 if (((GetContext().Status() & ParserStatus::FUNCTION) != 0) && !allowBreak) { 2148 ThrowSyntaxError("Jump target cannot cross function boundary"); 2149 } 2150} 2151 2152void TSParser::ThrowIllegalBreakError() 2153{ 2154 ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement"); 2155} 2156 2157void TSParser::ThrowIllegalContinueError() 2158{ 2159 ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement"); 2160} 2161 2162void TSParser::ThrowMultipleDefaultError() 2163{ 2164 ThrowSyntaxError("A 'default' clause cannot appear more than once in a 'switch' statement"); 2165} 2166 2167void TSParser::ThrowIllegalNewLineErrorAfterThrow() 2168{ 2169 ThrowSyntaxError("Line break not permitted here"); 2170} 2171 2172void TSParser::ThrowIfBodyEmptyError(ir::Statement *consequent) 2173{ 2174 if (consequent->IsEmptyStatement()) { 2175 ThrowSyntaxError("The body of an if statement cannot be the empty statement"); 2176 } 2177} 2178 2179} // namespace ark::es2panda::parser 2180