1 /** 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "parserImpl.h" 17 18 #include <binder/scope.h> 19 #include <binder/tsBinding.h> 20 #include <util/helpers.h> 21 #include <ir/astDump.h> 22 #include <ir/astNode.h> 23 #include <ir/base/classDefinition.h> 24 #include <ir/base/classProperty.h> 25 #include <ir/base/decorator.h> 26 #include <ir/base/methodDefinition.h> 27 #include <ir/base/property.h> 28 #include <ir/base/scriptFunction.h> 29 #include <ir/base/spreadElement.h> 30 #include <ir/expression.h> 31 #include <ir/expressions/arrayExpression.h> 32 #include <ir/expressions/assignmentExpression.h> 33 #include <ir/expressions/callExpression.h> 34 #include <ir/expressions/functionExpression.h> 35 #include <ir/expressions/identifier.h> 36 #include <ir/expressions/literals/bigIntLiteral.h> 37 #include <ir/expressions/literals/booleanLiteral.h> 38 #include <ir/expressions/literals/nullLiteral.h> 39 #include <ir/expressions/literals/numberLiteral.h> 40 #include <ir/expressions/literals/stringLiteral.h> 41 #include <ir/expressions/memberExpression.h> 42 #include <ir/expressions/objectExpression.h> 43 #include <ir/expressions/superExpression.h> 44 #include <ir/module/exportDefaultDeclaration.h> 45 #include <ir/module/exportNamedDeclaration.h> 46 #include <ir/module/exportSpecifier.h> 47 #include <ir/statements/blockStatement.h> 48 #include <ir/statements/classDeclaration.h> 49 #include <ir/statements/emptyStatement.h> 50 #include <ir/statements/expressionStatement.h> 51 #include <ir/statements/functionDeclaration.h> 52 #include <ir/statements/variableDeclaration.h> 53 #include <ir/ts/tsAnyKeyword.h> 54 #include <ir/ts/tsArrayType.h> 55 #include <ir/ts/tsAsExpression.h> 56 #include <ir/ts/tsBigintKeyword.h> 57 #include <ir/ts/tsBooleanKeyword.h> 58 #include <ir/ts/tsClassImplements.h> 59 #include <ir/ts/tsConditionalType.h> 60 #include <ir/ts/tsConstructorType.h> 61 #include <ir/ts/tsEnumDeclaration.h> 62 #include <ir/ts/tsEnumMember.h> 63 #include <ir/ts/tsFunctionType.h> 64 #include <ir/ts/tsImportType.h> 65 #include <ir/ts/tsIndexSignature.h> 66 #include <ir/ts/tsIndexedAccessType.h> 67 #include <ir/ts/tsInferType.h> 68 #include <ir/ts/tsIntersectionType.h> 69 #include <ir/ts/tsLiteralType.h> 70 #include <ir/ts/tsMappedType.h> 71 #include <ir/ts/tsMethodSignature.h> 72 #include <ir/ts/tsModuleDeclaration.h> 73 #include <ir/ts/tsNamedTupleMember.h> 74 #include <ir/ts/tsNeverKeyword.h> 75 #include <ir/ts/tsNullKeyword.h> 76 #include <ir/ts/tsNumberKeyword.h> 77 #include <ir/ts/tsObjectKeyword.h> 78 #include <ir/ts/tsOptionalType.h> 79 #include <ir/ts/tsParameterProperty.h> 80 #include <ir/ts/tsParenthesizedType.h> 81 #include <ir/ts/tsPrivateIdentifier.h> 82 #include <ir/ts/tsPropertySignature.h> 83 #include <ir/ts/tsQualifiedName.h> 84 #include <ir/ts/tsRestType.h> 85 #include <ir/ts/tsSignatureDeclaration.h> 86 #include <ir/ts/tsStringKeyword.h> 87 #include <ir/ts/tsSymbolKeyword.h> 88 #include <ir/ts/tsTemplateLiteralType.h> 89 #include <ir/ts/tsThisType.h> 90 #include <ir/ts/tsTupleType.h> 91 #include <ir/ts/tsTypeAssertion.h> 92 #include <ir/ts/tsTypeLiteral.h> 93 #include <ir/ts/tsTypeOperator.h> 94 #include <ir/ts/tsTypeParameterDeclaration.h> 95 #include <ir/ts/tsTypeParameterInstantiation.h> 96 #include <ir/ts/tsTypePredicate.h> 97 #include <ir/ts/tsTypeQuery.h> 98 #include <ir/ts/tsTypeReference.h> 99 #include <ir/ts/tsUndefinedKeyword.h> 100 #include <ir/ts/tsUnionType.h> 101 #include <ir/ts/tsUnknownKeyword.h> 102 #include <ir/ts/tsVoidKeyword.h> 103 #include <lexer/lexer.h> 104 #include <lexer/token/letters.h> 105 #include <lexer/token/sourceLocation.h> 106 #include <mem/pool_manager.h> 107 108 namespace panda::es2panda::parser { 109 ParserImpl(ScriptExtension extension)110 ParserImpl::ParserImpl(ScriptExtension extension) : program_(extension), context_(&program_) {} 111 InitLexer(const std::string & fileName,const std::string & source)112 std::unique_ptr<lexer::Lexer> ParserImpl::InitLexer(const std::string &fileName, const std::string &source) 113 { 114 bool isDtsFile = false; 115 if (Extension() == ScriptExtension::TS) { 116 isDtsFile = util::Helpers::FileExtensionIs(fileName, ".d.ts"); 117 } 118 program_.SetSource(source, fileName, isDtsFile); 119 auto lexer = std::make_unique<lexer::Lexer>(&context_); 120 lexer_ = lexer.get(); 121 122 return lexer; 123 } 124 Parse(const std::string & fileName,const std::string & source,const std::string & recordName,ScriptKind kind)125 Program ParserImpl::Parse(const std::string &fileName, const std::string &source, 126 const std::string &recordName, ScriptKind kind) 127 { 128 program_.SetKind(kind); 129 program_.SetRecordName(recordName); 130 131 /* 132 * In order to make the lexer's memory alive, the return value 'lexer' can not be omitted. 133 */ 134 auto lexer = InitLexer(fileName, source); 135 switch (kind) { 136 case ScriptKind::SCRIPT: { 137 ParseScript(); 138 break; 139 } 140 case ScriptKind::MODULE: { 141 ParseModule(); 142 break; 143 } 144 case ScriptKind::COMMONJS: { 145 ParseCommonjs(); 146 break; 147 } 148 default: { 149 UNREACHABLE(); 150 } 151 } 152 binder::ResolveBindingFlags bindFlags = binder::ResolveBindingFlags::ALL; 153 if (Extension() == ScriptExtension::TS) { 154 bindFlags = binder::ResolveBindingFlags::TS_BEFORE_TRANSFORM; 155 } 156 Binder()->IdentifierAnalysis(bindFlags); 157 return std::move(program_); 158 } 159 ParseScript()160 void ParserImpl::ParseScript() 161 { 162 ParseProgram(ScriptKind::SCRIPT); 163 } 164 ParseModule()165 void ParserImpl::ParseModule() 166 { 167 context_.Status() |= (ParserStatus::MODULE); 168 ParseProgram(ScriptKind::MODULE); 169 } 170 ParseProgram(ScriptKind kind)171 void ParserImpl::ParseProgram(ScriptKind kind) 172 { 173 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 174 lexer_->NextToken(); 175 176 auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); 177 if (IsDtsFile() && !CheckTopStatementsForRequiredDeclare(statements)) { 178 ThrowSyntaxError( 179 "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier."); 180 } 181 182 auto *blockStmt = AllocNode<ir::BlockStatement>(Binder()->GetScope(), std::move(statements)); 183 Binder()->GetScope()->BindNode(blockStmt); 184 blockStmt->SetRange({startLoc, lexer_->GetToken().End()}); 185 186 program_.SetAst(blockStmt); 187 } 188 CheckTopStatementsForRequiredDeclare(const ArenaVector<ir::Statement * > & statements)189 bool ParserImpl::CheckTopStatementsForRequiredDeclare(const ArenaVector<ir::Statement *> &statements) 190 { 191 for (auto *statement : statements) { 192 switch (statement->Type()) { 193 case ir::AstNodeType::TS_INTERFACE_DECLARATION: 194 case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: 195 case ir::AstNodeType::IMPORT_DECLARATION: 196 case ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION: 197 case ir::AstNodeType::EXPORT_ALL_DECLARATION: 198 case ir::AstNodeType::EXPORT_DEFAULT_DECLARATION: 199 case ir::AstNodeType::EXPORT_NAMED_DECLARATION: 200 case ir::AstNodeType::TS_NAMESPACE_EXPORT_DECLARATION: 201 continue; 202 case ir::AstNodeType::CLASS_DECLARATION: { 203 if (!statement->AsClassDeclaration()->Definition()->Declare()) { 204 return false; 205 } 206 break; 207 } 208 case ir::AstNodeType::FUNCTION_DECLARATION: { 209 if (!statement->AsFunctionDeclaration()->Function()->Declare() && 210 !statement->AsFunctionDeclaration()->Function()->IsOverload()) { 211 return false; 212 } 213 break; 214 } 215 case ir::AstNodeType::VARIABLE_DECLARATION: { 216 if (!statement->AsVariableDeclaration()->Declare()) { 217 return false; 218 } 219 break; 220 } 221 case ir::AstNodeType::TS_MODULE_DECLARATION: { 222 if (!statement->AsTSModuleDeclaration()->Declare()) { 223 return false; 224 } 225 break; 226 } 227 case ir::AstNodeType::TS_ENUM_DECLARATION: { 228 if (!statement->AsTSEnumDeclaration()->IsDeclare()) { 229 return false; 230 } 231 break; 232 } 233 default: 234 ThrowSyntaxError("Statements are not allowed in ambient contexts."); 235 UNREACHABLE(); 236 } 237 } 238 return true; 239 } 240 241 /* 242 * Definitions of private methods 243 */ CarryExpressionParserFlag(ExpressionParseFlags origin,ExpressionParseFlags carry)244 ExpressionParseFlags ParserImpl::CarryExpressionParserFlag(ExpressionParseFlags origin, ExpressionParseFlags carry) 245 { 246 return static_cast<ExpressionParseFlags>(origin & carry); 247 } 248 CarryPatternFlags(ExpressionParseFlags flags)249 ExpressionParseFlags ParserImpl::CarryPatternFlags(ExpressionParseFlags flags) 250 { 251 return CarryExpressionParserFlag(flags, ExpressionParseFlags::POTENTIALLY_IN_PATTERN | 252 ExpressionParseFlags::OBJECT_PATTERN); 253 } 254 CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags)255 ExpressionParseFlags ParserImpl::CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags) 256 { 257 return CarryExpressionParserFlag(flags, ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN | 258 ExpressionParseFlags::POTENTIALLY_IN_PATTERN | 259 ExpressionParseFlags::OBJECT_PATTERN); 260 } 261 CurrentLiteralIsBasicType()262 bool ParserImpl::CurrentLiteralIsBasicType() 263 { 264 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 265 lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 266 267 switch (lexer_->GetToken().KeywordType()) { 268 case lexer::TokenType::KEYW_ANY: 269 case lexer::TokenType::KEYW_BOOLEAN: 270 case lexer::TokenType::KEYW_NUMBER: 271 case lexer::TokenType::KEYW_STRING: 272 case lexer::TokenType::KEYW_SYMBOL: 273 case lexer::TokenType::KEYW_UNKNOWN: 274 case lexer::TokenType::KEYW_UNDEFINED: 275 case lexer::TokenType::KEYW_NEVER: 276 case lexer::TokenType::KEYW_OBJECT: 277 case lexer::TokenType::KEYW_BIGINT: { 278 return true; 279 } 280 default: { 281 break; 282 } 283 } 284 285 return false; 286 } CurrentIsBasicType()287 bool ParserImpl::CurrentIsBasicType() 288 { 289 switch (lexer_->GetToken().Type()) { 290 case lexer::TokenType::PUNCTUATOR_MINUS: 291 case lexer::TokenType::LITERAL_NUMBER: 292 case lexer::TokenType::LITERAL_STRING: 293 case lexer::TokenType::LITERAL_FALSE: 294 case lexer::TokenType::LITERAL_TRUE: 295 case lexer::TokenType::LITERAL_NULL: 296 case lexer::TokenType::KEYW_VOID: { 297 return true; 298 } 299 case lexer::TokenType::LITERAL_IDENT: { 300 return CurrentLiteralIsBasicType(); 301 } 302 default: { 303 break; 304 } 305 } 306 307 return false; 308 } 309 ParseTsConstExpression()310 ir::TSTypeReference *ParserImpl::ParseTsConstExpression() 311 { 312 auto *identRef = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 313 identRef->SetReference(); 314 identRef->SetRange(lexer_->GetToken().Loc()); 315 316 auto *typeReference = AllocNode<ir::TSTypeReference>(identRef, nullptr); 317 typeReference->SetRange(lexer_->GetToken().Loc()); 318 319 lexer_->NextToken(); 320 321 return typeReference; 322 } 323 ParseTsIdentifierReference(TypeAnnotationParsingOptions options)324 ir::Expression *ParserImpl::ParseTsIdentifierReference(TypeAnnotationParsingOptions options) 325 { 326 if (CurrentLiteralIsBasicType() && lexer_->Lookahead() != LEX_CHAR_DOT) { 327 return ParseTsBasicType(options); 328 } 329 330 return ParseTsTypeReferenceOrQuery(options, false); 331 } 332 IsStartOfMappedType() const333 bool ParserImpl::IsStartOfMappedType() const 334 { 335 auto pos = lexer_->Save(); 336 lexer_->NextToken(); 337 bool result = false; 338 339 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 340 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 341 lexer_->NextToken(); 342 result = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY; 343 lexer_->Rewind(pos); 344 return result; 345 } 346 347 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 348 lexer_->NextToken(); 349 } 350 351 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 352 lexer_->Rewind(pos); 353 return false; 354 } 355 356 lexer_->NextToken(); 357 358 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 359 lexer_->Rewind(pos); 360 return false; 361 } 362 363 lexer_->NextToken(); 364 365 result = lexer_->GetToken().Type() == lexer::TokenType::KEYW_IN; 366 367 lexer_->Rewind(pos); 368 return result; 369 } 370 IsStartOfTsTypePredicate() const371 bool ParserImpl::IsStartOfTsTypePredicate() const 372 { 373 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 374 lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS); 375 376 auto pos = lexer_->Save(); 377 bool isAsserts = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 378 if (isAsserts) { 379 lexer_->NextToken(); 380 } 381 382 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && 383 lexer_->GetToken().Type() != lexer::TokenType::KEYW_THIS) { 384 lexer_->Rewind(pos); 385 return false; 386 } 387 388 if (isAsserts) { 389 lexer_->Rewind(pos); 390 return true; 391 } 392 393 lexer_->NextToken(); 394 395 bool result = !lexer_->GetToken().NewLine() && (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IS); 396 lexer_->Rewind(pos); 397 return result; 398 } 399 IsStartOfAbstractConstructorType() const400 bool ParserImpl::IsStartOfAbstractConstructorType() const 401 { 402 if (lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) { 403 return false; 404 } 405 406 lexer::LexerPosition pos = lexer_->Save(); 407 lexer_->NextToken(); // eat 'abstract' 408 bool result = lexer_->GetToken().Type() == lexer::TokenType::KEYW_NEW; 409 410 lexer_->Rewind(pos); 411 412 return result; 413 } 414 ParseTsTypeLiteralOrTsMappedType(ir::Expression * typeAnnotation)415 ir::Expression *ParserImpl::ParseTsTypeLiteralOrTsMappedType(ir::Expression *typeAnnotation) 416 { 417 if (typeAnnotation) { 418 return nullptr; 419 } 420 421 if (IsStartOfMappedType()) { 422 return ParseTsMappedType(); 423 } 424 425 lexer::SourcePosition bodyStart = lexer_->GetToken().Start(); 426 auto members = ParseTsTypeLiteralOrInterface(); 427 lexer::SourcePosition bodyEnd = lexer_->GetToken().End(); 428 lexer_->NextToken(); 429 430 auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members)); 431 auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, literalType); 432 literalType->SetVariable(typeVar); 433 literalType->SetRange({bodyStart, bodyEnd}); 434 return literalType; 435 } 436 ParseTsTypeReferenceOrTsTypePredicate(ir::Expression * typeAnnotation,bool canBeTsTypePredicate,bool throwError)437 ir::Expression *ParserImpl::ParseTsTypeReferenceOrTsTypePredicate(ir::Expression *typeAnnotation, 438 bool canBeTsTypePredicate, bool throwError) 439 { 440 if (typeAnnotation) { 441 return nullptr; 442 } 443 444 if (canBeTsTypePredicate && IsStartOfTsTypePredicate()) { 445 return ParseTsTypePredicate(); 446 } 447 448 return ParseTsTypeOperatorOrTypeReference(throwError); 449 } 450 ParseTsThisTypeOrTsTypePredicate(ir::Expression * typeAnnotation,bool canBeTsTypePredicate,bool throwError)451 ir::Expression *ParserImpl::ParseTsThisTypeOrTsTypePredicate(ir::Expression *typeAnnotation, bool canBeTsTypePredicate, 452 bool throwError) 453 { 454 if (typeAnnotation) { 455 return nullptr; 456 } 457 458 if (canBeTsTypePredicate && IsStartOfTsTypePredicate()) { 459 return ParseTsTypePredicate(); 460 } 461 462 return ParseTsThisType(throwError); 463 } 464 ParseTsTemplateLiteralType(bool throwError)465 ir::Expression *ParserImpl::ParseTsTemplateLiteralType(bool throwError) 466 { 467 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK); 468 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 469 470 ArenaVector<ir::TemplateElement *> quasis(Allocator()->Adapter()); 471 ArenaVector<ir::Expression *> references(Allocator()->Adapter()); 472 473 while (true) { 474 lexer_->ResetTokenEnd(); 475 const auto startPos = lexer_->Save(); 476 477 lexer_->ScanString<LEX_CHAR_BACK_TICK>(); 478 util::StringView cooked = lexer_->GetToken().String(); 479 480 lexer_->Rewind(startPos); 481 auto [raw, end, scanExpression] = lexer_->ScanTemplateString(); 482 483 auto *element = AllocNode<ir::TemplateElement>(raw.View(), cooked); 484 element->SetRange({lexer::SourcePosition{startPos.iterator.Index(), startPos.line}, 485 lexer::SourcePosition{end, lexer_->Line()}}); 486 quasis.push_back(element); 487 488 if (!scanExpression) { 489 lexer_->ScanTemplateStringEnd(); 490 break; 491 } 492 493 ir::Expression *reference = nullptr; 494 495 { 496 lexer::TemplateLiteralParserContext ctx(lexer_); 497 lexer_->PushTemplateContext(&ctx); 498 lexer_->NextToken(); 499 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 500 reference = ParseTsTypeAnnotation(&options); 501 } 502 503 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 504 if (throwError) { 505 ThrowSyntaxError("Unexpected token, expected '}'."); 506 } 507 return nullptr; 508 } 509 510 references.push_back(reference); 511 } 512 513 ir::Expression *typeAnnotation = AllocNode<ir::TSTemplateLiteralType>(std::move(quasis), std::move(references)); 514 typeAnnotation->SetRange({startLoc, lexer_->GetToken().End()}); 515 516 lexer_->NextToken(); 517 518 return typeAnnotation; 519 } 520 ParseTsTypeAnnotationElement(ir::Expression * typeAnnotation,TypeAnnotationParsingOptions * options)521 ir::Expression *ParserImpl::ParseTsTypeAnnotationElement(ir::Expression *typeAnnotation, 522 TypeAnnotationParsingOptions *options) 523 { 524 switch (lexer_->GetToken().Type()) { 525 case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { 526 if (*options & (TypeAnnotationParsingOptions::IN_MODIFIER | TypeAnnotationParsingOptions::IN_UNION | 527 TypeAnnotationParsingOptions::IN_INTERSECTION)) { 528 break; 529 } 530 531 return ParseTsUnionType(typeAnnotation, *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS); 532 } 533 case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { 534 if (*options & (TypeAnnotationParsingOptions::IN_MODIFIER | 535 TypeAnnotationParsingOptions::IN_INTERSECTION)) { 536 break; 537 } 538 539 return ParseTsIntersectionType(typeAnnotation, *options & TypeAnnotationParsingOptions::IN_UNION, 540 *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS); 541 } 542 case lexer::TokenType::PUNCTUATOR_LESS_THAN: 543 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: 544 case lexer::TokenType::KEYW_NEW: { 545 return ParseTsParenthesizedOrFunctionType(typeAnnotation, 546 *options & TypeAnnotationParsingOptions::THROW_ERROR); 547 } 548 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 549 if (typeAnnotation) { 550 if (lexer_->GetToken().NewLine()) { 551 break; 552 } 553 if (lexer_->Lookahead() == LEX_CHAR_RIGHT_SQUARE) { 554 return ParseTsArrayType(typeAnnotation); 555 } 556 557 return ParseTsIndexAccessType(typeAnnotation, *options & TypeAnnotationParsingOptions::THROW_ERROR); 558 } 559 560 return ParseTsTupleType(); 561 } 562 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 563 return ParseTsTypeLiteralOrTsMappedType(typeAnnotation); 564 } 565 case lexer::TokenType::PUNCTUATOR_MINUS: 566 case lexer::TokenType::LITERAL_NUMBER: 567 case lexer::TokenType::LITERAL_STRING: 568 case lexer::TokenType::LITERAL_FALSE: 569 case lexer::TokenType::LITERAL_TRUE: 570 case lexer::TokenType::LITERAL_NULL: 571 case lexer::TokenType::KEYW_VOID: { 572 if (typeAnnotation) { 573 break; 574 } 575 576 return ParseTsBasicType(*options); 577 } 578 case lexer::TokenType::KEYW_TYPEOF: { 579 if (typeAnnotation) { 580 break; 581 } 582 583 return ParseTsTypeReferenceOrQuery(*options, true); 584 } 585 case lexer::TokenType::KEYW_IMPORT: { 586 if (typeAnnotation) { 587 break; 588 } 589 590 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 591 return ParseTsImportType(startLoc); 592 } 593 case lexer::TokenType::KEYW_CONST: { 594 if (!(*options & TypeAnnotationParsingOptions::ALLOW_CONST)) { 595 break; 596 } 597 598 *options &= ~TypeAnnotationParsingOptions::ALLOW_CONST; 599 return ParseTsConstExpression(); 600 } 601 case lexer::TokenType::LITERAL_IDENT: { 602 if (IsStartOfAbstractConstructorType()) { 603 return ParseTsParenthesizedOrFunctionType(typeAnnotation, 604 *options & TypeAnnotationParsingOptions::THROW_ERROR); 605 } 606 607 return ParseTsTypeReferenceOrTsTypePredicate( 608 typeAnnotation, *options & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE, 609 *options & TypeAnnotationParsingOptions::THROW_ERROR); 610 } 611 case lexer::TokenType::KEYW_EXTENDS: { 612 if (*options & (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) { 613 break; 614 } 615 616 if (!typeAnnotation) { 617 return ParseTsIdentifierReference(*options); 618 } 619 620 return ParseTsConditionalType(typeAnnotation, *options & TypeAnnotationParsingOptions::RESTRICT_EXTENDS); 621 } 622 case lexer::TokenType::KEYW_THIS: { 623 return ParseTsThisTypeOrTsTypePredicate(typeAnnotation, 624 *options & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE, 625 *options & TypeAnnotationParsingOptions::THROW_ERROR); 626 } 627 case lexer::TokenType::PUNCTUATOR_BACK_TICK: { 628 return ParseTsTemplateLiteralType(*options & TypeAnnotationParsingOptions::THROW_ERROR); 629 } 630 default: { 631 break; 632 } 633 } 634 635 if (!typeAnnotation && (*options & TypeAnnotationParsingOptions::THROW_ERROR)) { 636 ThrowSyntaxError("Type expected"); 637 } 638 639 return nullptr; 640 } 641 ParseTsImportType(const lexer::SourcePosition & startLoc,bool isTypeof)642 ir::TSImportType *ParserImpl::ParseTsImportType(const lexer::SourcePosition &startLoc, bool isTypeof) 643 { 644 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_IMPORT); 645 646 lexer_->NextToken(); 647 648 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 649 ThrowSyntaxError("'(' expected"); 650 } 651 652 lexer_->NextToken(); 653 654 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 655 ir::Expression *param = ParseTsTypeAnnotation(&options); 656 657 if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) { 658 ThrowSyntaxError("String literal expected"); 659 } 660 661 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 662 ThrowSyntaxError("')' expected"); 663 } 664 665 lexer_->NextToken(); 666 667 ir::Expression *qualifier = nullptr; 668 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 669 lexer_->NextToken(); 670 671 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 672 ThrowSyntaxError("Identifier expected"); 673 } 674 675 qualifier = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 676 qualifier->SetRange(lexer_->GetToken().Loc()); 677 678 lexer_->NextToken(); 679 680 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 681 qualifier = ParseTsQualifiedReference(qualifier); 682 } 683 } 684 685 ir::TSTypeParameterInstantiation *typeParams = nullptr; 686 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || 687 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 688 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 689 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 690 } 691 692 typeParams = ParseTsTypeParameterInstantiation(); 693 } 694 695 auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof); 696 697 importType->SetRange({startLoc, lexer_->GetToken().End()}); 698 699 return importType; 700 } 701 ParseTsThisType(bool throwError)702 ir::Expression *ParserImpl::ParseTsThisType(bool throwError) 703 { 704 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS); 705 706 if (throwError && !(context_.Status() & ParserStatus::ALLOW_THIS_TYPE)) { 707 ThrowSyntaxError( 708 "A 'this' type is available only in a non-static member " 709 "of a class or interface."); 710 } 711 712 auto *returnType = AllocNode<ir::TSThisType>(); 713 returnType->SetRange(lexer_->GetToken().Loc()); 714 715 lexer_->NextToken(); 716 717 return returnType; 718 } 719 ParseTsConditionalType(ir::Expression * checkType,bool restrictExtends)720 ir::Expression *ParserImpl::ParseTsConditionalType(ir::Expression *checkType, bool restrictExtends) 721 { 722 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 723 if (restrictExtends) { 724 ThrowSyntaxError("'?' expected."); 725 } 726 727 lexer::SourcePosition startLoc = checkType->Start(); 728 729 lexer_->NextToken(); // eat 'extends' 730 731 ParserStatus savedStatus = context_.Status(); 732 context_.Status() |= ParserStatus::IN_EXTENDS; 733 734 TypeAnnotationParsingOptions options = 735 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 736 auto *extendsType = ParseTsTypeAnnotation(&options); 737 738 context_.Status() = savedStatus; 739 740 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 741 ThrowSyntaxError("'?' expected."); 742 } 743 744 lexer_->NextToken(); // eat '?' 745 746 options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 747 auto *trueType = ParseTsTypeAnnotation(&options); 748 749 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 750 ThrowSyntaxError("':' expected."); 751 } 752 753 lexer_->NextToken(); // eat ':' 754 755 auto *falseType = ParseTsTypeAnnotation(&options); 756 757 lexer::SourcePosition endLoc = falseType->End(); 758 759 auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType); 760 761 conditionalType->SetRange({startLoc, endLoc}); 762 763 return conditionalType; 764 } 765 ParseTsTypeAnnotation(TypeAnnotationParsingOptions * options)766 ir::Expression *ParserImpl::ParseTsTypeAnnotation(TypeAnnotationParsingOptions *options) 767 { 768 ir::Expression *typeAnnotation = nullptr; 769 770 while (true) { 771 ir::Expression *element = ParseTsTypeAnnotationElement(typeAnnotation, options); 772 773 *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 774 775 if (!element) { 776 break; 777 } 778 779 typeAnnotation = element; 780 781 if ((*options & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) && lexer_->GetToken().NewLine()) { 782 break; 783 } 784 } 785 786 return typeAnnotation; 787 } 788 ParseTsTypeOperatorOrTypeReference(bool throwError)789 ir::Expression *ParserImpl::ParseTsTypeOperatorOrTypeReference(bool throwError) 790 { 791 TypeAnnotationParsingOptions options = throwError ? 792 TypeAnnotationParsingOptions::THROW_ERROR : TypeAnnotationParsingOptions::NO_OPTS; 793 794 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 795 lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start(); 796 lexer_->NextToken(); 797 798 options |= TypeAnnotationParsingOptions::IN_MODIFIER; 799 ir::Expression *type = ParseTsTypeAnnotation(&options); 800 ASSERT(type != nullptr); 801 802 if (!type->IsTSArrayType() && !type->IsTSTupleType()) { 803 ThrowSyntaxError( 804 "'readonly' type modifier is only permitted on array " 805 "and tuple literal types."); 806 } 807 808 auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY); 809 810 typeOperator->SetRange({typeOperatorStart, type->End()}); 811 812 return typeOperator; 813 } 814 815 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) { 816 lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start(); 817 lexer_->NextToken(); 818 819 options |= TypeAnnotationParsingOptions::IN_MODIFIER; 820 ir::Expression *type = ParseTsTypeAnnotation(&options); 821 ASSERT(type != nullptr); 822 823 auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF); 824 825 typeOperator->SetRange({typeOperatorStart, type->End()}); 826 827 return typeOperator; 828 } 829 830 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNIQUE) { 831 lexer::SourcePosition typeOperatorStart = lexer_->GetToken().Start(); 832 lexer_->NextToken(); 833 834 ir::Expression *type = ParseTsTypeAnnotation(&options); 835 ASSERT(type != nullptr); 836 837 auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::UNIQUE); 838 839 typeOperator->SetRange({typeOperatorStart, type->End()}); 840 841 return typeOperator; 842 } 843 844 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) { 845 if (!(context_.Status() & ParserStatus::IN_EXTENDS)) { 846 ThrowSyntaxError( 847 "'infer' declarations are only permitted in the " 848 "'extends' clause of a conditional type."); 849 } 850 851 lexer::SourcePosition inferStart = lexer_->GetToken().Start(); 852 lexer_->NextToken(); 853 854 ir::TSTypeParameter *typeParam = ParseTsTypeParameter(true); 855 856 auto *inferType = AllocNode<ir::TSInferType>(typeParam); 857 858 inferType->SetRange({inferStart, lexer_->GetToken().End()}); 859 860 return inferType; 861 } 862 863 return ParseTsIdentifierReference(options); 864 } 865 IsTSNamedTupleMember()866 bool ParserImpl::IsTSNamedTupleMember() 867 { 868 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 869 return false; 870 } 871 const auto savePos = lexer_->Save(); 872 bool isNamedMember = false; 873 lexer_->NextToken(); 874 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON || 875 (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK && 876 lexer_->Lookahead() == LEX_CHAR_COLON)) { 877 isNamedMember = true; 878 } 879 lexer_->Rewind(savePos); 880 return isNamedMember; 881 } 882 HandleRestType(ir::AstNodeType elementType,bool * hasRestType) const883 void ParserImpl::HandleRestType(ir::AstNodeType elementType, bool *hasRestType) const 884 { 885 if (elementType == ir::AstNodeType::TS_ARRAY_TYPE && *hasRestType) { 886 ThrowSyntaxError("A rest element cannot follow another rest element"); 887 } 888 *hasRestType = true; 889 } 890 ParseTsTupleElement(ir::TSTupleKind * kind,bool * seenOptional,bool * hasRestType)891 ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional, bool *hasRestType) 892 { 893 lexer::SourcePosition startPos = lexer_->GetToken().Start(); 894 ir::Expression *element = nullptr; 895 bool isRestType = false; 896 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 897 898 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 899 isRestType = true; 900 lexer_->NextToken(); // eat '...' 901 } 902 903 if (IsTSNamedTupleMember()) { 904 if (*kind == ir::TSTupleKind::DEFAULT) { 905 ThrowSyntaxError("Tuple members must all have or haven't names"); 906 } 907 *kind = ir::TSTupleKind::NAMED; 908 909 auto *elementIdent = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 910 elementIdent->SetRange(lexer_->GetToken().Loc()); 911 lexer_->NextToken(); // eat identifier 912 913 bool isOptional = false; 914 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 915 lexer_->NextToken(); // eat '?' 916 isOptional = true; 917 *seenOptional = true; 918 } else if (*seenOptional && !isRestType) { 919 ThrowSyntaxError("A required element cannot follow an optional element"); 920 } 921 922 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 923 ThrowSyntaxError("':' expected"); 924 } 925 926 lexer_->NextToken(); // eat ':' 927 auto *elementType = ParseTsTypeAnnotation(&options); 928 ASSERT(elementType != nullptr); 929 930 if (elementType && isRestType) { 931 HandleRestType(elementType->Type(), hasRestType); 932 } 933 934 element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional, isRestType); 935 element->SetRange({startPos, elementType->End()}); 936 } else { 937 if (*kind == ir::TSTupleKind::NAMED) { 938 ThrowSyntaxError("Tuple members must all have or haven't names"); 939 } 940 *kind = ir::TSTupleKind::DEFAULT; 941 942 element = ParseTsTypeAnnotation(&options); 943 ASSERT(element != nullptr); 944 if (element && isRestType) { 945 HandleRestType(element->Type(), hasRestType); 946 lexer::SourcePosition endPos = element->End(); 947 element = AllocNode<ir::TSRestType>(std::move(element)); 948 element->SetRange({startPos, endPos}); 949 } 950 951 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 952 lexer::SourcePosition elementStartPos = element->Start(); 953 element = AllocNode<ir::TSOptionalType>(std::move(element)); 954 element->SetRange({elementStartPos, lexer_->GetToken().End()}); 955 lexer_->NextToken(); // eat '?' 956 *seenOptional = true; 957 } else if (*seenOptional && !isRestType) { 958 ThrowSyntaxError("A required element cannot follow an optional element"); 959 } 960 } 961 return element; 962 } 963 ParseTsTupleType()964 ir::TSTupleType *ParserImpl::ParseTsTupleType() 965 { 966 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 967 lexer::SourcePosition tupleStart = lexer_->GetToken().Start(); 968 ArenaVector<ir::Expression *> elements(Allocator()->Adapter()); 969 ir::TSTupleKind kind = ir::TSTupleKind::NONE; 970 bool seenOptional = false; 971 bool hasRestType = false; 972 973 lexer_->NextToken(); // eat '[' 974 975 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 976 ir::Expression *element = ParseTsTupleElement(&kind, &seenOptional, &hasRestType); 977 978 elements.push_back(element); 979 980 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 981 break; 982 } 983 984 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) { 985 ThrowSyntaxError("',' expected."); 986 } 987 988 lexer_->NextToken(); // eat ',' 989 } 990 991 lexer::SourcePosition tupleEnd = lexer_->GetToken().End(); 992 lexer_->NextToken(); // eat ']' 993 994 auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements)); 995 tupleType->SetRange({tupleStart, tupleEnd}); 996 return tupleType; 997 } 998 ParseTsQualifiedReference(ir::Expression * typeName)999 ir::Expression *ParserImpl::ParseTsQualifiedReference(ir::Expression *typeName) 1000 { 1001 lexer::SourcePosition startLoc = typeName->Start(); 1002 1003 do { 1004 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); // eat '.' 1005 1006 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 1007 ThrowSyntaxError("Identifier expected"); 1008 } 1009 1010 auto *propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1011 propName->SetRange(lexer_->GetToken().Loc()); 1012 1013 typeName = AllocNode<ir::TSQualifiedName>(typeName, propName); 1014 typeName->SetRange({typeName->AsTSQualifiedName()->Left()->Start(), lexer_->GetToken().End()}); 1015 1016 lexer_->NextToken(); 1017 } while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD); 1018 1019 typeName->SetRange({startLoc, lexer_->GetToken().End()}); 1020 1021 return typeName; 1022 } 1023 ParseTsIndexAccessType(ir::Expression * typeName,bool throwError)1024 ir::Expression *ParserImpl::ParseTsIndexAccessType(ir::Expression *typeName, bool throwError) 1025 { 1026 TypeAnnotationParsingOptions options = throwError ? 1027 TypeAnnotationParsingOptions::THROW_ERROR : TypeAnnotationParsingOptions::NO_OPTS; 1028 1029 do { 1030 lexer_->NextToken(); // eat '[' 1031 1032 ir::Expression *indexType = ParseTsTypeAnnotation(&options); 1033 1034 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1035 if (!throwError) { 1036 return nullptr; 1037 } 1038 ThrowSyntaxError("']' expected"); 1039 } 1040 1041 lexer_->NextToken(); // eat ']' 1042 1043 typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType); 1044 typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), lexer_->GetToken().End()}); 1045 } while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 1046 lexer_->Lookahead() != LEX_CHAR_RIGHT_SQUARE); 1047 1048 return typeName; 1049 } 1050 ParseTsTypeReferenceOrQuery(TypeAnnotationParsingOptions options,bool parseQuery)1051 ir::Expression *ParserImpl::ParseTsTypeReferenceOrQuery(TypeAnnotationParsingOptions options, bool parseQuery) 1052 { 1053 lexer::SourcePosition referenceStartLoc = lexer_->GetToken().Start(); 1054 1055 if (parseQuery) { 1056 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF); 1057 lexer_->NextToken(); // eat 'typeof' 1058 1059 if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) { 1060 lexer::SourcePosition &startLoc = referenceStartLoc; 1061 return ParseTsImportType(startLoc, true); 1062 } 1063 1064 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 1065 ThrowSyntaxError("Identifier expected."); 1066 } 1067 } 1068 1069 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 1070 lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 1071 1072 ir::Expression *typeName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1073 typeName->SetRange(lexer_->GetToken().Loc()); 1074 typeName->AsIdentifier()->SetReference(); 1075 1076 if (lexer_->Lookahead() == LEX_CHAR_LESS_THAN) { 1077 lexer_->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 1078 } else { 1079 lexer_->NextToken(); 1080 } 1081 1082 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 1083 typeName = ParseTsQualifiedReference(typeName); 1084 } 1085 1086 ir::TSTypeParameterInstantiation *typeParamInst = nullptr; 1087 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1088 if (parseQuery) { 1089 ThrowSyntaxError("Unexpected token."); 1090 } 1091 1092 typeParamInst = ParseTsTypeParameterInstantiation(options & TypeAnnotationParsingOptions::THROW_ERROR); 1093 } 1094 1095 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 1096 lexer_->Lookahead() != LEX_CHAR_RIGHT_SQUARE) { 1097 if (parseQuery) { 1098 typeName = AllocNode<ir::TSTypeQuery>(typeName); 1099 } else { 1100 typeName = AllocNode<ir::TSTypeReference>(typeName, typeParamInst); 1101 } 1102 1103 typeName->SetRange({referenceStartLoc, lexer_->GetToken().End()}); 1104 1105 return ParseTsIndexAccessType(typeName, options & TypeAnnotationParsingOptions::THROW_ERROR); 1106 } 1107 1108 ir::Expression *returnNode = nullptr; 1109 1110 lexer::SourcePosition referenceEndLoc = typeName->End(); 1111 1112 if (parseQuery) { 1113 returnNode = AllocNode<ir::TSTypeQuery>(typeName); 1114 } else { 1115 returnNode = AllocNode<ir::TSTypeReference>(typeName, typeParamInst); 1116 } 1117 1118 returnNode->SetRange({referenceStartLoc, referenceEndLoc}); 1119 1120 return returnNode; 1121 } 1122 ParseTsMappedTypeParameter()1123 ir::TSTypeParameter *ParserImpl::ParseTsMappedTypeParameter() 1124 { 1125 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 1126 1127 auto *paramName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1128 paramName->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()}); 1129 1130 lexer_->NextToken(); 1131 1132 lexer_->NextToken(); // eat 'in' 1133 1134 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 1135 ir::Expression *constraint = ParseTsTypeAnnotation(&options); 1136 1137 lexer::SourcePosition endLoc = constraint->End(); 1138 1139 auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr); 1140 1141 typeParameter->SetRange({startLoc, endLoc}); 1142 1143 return typeParameter; 1144 } 1145 ParseMappedOption(lexer::TokenType tokenType)1146 ir::MappedOption ParserImpl::ParseMappedOption(lexer::TokenType tokenType) 1147 { 1148 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS && 1149 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS && 1150 lexer_->GetToken().KeywordType() != tokenType && lexer_->GetToken().Type() != tokenType) { 1151 return ir::MappedOption::NO_OPTS; 1152 } 1153 1154 auto result = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS 1155 : ir::MappedOption::PLUS; 1156 1157 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 1158 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 1159 lexer_->NextToken(); 1160 } 1161 1162 if (lexer_->GetToken().KeywordType() != tokenType && lexer_->GetToken().Type() != tokenType) { 1163 ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."}); 1164 } 1165 1166 lexer_->NextToken(); 1167 1168 return result; 1169 } 1170 ParseTsMappedType()1171 ir::TSMappedType *ParserImpl::ParseTsMappedType() 1172 { 1173 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); 1174 1175 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 1176 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); // eat '{' 1177 1178 ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY); 1179 1180 lexer_->NextToken(); // eat '[' 1181 1182 ir::TSTypeParameter *typeParameter = ParseTsMappedTypeParameter(); 1183 1184 ir::Expression *nameKeyType = nullptr; 1185 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) { 1186 lexer_->NextToken(); // eat 'as' 1187 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 1188 nameKeyType = ParseTsTypeAnnotation(&options); 1189 ASSERT(nameKeyType != nullptr); 1190 } 1191 1192 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1193 ThrowSyntaxError("']' expected"); 1194 } 1195 1196 lexer_->NextToken(); // eat ']' 1197 1198 ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK); 1199 1200 ir::Expression *typeAnnotation = nullptr; 1201 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1202 lexer_->NextToken(); // eat ':' 1203 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 1204 typeAnnotation = ParseTsTypeAnnotation(&options); 1205 } 1206 1207 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 1208 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 1209 ThrowSyntaxError("';' expected"); 1210 } 1211 1212 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 1213 lexer_->NextToken(); // eat ';' 1214 } 1215 1216 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 1217 ThrowSyntaxError("'}' expected"); 1218 } 1219 1220 auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, nameKeyType, typeAnnotation, readonly, optional); 1221 1222 mappedType->SetRange({startLoc, lexer_->GetToken().End()}); 1223 1224 lexer_->NextToken(); // eat '}' 1225 1226 return mappedType; 1227 } 1228 ParseTsTypePredicate()1229 ir::TSTypePredicate *ParserImpl::ParseTsTypePredicate() 1230 { 1231 auto pos = lexer_->Save(); 1232 lexer::SourcePosition startPos = lexer_->GetToken().Start(); 1233 bool isAsserts = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 1234 if (isAsserts) { 1235 lexer_->NextToken(); // eat 'asserts' 1236 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) { 1237 isAsserts = false; 1238 lexer_->Rewind(pos); 1239 } 1240 } 1241 1242 ir::Expression *parameterName = nullptr; 1243 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 1244 parameterName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1245 } else { 1246 parameterName = AllocNode<ir::TSThisType>(); 1247 } 1248 1249 parameterName->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()}); 1250 1251 lexer_->NextToken(); 1252 1253 ir::Expression *typeAnnotation = nullptr; 1254 lexer::SourcePosition endPos; 1255 ir::TSTypePredicate *result = nullptr; 1256 1257 if (isAsserts && lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) { 1258 endPos = parameterName->End(); 1259 result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 1260 result->SetRange({startPos, endPos}); 1261 return result; 1262 } 1263 1264 lexer_->NextToken(); // eat 'is' 1265 1266 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 1267 typeAnnotation = ParseTsTypeAnnotation(&options); 1268 endPos = typeAnnotation->End(); 1269 1270 result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 1271 1272 result->SetRange({startPos, endPos}); 1273 1274 return result; 1275 } 1276 ParseTsTypeLiteralOrInterfaceKey(bool * computed,bool * signature,bool * isIndexSignature)1277 ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceKey(bool *computed, bool *signature, bool *isIndexSignature) 1278 { 1279 ir::Expression *key = nullptr; 1280 1281 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && 1282 (lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_NEW || 1283 (lexer_->Lookahead() != LEX_CHAR_LEFT_PAREN && lexer_->Lookahead() != LEX_CHAR_LESS_THAN))) { 1284 key = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1285 key->SetRange(lexer_->GetToken().Loc()); 1286 lexer_->NextToken(); 1287 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER) { 1288 if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) { 1289 key = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt()); 1290 } else { 1291 key = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String()); 1292 } 1293 1294 key->SetRange(lexer_->GetToken().Loc()); 1295 lexer_->NextToken(); 1296 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { 1297 key = AllocNode<ir::StringLiteral>(lexer_->GetToken().String()); 1298 key->SetRange(lexer_->GetToken().Loc()); 1299 lexer_->NextToken(); 1300 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 1301 *computed = true; 1302 lexer_->NextToken(); // eat '[' 1303 1304 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && lexer_->Lookahead() == LEX_CHAR_COLON) { 1305 *isIndexSignature = true; 1306 key = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 1307 key->SetRange(lexer_->GetToken().Loc()); 1308 1309 lexer_->NextToken(); // eat param 1310 1311 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 1312 ThrowSyntaxError("':' expected"); 1313 } 1314 1315 lexer_->NextToken(); // eat ':' 1316 1317 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 1318 ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options); 1319 1320 if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { 1321 ThrowSyntaxError( 1322 "An index signature parameter type must be either " 1323 "'string' or 'number'"); 1324 } 1325 1326 key->SetTsTypeAnnotation(typeAnnotation); 1327 } else { 1328 key = ParseExpression(); 1329 } 1330 1331 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1332 ThrowSyntaxError("']' expected"); 1333 } 1334 1335 lexer_->NextToken(); // eat ']' 1336 } else if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 1337 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN && 1338 lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_NEW) { 1339 ThrowSyntaxError("Unexpected token"); 1340 } else { 1341 *signature = true; 1342 } 1343 1344 return key; 1345 } 1346 CreateTSVariableForProperty(ir::AstNode * node,const ir::Expression * key,binder::VariableFlags flags)1347 void ParserImpl::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, binder::VariableFlags flags) 1348 { 1349 binder::Variable *propVar = nullptr; 1350 bool isMethod = flags & binder::VariableFlags::METHOD; 1351 util::StringView propName = "__computed"; 1352 1353 switch (key->Type()) { 1354 case ir::AstNodeType::IDENTIFIER: { 1355 propName = key->AsIdentifier()->Name(); 1356 break; 1357 } 1358 case ir::AstNodeType::NUMBER_LITERAL: { 1359 propName = key->AsNumberLiteral()->Str(); 1360 flags |= binder::VariableFlags::NUMERIC_NAME; 1361 break; 1362 } 1363 case ir::AstNodeType::STRING_LITERAL: { 1364 propName = key->AsStringLiteral()->Str(); 1365 break; 1366 } 1367 default: { 1368 flags |= binder::VariableFlags::COMPUTED; 1369 break; 1370 } 1371 } 1372 1373 propVar = isMethod ? binder::Scope::CreateVar<binder::MethodDecl>(Allocator(), propName, flags, node) 1374 : binder::Scope::CreateVar<binder::PropertyDecl>(Allocator(), propName, flags, node); 1375 1376 node->SetVariable(propVar); 1377 } 1378 ParseTsTypeLiteralOrInterfaceMember()1379 ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceMember() 1380 { 1381 bool computed = false; 1382 bool optional = false; 1383 bool signature = false; 1384 bool readonly = false; 1385 bool isConstructSignature = false; 1386 bool isIndexSignature = false; 1387 lexer::SourcePosition memberStartLoc = lexer_->GetToken().Start(); 1388 char32_t nextToken = lexer_->Lookahead(); 1389 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY && nextToken != LEX_CHAR_LEFT_PAREN && 1390 nextToken != LEX_CHAR_COLON && nextToken != LEX_CHAR_COMMA && nextToken != LEX_CHAR_LESS_THAN && 1391 nextToken != LEX_CHAR_SEMICOLON) { 1392 readonly = true; 1393 lexer_->NextToken(); 1394 } 1395 1396 ir::Expression *key = ParseTsTypeLiteralOrInterfaceKey(&computed, &signature, &isIndexSignature); 1397 1398 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 1399 if (isIndexSignature) { 1400 ThrowSyntaxError("';' expected"); 1401 } 1402 1403 optional = true; 1404 lexer_->NextToken(); // eat '?' 1405 } 1406 1407 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW && signature) { 1408 lexer_->NextToken(); // eat 'new' 1409 1410 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 1411 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1412 ThrowSyntaxError("'(' expected"); 1413 } 1414 1415 isConstructSignature = true; 1416 } 1417 1418 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 1419 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1420 if (isIndexSignature) { 1421 ThrowSyntaxError("';' expected"); 1422 } 1423 1424 typeParamDecl = ParseTsTypeParameterDeclaration(); 1425 1426 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1427 ThrowSyntaxError("'(' expected"); 1428 } 1429 } 1430 1431 ir::Expression *member = nullptr; 1432 ir::Expression *typeAnnotation = nullptr; 1433 binder::VariableFlags flags = binder::VariableFlags::NONE; 1434 1435 if (optional) { 1436 flags |= binder::VariableFlags::OPTIONAL; 1437 } 1438 1439 if (readonly) { 1440 flags |= binder::VariableFlags::READONLY; 1441 } 1442 1443 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && !isIndexSignature) { 1444 FunctionParameterContext funcParamContext(&context_, Binder()); 1445 auto *funcParamScope = funcParamContext.LexicalScope().GetScope(); 1446 ArenaVector<ir::Expression *> params = ParseFunctionParams(true); 1447 1448 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1449 lexer_->NextToken(); // eat ':' 1450 TypeAnnotationParsingOptions options = 1451 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 1452 typeAnnotation = ParseTsTypeAnnotation(&options); 1453 } 1454 1455 if (signature) { 1456 auto kind = isConstructSignature 1457 ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE 1458 : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE; 1459 member = AllocNode<ir::TSSignatureDeclaration>(funcParamScope, kind, typeParamDecl, std::move(params), 1460 typeAnnotation); 1461 funcParamScope->BindNode(member); 1462 } else { 1463 member = AllocNode<ir::TSMethodSignature>(funcParamScope, key, typeParamDecl, std::move(params), 1464 typeAnnotation, computed, optional); 1465 funcParamScope->BindNode(member); 1466 CreateTSVariableForProperty(member, key, flags | binder::VariableFlags::METHOD); 1467 } 1468 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 1469 lexer_->NextToken(); // eat ':' 1470 TypeAnnotationParsingOptions options = 1471 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 1472 typeAnnotation = ParseTsTypeAnnotation(&options); 1473 } else if (isIndexSignature) { 1474 ThrowSyntaxError("An index signature must have a type annotation.", memberStartLoc); 1475 } 1476 1477 if (!member && isIndexSignature) { 1478 member = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, readonly); 1479 } else if (!member) { 1480 member = AllocNode<ir::TSPropertySignature>(key, typeAnnotation, computed, optional, readonly); 1481 CreateTSVariableForProperty(member, key, flags | binder::VariableFlags::PROPERTY); 1482 } else if (readonly) { 1483 ThrowSyntaxError( 1484 "'readonly' modifier can only appear on a property " 1485 "declaration or index signature.", 1486 memberStartLoc); 1487 } 1488 1489 member->SetRange({memberStartLoc, lexer_->GetToken().End()}); 1490 1491 return member; 1492 } 1493 GetTSPropertyName(ir::Expression * key)1494 util::StringView GetTSPropertyName(ir::Expression *key) 1495 { 1496 switch (key->Type()) { 1497 case ir::AstNodeType::IDENTIFIER: { 1498 return key->AsIdentifier()->Name(); 1499 } 1500 case ir::AstNodeType::NUMBER_LITERAL: { 1501 return key->AsNumberLiteral()->Str(); 1502 } 1503 case ir::AstNodeType::STRING_LITERAL: { 1504 return key->AsStringLiteral()->Str(); 1505 } 1506 default: { 1507 UNREACHABLE(); 1508 } 1509 } 1510 } 1511 CheckObjectTypeForDuplicatedProperties(ir::Expression * member,ArenaVector<ir::Expression * > const & members)1512 void ParserImpl::CheckObjectTypeForDuplicatedProperties(ir::Expression *member, ArenaVector<ir::Expression *> const &members) 1513 { 1514 ir::Expression *key = nullptr; 1515 1516 if (member->IsTSPropertySignature()) { 1517 key = member->AsTSPropertySignature()->Key(); 1518 } else if (member->IsTSMethodSignature()) { 1519 key = member->AsTSMethodSignature()->Key(); 1520 } else { 1521 return; 1522 } 1523 1524 if (!key->IsIdentifier() && !key->IsNumberLiteral() && !key->IsStringLiteral()) { 1525 return; 1526 } 1527 1528 for (auto *it : members) { 1529 ir::Expression *compare = nullptr; 1530 1531 switch (it->Type()) { 1532 case ir::AstNodeType::TS_PROPERTY_SIGNATURE: { 1533 compare = it->AsTSPropertySignature()->Key(); 1534 break; 1535 } 1536 case ir::AstNodeType::TS_METHOD_SIGNATURE: { 1537 compare = it->AsTSMethodSignature()->Key(); 1538 break; 1539 } 1540 default: { 1541 continue; 1542 } 1543 } 1544 1545 if (!compare->IsIdentifier() && !compare->IsNumberLiteral() && !compare->IsStringLiteral()) { 1546 continue; 1547 } 1548 1549 if (member->IsTSMethodSignature() && it->Type() == ir::AstNodeType::TS_METHOD_SIGNATURE) { 1550 continue; 1551 } 1552 1553 if (GetTSPropertyName(key) == GetTSPropertyName(compare)) { 1554 ThrowSyntaxError("Duplicated identifier", key->Start()); 1555 } 1556 } 1557 } 1558 ParseTsTypeLiteralOrInterface()1559 ArenaVector<ir::Expression *> ParserImpl::ParseTsTypeLiteralOrInterface() 1560 { 1561 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); 1562 1563 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); // eat '{' 1564 1565 ArenaVector<ir::Expression *> members(Allocator()->Adapter()); 1566 1567 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 1568 ir::Expression *member = ParseTsTypeLiteralOrInterfaceMember(); 1569 1570 CheckObjectTypeForDuplicatedProperties(member, members); 1571 1572 members.push_back(member); 1573 1574 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 1575 break; 1576 } 1577 1578 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 1579 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 1580 if (!lexer_->GetToken().NewLine()) { 1581 ThrowSyntaxError("',' expected"); 1582 } 1583 1584 if (lexer_->GetToken().IsKeyword()) { 1585 lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); 1586 } 1587 1588 continue; 1589 } 1590 1591 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 1592 } 1593 1594 return members; 1595 } 1596 ParseTsArrayType(ir::Expression * elementType)1597 ir::TSArrayType *ParserImpl::ParseTsArrayType(ir::Expression *elementType) 1598 { 1599 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 1600 lexer_->NextToken(); // eat '[' 1601 1602 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 1603 ThrowSyntaxError("']' expected"); 1604 } 1605 1606 lexer::SourcePosition endLoc = lexer_->GetToken().End(); 1607 lexer_->NextToken(); // eat ']' 1608 1609 lexer::SourcePosition startLoc = elementType->Start(); 1610 auto *arrayType = AllocNode<ir::TSArrayType>(elementType); 1611 arrayType->SetRange({startLoc, endLoc}); 1612 1613 return arrayType; 1614 } 1615 ParseTsUnionType(ir::Expression * type,bool restrictExtends)1616 ir::TSUnionType *ParserImpl::ParseTsUnionType(ir::Expression *type, bool restrictExtends) 1617 { 1618 ArenaVector<ir::Expression *> types(Allocator()->Adapter()); 1619 lexer::SourcePosition startLoc; 1620 1621 TypeAnnotationParsingOptions options = 1622 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::IN_UNION; 1623 1624 if (restrictExtends) { 1625 options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 1626 } 1627 1628 if (type) { 1629 startLoc = type->Start(); 1630 types.push_back(type); 1631 } else { 1632 startLoc = lexer_->GetToken().Start(); 1633 } 1634 1635 while (true) { 1636 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) { 1637 break; 1638 } 1639 1640 lexer_->NextToken(); // eat '|' 1641 1642 types.push_back(ParseTsTypeAnnotation(&options)); 1643 } 1644 1645 lexer::SourcePosition endLoc = types.back()->End(); 1646 1647 auto *unionType = AllocNode<ir::TSUnionType>(std::move(types)); 1648 auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, unionType); 1649 unionType->SetVariable(typeVar); 1650 unionType->SetRange({startLoc, endLoc}); 1651 1652 return unionType; 1653 } 1654 ParseTsIntersectionType(ir::Expression * type,bool inUnion,bool restrictExtends)1655 ir::TSIntersectionType *ParserImpl::ParseTsIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends) 1656 { 1657 ArenaVector<ir::Expression *> types(Allocator()->Adapter()); 1658 lexer::SourcePosition startLoc; 1659 1660 TypeAnnotationParsingOptions options = 1661 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION; 1662 1663 if (restrictExtends) { 1664 options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 1665 } 1666 1667 if (inUnion) { 1668 options |= TypeAnnotationParsingOptions::IN_UNION; 1669 } 1670 1671 if (type) { 1672 startLoc = type->Start(); 1673 types.push_back(type); 1674 } else { 1675 startLoc = lexer_->GetToken().Start(); 1676 } 1677 1678 while (true) { 1679 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) { 1680 break; 1681 } 1682 1683 lexer_->NextToken(); // eat '&' 1684 1685 types.push_back(ParseTsTypeAnnotation(&options)); 1686 } 1687 1688 lexer::SourcePosition endLoc = types.back()->End(); 1689 1690 auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types)); 1691 auto *typeVar = binder::Scope::CreateVar(Allocator(), "__type", binder::VariableFlags::TYPE, intersectionType); 1692 intersectionType->SetVariable(typeVar); 1693 intersectionType->SetRange({startLoc, endLoc}); 1694 1695 return intersectionType; 1696 } 1697 IsTsFunctionType()1698 bool ParserImpl::IsTsFunctionType() 1699 { 1700 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 1701 const auto startPos = lexer_->Save(); 1702 lexer_->NextToken(); // eat '(' 1703 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS || 1704 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 1705 lexer_->Rewind(startPos); 1706 return true; 1707 } 1708 1709 try { 1710 ParseModifiers(); 1711 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 1712 (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS)) { 1713 lexer_->NextToken(); 1714 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 1715 ParseArrayExpression(ExpressionParseFlags::MUST_BE_PATTERN); 1716 } else if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 1717 ParseObjectExpression(ExpressionParseFlags::MUST_BE_PATTERN | ExpressionParseFlags::OBJECT_PATTERN); 1718 } else { 1719 lexer_->Rewind(startPos); 1720 return false; 1721 } 1722 } catch ([[maybe_unused]] const class Error &e) { 1723 lexer_->Rewind(startPos); 1724 return false; 1725 } 1726 1727 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || 1728 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK || 1729 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON || 1730 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL) { 1731 lexer_->Rewind(startPos); 1732 return true; 1733 } 1734 1735 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1736 lexer_->NextToken(); // eat ')' 1737 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) { 1738 lexer_->Rewind(startPos); 1739 return true; 1740 } 1741 } 1742 lexer_->Rewind(startPos); 1743 return false; 1744 } 1745 ParseTsParenthesizedOrFunctionType(ir::Expression * typeAnnotation,bool throwError)1746 ir::Expression *ParserImpl::ParseTsParenthesizedOrFunctionType(ir::Expression *typeAnnotation, bool throwError) 1747 { 1748 if (typeAnnotation) { 1749 return nullptr; 1750 } 1751 1752 lexer::SourcePosition typeStart = lexer_->GetToken().Start(); 1753 1754 bool abstractConstructor = lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT; 1755 if (abstractConstructor) { 1756 lexer_->NextToken(); // eat 'abstract' 1757 } 1758 1759 bool isConstructionType = false; 1760 1761 if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_NEW) { 1762 lexer_->NextToken(); // eat 'new' 1763 isConstructionType = true; 1764 1765 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 1766 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1767 if (!throwError) { 1768 return nullptr; 1769 } 1770 ThrowSyntaxError("'(' expected"); 1771 } 1772 } 1773 1774 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) { 1775 return ParseTsFunctionType(typeStart, isConstructionType, throwError, abstractConstructor); 1776 } 1777 1778 if (IsTsFunctionType()) { 1779 return ParseTsFunctionType(typeStart, false, throwError); 1780 } 1781 1782 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 1783 lexer_->NextToken(); // eat '(' 1784 1785 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 1786 ir::Expression *type = ParseTsTypeAnnotation(&options); 1787 1788 if (throwError && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 1789 ThrowSyntaxError("')' expected"); 1790 } 1791 1792 lexer::SourcePosition endLoc = lexer_->GetToken().End(); 1793 lexer_->NextToken(); // eat ')' 1794 1795 auto *result = AllocNode<ir::TSParenthesizedType>(type); 1796 result->SetRange({typeStart, endLoc}); 1797 1798 return result; 1799 } 1800 ParseTsFunctionType(lexer::SourcePosition startLoc,bool isConstructionType,bool throwError,bool abstractConstructor)1801 ir::Expression *ParserImpl::ParseTsFunctionType(lexer::SourcePosition startLoc, bool isConstructionType, 1802 bool throwError, bool abstractConstructor) 1803 { 1804 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 1805 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 1806 typeParamDecl = ParseTsTypeParameterDeclaration(throwError); 1807 1808 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1809 if (!throwError) { 1810 return nullptr; 1811 } 1812 1813 ThrowSyntaxError("'(' expected"); 1814 } 1815 } 1816 1817 FunctionParameterContext funcParamContext(&context_, Binder()); 1818 auto *funcParamScope = funcParamContext.LexicalScope().GetScope(); 1819 1820 ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 1821 try { 1822 params = ParseFunctionParams(true); 1823 } catch (const Error &e) { 1824 if (!throwError) { 1825 return nullptr; 1826 } 1827 throw e; 1828 } 1829 1830 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 1831 ThrowSyntaxError("'=>' expected"); 1832 } 1833 1834 lexer_->NextToken(); // eat '=>' 1835 1836 TypeAnnotationParsingOptions options = 1837 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 1838 ir::Expression *returnTypeAnnotation = ParseTsTypeAnnotation(&options); 1839 1840 ir::Expression *funcType = nullptr; 1841 1842 if (isConstructionType) { 1843 funcType = AllocNode<ir::TSConstructorType>(funcParamScope, std::move(params), typeParamDecl, 1844 returnTypeAnnotation, abstractConstructor); 1845 } else { 1846 funcType = 1847 AllocNode<ir::TSFunctionType>(funcParamScope, std::move(params), typeParamDecl, returnTypeAnnotation); 1848 } 1849 1850 funcType->SetRange({startLoc, returnTypeAnnotation->End()}); 1851 funcParamScope->BindNode(funcType); 1852 1853 return funcType; 1854 } 1855 ParseTsBasicType(TypeAnnotationParsingOptions options)1856 ir::Expression *ParserImpl::ParseTsBasicType(TypeAnnotationParsingOptions options) 1857 { 1858 ir::Expression *typeAnnotation = nullptr; 1859 1860 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) { 1861 lexer_->NextToken(); 1862 1863 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) { 1864 if (options & TypeAnnotationParsingOptions::THROW_ERROR) { 1865 ThrowSyntaxError("Type expected"); 1866 } else { 1867 return nullptr; 1868 } 1869 } 1870 } 1871 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NUMBER) { 1872 if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) { 1873 auto *bigintNode = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt()); 1874 bigintNode->SetRange(lexer_->GetToken().Loc()); 1875 1876 typeAnnotation = AllocNode<ir::TSLiteralType>(bigintNode); 1877 } else { 1878 auto *numberNode = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String()); 1879 numberNode->SetRange(lexer_->GetToken().Loc()); 1880 1881 typeAnnotation = AllocNode<ir::TSLiteralType>(numberNode); 1882 } 1883 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { 1884 auto *stringNode = AllocNode<ir::StringLiteral>(lexer_->GetToken().String()); 1885 stringNode->SetRange(lexer_->GetToken().Loc()); 1886 1887 typeAnnotation = AllocNode<ir::TSLiteralType>(stringNode); 1888 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE) { 1889 auto *booleanLiteral = AllocNode<ir::BooleanLiteral>(true); 1890 booleanLiteral->SetRange(lexer_->GetToken().Loc()); 1891 1892 typeAnnotation = AllocNode<ir::TSLiteralType>(booleanLiteral); 1893 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE) { 1894 auto *booleanLiteral = AllocNode<ir::BooleanLiteral>(false); 1895 booleanLiteral->SetRange(lexer_->GetToken().Loc()); 1896 1897 typeAnnotation = AllocNode<ir::TSLiteralType>(booleanLiteral); 1898 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ANY) { 1899 typeAnnotation = AllocNode<ir::TSAnyKeyword>(); 1900 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_BOOLEAN) { 1901 typeAnnotation = AllocNode<ir::TSBooleanKeyword>(); 1902 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NUMBER) { 1903 typeAnnotation = AllocNode<ir::TSNumberKeyword>(); 1904 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_STRING) { 1905 typeAnnotation = AllocNode<ir::TSStringKeyword>(); 1906 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNKNOWN) { 1907 typeAnnotation = AllocNode<ir::TSUnknownKeyword>(); 1908 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_VOID) { 1909 typeAnnotation = AllocNode<ir::TSVoidKeyword>(); 1910 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::LITERAL_NULL) { 1911 typeAnnotation = AllocNode<ir::TSNullKeyword>(); 1912 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_UNDEFINED) { 1913 typeAnnotation = AllocNode<ir::TSUndefinedKeyword>(); 1914 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_NEVER) { 1915 typeAnnotation = AllocNode<ir::TSNeverKeyword>(); 1916 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_OBJECT) { 1917 typeAnnotation = AllocNode<ir::TSObjectKeyword>(); 1918 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_BIGINT) { 1919 typeAnnotation = AllocNode<ir::TSBigintKeyword>(); 1920 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_SYMBOL) { 1921 typeAnnotation = AllocNode<ir::TSSymbolKeyword>(); 1922 } else { 1923 ThrowSyntaxError("Unexpected type"); 1924 } 1925 1926 typeAnnotation->SetRange(lexer_->GetToken().Loc()); 1927 1928 lexer_->NextToken(); 1929 return typeAnnotation; 1930 } 1931 GetAccessability(ir::ModifierFlags modifiers)1932 static ir::ModifierFlags GetAccessability(ir::ModifierFlags modifiers) 1933 { 1934 if (modifiers & ir::ModifierFlags::PUBLIC) { 1935 return ir::ModifierFlags::PUBLIC; 1936 } 1937 1938 if (modifiers & ir::ModifierFlags::PRIVATE) { 1939 return ir::ModifierFlags::PRIVATE; 1940 } 1941 1942 if (modifiers & ir::ModifierFlags::PROTECTED) { 1943 return ir::ModifierFlags::PROTECTED; 1944 } 1945 1946 return ir::ModifierFlags::NONE; 1947 } 1948 IsModifierKind(const lexer::Token & token)1949 static bool IsModifierKind(const lexer::Token &token) 1950 { 1951 if (token.Type() == lexer::TokenType::LITERAL_IDENT) { 1952 switch (token.KeywordType()) { 1953 case lexer::TokenType::KEYW_PUBLIC: 1954 case lexer::TokenType::KEYW_PRIVATE: 1955 case lexer::TokenType::KEYW_PROTECTED: 1956 case lexer::TokenType::KEYW_STATIC: 1957 case lexer::TokenType::KEYW_ASYNC: 1958 case lexer::TokenType::KEYW_ABSTRACT: 1959 case lexer::TokenType::KEYW_DECLARE: 1960 case lexer::TokenType::KEYW_READONLY: 1961 return true; 1962 default: 1963 return false; 1964 } 1965 } 1966 1967 return false; 1968 } 1969 ParseModifiers()1970 ir::ModifierFlags ParserImpl::ParseModifiers() 1971 { 1972 ir::ModifierFlags resultStatus = ir::ModifierFlags::NONE; 1973 ir::ModifierFlags prevStatus = ir::ModifierFlags::ALL; 1974 1975 while (IsModifierKind(lexer_->GetToken())) { 1976 char32_t nextCp = lexer_->Lookahead(); 1977 if (!((Extension() == ScriptExtension::JS && nextCp != LEX_CHAR_LEFT_PAREN) || 1978 (Extension() == ScriptExtension::TS && nextCp != LEX_CHAR_EQUALS && nextCp != LEX_CHAR_SEMICOLON && 1979 nextCp != LEX_CHAR_COMMA && nextCp != LEX_CHAR_LEFT_PAREN))) { 1980 break; 1981 } 1982 1983 lexer::TokenFlags tokenFlags = lexer_->GetToken().Flags(); 1984 if (tokenFlags & lexer::TokenFlags::HAS_ESCAPE) { 1985 ThrowSyntaxError("Keyword must not contain escaped characters"); 1986 } 1987 1988 ir::ModifierFlags actualStatus = ir::ModifierFlags::NONE; 1989 ir::ModifierFlags nextStatus = ir::ModifierFlags::NONE; 1990 1991 switch (lexer_->GetToken().KeywordType()) { 1992 case lexer::TokenType::KEYW_PUBLIC: { 1993 actualStatus = ir::ModifierFlags::PUBLIC; 1994 nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY | 1995 ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT; 1996 break; 1997 } 1998 case lexer::TokenType::KEYW_PRIVATE: { 1999 actualStatus = ir::ModifierFlags::PRIVATE; 2000 nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY | 2001 ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT; 2002 break; 2003 } 2004 case lexer::TokenType::KEYW_PROTECTED: { 2005 actualStatus = ir::ModifierFlags::PROTECTED; 2006 nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | ir::ModifierFlags::READONLY | 2007 ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT; 2008 break; 2009 } 2010 case lexer::TokenType::KEYW_STATIC: { 2011 actualStatus = ir::ModifierFlags::STATIC; 2012 nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE | 2013 ir::ModifierFlags::ABSTRACT; 2014 break; 2015 } 2016 case lexer::TokenType::KEYW_ASYNC: { 2017 actualStatus = ir::ModifierFlags::ASYNC; 2018 nextStatus = ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT; 2019 break; 2020 } 2021 case lexer::TokenType::KEYW_ABSTRACT: { 2022 actualStatus = ir::ModifierFlags::ABSTRACT; 2023 nextStatus = ir::ModifierFlags::ACCESS | ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | 2024 ir::ModifierFlags::READONLY | ir::ModifierFlags::DECLARE; 2025 break; 2026 } 2027 case lexer::TokenType::KEYW_DECLARE: { 2028 actualStatus = ir::ModifierFlags::DECLARE; 2029 nextStatus = ir::ModifierFlags::ACCESS | ir::ModifierFlags::ASYNC | ir::ModifierFlags::STATIC | 2030 ir::ModifierFlags::READONLY; 2031 break; 2032 } 2033 case lexer::TokenType::KEYW_READONLY: { 2034 actualStatus = ir::ModifierFlags::READONLY; 2035 nextStatus = ir::ModifierFlags::ASYNC | ir::ModifierFlags::DECLARE | ir::ModifierFlags::ABSTRACT; 2036 break; 2037 } 2038 default: { 2039 UNREACHABLE(); 2040 } 2041 } 2042 2043 if (lexer_->Lookahead() == LEX_CHAR_COLON || lexer_->Lookahead() == LEX_CHAR_COMMA || 2044 lexer_->Lookahead() == LEX_CHAR_RIGHT_PAREN || lexer_->Lookahead() == LEX_CHAR_QUESTION || 2045 lexer_->Lookahead() == LEX_CHAR_RIGHT_BRACE || lexer_->Lookahead() == LEX_CHAR_LESS_THAN) { 2046 break; 2047 } 2048 2049 auto pos = lexer_->Save(); 2050 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2051 2052 if ((prevStatus & actualStatus) == 0) { 2053 lexer_->Rewind(pos); 2054 ThrowSyntaxError("Unexpected modifier"); 2055 } 2056 2057 if ((resultStatus & actualStatus) != 0) { 2058 lexer_->Rewind(pos); 2059 ThrowSyntaxError("Duplicated modifier is not allowed"); 2060 } 2061 2062 if ((context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) && 2063 (actualStatus & ~ir::ModifierFlags::ALLOWED_IN_CTOR_PARAMETER)) { 2064 lexer_->Rewind(pos); 2065 ThrowParameterModifierError(actualStatus); 2066 } 2067 2068 resultStatus |= actualStatus; 2069 prevStatus = nextStatus; 2070 } 2071 2072 return resultStatus; 2073 } 2074 CheckAccessorPair(const ArenaVector<ir::Statement * > & properties,const ir::Expression * propName,ir::MethodDefinitionKind methodKind,ir::ModifierFlags access,bool hasDecorator,lexer::SourcePosition errorInfo)2075 void ParserImpl::CheckAccessorPair(const ArenaVector<ir::Statement *> &properties, const ir::Expression *propName, 2076 ir::MethodDefinitionKind methodKind, ir::ModifierFlags access, bool hasDecorator, 2077 lexer::SourcePosition errorInfo) 2078 { 2079 for (const auto &it : properties) { 2080 if (!it->IsMethodDefinition() || (!hasDecorator && it->AsMethodDefinition()->Kind() != methodKind)) { 2081 continue; 2082 } 2083 2084 const ir::Expression *key = it->AsMethodDefinition()->Key(); 2085 2086 if (key->Type() != propName->Type()) { 2087 continue; 2088 } 2089 2090 bool keyIsSame = false; 2091 2092 if (key->IsIdentifier()) { 2093 const util::StringView &strName = propName->AsIdentifier()->Name(); 2094 const util::StringView &compareName = (key->AsIdentifier()->Name()); 2095 2096 keyIsSame = strName == compareName; 2097 } else if (key->IsNumberLiteral()) { 2098 keyIsSame = *key->AsNumberLiteral() == *propName->AsNumberLiteral(); 2099 } else if (key->IsStringLiteral()) { 2100 keyIsSame = *key->AsStringLiteral() == *propName->AsStringLiteral(); 2101 } 2102 2103 if (!keyIsSame) { 2104 continue; 2105 } 2106 2107 if (hasDecorator && 2108 (it->AsMethodDefinition()->Kind() == ir::MethodDefinitionKind::GET || 2109 it->AsMethodDefinition()->Kind() == ir::MethodDefinitionKind::SET) && 2110 !it->AsMethodDefinition()->Decorators().empty()) { 2111 ThrowSyntaxError("Decorators cannot be applied to multiple get/set accessors of the same name.", errorInfo); 2112 } 2113 2114 if (it->AsMethodDefinition()->Kind() != methodKind) { 2115 continue; 2116 } 2117 2118 ir::ModifierFlags getAccess = ir::ModifierFlags::NONE; 2119 ir::ModifierFlags setAccess = ir::ModifierFlags::NONE; 2120 2121 if (methodKind == ir::MethodDefinitionKind::GET) { 2122 setAccess = access; 2123 getAccess = GetAccessability(it->AsMethodDefinition()->Modifiers()); 2124 } else { 2125 getAccess = access; 2126 setAccess = GetAccessability(it->AsMethodDefinition()->Modifiers()); 2127 } 2128 2129 if ((setAccess == ir::ModifierFlags::NONE && getAccess > ir::ModifierFlags::PUBLIC) || 2130 (setAccess != ir::ModifierFlags::NONE && getAccess > setAccess)) { 2131 ThrowSyntaxError("A get accessor must be at least as accessible as the setter", key->Start()); 2132 } 2133 } 2134 } 2135 ParseClassKeyModifiers(ClassElmentDescriptor * desc)2136 void ParserImpl::ParseClassKeyModifiers(ClassElmentDescriptor *desc) 2137 { 2138 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 2139 return; 2140 } 2141 2142 char32_t nextCp = lexer_->Lookahead(); 2143 2144 if ((Extension() == ScriptExtension::JS && nextCp != LEX_CHAR_LEFT_PAREN) || 2145 (Extension() == ScriptExtension::TS && 2146 nextCp != LEX_CHAR_EQUALS && nextCp != LEX_CHAR_SEMICOLON && nextCp != LEX_CHAR_LEFT_PAREN && 2147 nextCp != LEX_CHAR_LESS_THAN && nextCp != LEX_CHAR_QUESTION && nextCp != LEX_CHAR_COLON)) { 2148 if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_GET) { 2149 if (desc->isPrivateIdent) { 2150 ThrowSyntaxError("Private identifier can not be getter"); 2151 } 2152 2153 if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) { 2154 ThrowSyntaxError("Keyword must not contain escaped characters"); 2155 } 2156 2157 desc->methodKind = ir::MethodDefinitionKind::GET; 2158 desc->methodStart = lexer_->GetToken().Start(); 2159 2160 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2161 } else if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_SET) { 2162 if (desc->isPrivateIdent) { 2163 ThrowSyntaxError("Private identifier can not be setter"); 2164 } 2165 2166 if (lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) { 2167 ThrowSyntaxError("Keyword must not contain escaped characters"); 2168 } 2169 2170 desc->methodKind = ir::MethodDefinitionKind::SET; 2171 desc->methodStart = lexer_->GetToken().Start(); 2172 2173 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2174 } 2175 } 2176 } 2177 ThrowIfPrivateIdent(ClassElmentDescriptor * desc,const char * msg)2178 void ParserImpl::ThrowIfPrivateIdent(ClassElmentDescriptor *desc, const char *msg) 2179 { 2180 if (desc->isPrivateIdent) { 2181 ThrowSyntaxError(msg); 2182 } 2183 } 2184 ValidateClassKey(ClassElmentDescriptor * desc,bool isDeclare)2185 void ParserImpl::ValidateClassKey(ClassElmentDescriptor *desc, bool isDeclare) 2186 { 2187 if ((desc->modifiers & ir::ModifierFlags::ASYNC) && 2188 (desc->methodKind == ir::MethodDefinitionKind::GET || desc->methodKind == ir::MethodDefinitionKind::SET)) { 2189 ThrowSyntaxError("Async method can not be getter nor setter"); 2190 } 2191 2192 const util::StringView &propNameStr = lexer_->GetToken().Ident(); 2193 2194 if (propNameStr.Is("constructor")) { 2195 ThrowIfPrivateIdent(desc, "Private identifier can not be constructor"); 2196 2197 if (!(desc->modifiers & ir::ModifierFlags::STATIC)) { 2198 if ((desc->modifiers & ir::ModifierFlags::ASYNC) || desc->methodKind == ir::MethodDefinitionKind::GET || 2199 desc->methodKind == ir::MethodDefinitionKind::SET || desc->isGenerator) { 2200 ThrowSyntaxError("Constructor can not be special method"); 2201 } 2202 2203 desc->methodKind = ir::MethodDefinitionKind::CONSTRUCTOR; 2204 desc->methodStart = lexer_->GetToken().Start(); 2205 desc->newStatus |= ParserStatus::CONSTRUCTOR_FUNCTION; 2206 2207 if (desc->hasSuperClass) { 2208 desc->newStatus |= ParserStatus::ALLOW_SUPER_CALL; 2209 } 2210 } else if (Extension() == ScriptExtension::TS) { 2211 ThrowSyntaxError("Static modifier can not appear on a constructor"); 2212 } 2213 } else if (!isDeclare && propNameStr.Is("prototype") && (desc->modifiers & ir::ModifierFlags::STATIC)) { 2214 ThrowSyntaxError("Classes may not have static property named prototype"); 2215 } 2216 } 2217 ParseClassKey(ClassElmentDescriptor * desc,bool isDeclare)2218 ir::Expression *ParserImpl::ParseClassKey(ClassElmentDescriptor *desc, bool isDeclare) 2219 { 2220 ir::Expression *propName = nullptr; 2221 if (lexer_->GetToken().IsKeyword()) { 2222 lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); 2223 } 2224 2225 switch (lexer_->GetToken().Type()) { 2226 case lexer::TokenType::LITERAL_IDENT: { 2227 ValidateClassKey(desc, isDeclare); 2228 2229 propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 2230 propName->SetRange(lexer_->GetToken().Loc()); 2231 break; 2232 } 2233 case lexer::TokenType::LITERAL_STRING: { 2234 ThrowIfPrivateIdent(desc, "Private identifier name can not be string"); 2235 2236 propName = AllocNode<ir::StringLiteral>(lexer_->GetToken().String()); 2237 propName->SetRange(lexer_->GetToken().Loc()); 2238 break; 2239 } 2240 case lexer::TokenType::LITERAL_NUMBER: { 2241 ThrowIfPrivateIdent(desc, "Private identifier name can not be number"); 2242 2243 if (lexer_->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) { 2244 propName = AllocNode<ir::BigIntLiteral>(lexer_->GetToken().BigInt()); 2245 } else { 2246 propName = AllocNode<ir::NumberLiteral>(lexer_->GetToken().Number(), lexer_->GetToken().String()); 2247 } 2248 2249 propName->SetRange(lexer_->GetToken().Loc()); 2250 break; 2251 } 2252 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 2253 ThrowIfPrivateIdent(desc, "Unexpected character in private identifier"); 2254 2255 lexer_->NextToken(); // eat left square bracket 2256 2257 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && 2258 lexer_->Lookahead() == LEX_CHAR_COLON) { 2259 desc->isIndexSignature = true; 2260 2261 propName = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 2262 propName->SetRange(lexer_->GetToken().Loc()); 2263 2264 lexer_->NextToken(); // eat param 2265 2266 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 2267 ThrowSyntaxError("':' expected"); 2268 } 2269 2270 lexer_->NextToken(); // eat ':' 2271 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 2272 ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options); 2273 2274 if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { 2275 ThrowSyntaxError( 2276 "An index signature parameter type must be either " 2277 "'string' or 'number'"); 2278 } 2279 2280 propName->SetTsTypeAnnotation(typeAnnotation); 2281 2282 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 2283 ThrowSyntaxError("']' expected"); 2284 } 2285 2286 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2287 2288 return propName; 2289 } 2290 2291 desc->isComputed = true; 2292 2293 propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 2294 2295 if (Extension() == ScriptExtension::TS) { 2296 // TODO(songqi): Determine whether MemberExpression is a symbol during type check. 2297 desc->invalidComputedProperty = !propName->IsNumberLiteral() && 2298 util::Helpers::GetSignedNumberLiteral(propName) == util::SignedNumberLiteral::UNRECOGNIZED && 2299 !propName->IsStringLiteral() && !propName->IsMemberExpression() && !propName->IsIdentifier(); 2300 } 2301 2302 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 2303 ThrowSyntaxError("Unexpected token, expected ']'"); 2304 } 2305 break; 2306 } 2307 default: { 2308 ThrowSyntaxError("Unexpected token in class property"); 2309 } 2310 } 2311 2312 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2313 2314 return propName; 2315 } 2316 ValidateClassMethodStart(ClassElmentDescriptor * desc,ir::Expression * typeAnnotation)2317 void ParserImpl::ValidateClassMethodStart(ClassElmentDescriptor *desc, ir::Expression *typeAnnotation) 2318 { 2319 if (Extension() == ScriptExtension::JS) { 2320 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 2321 return; 2322 } 2323 desc->classMethod = true; 2324 } 2325 2326 if (Extension() == ScriptExtension::TS && 2327 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) { 2328 ThrowSyntaxError("A method cannot be named with a private identifier"); 2329 } 2330 2331 if (Extension() == ScriptExtension::TS) { 2332 if (!typeAnnotation && (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 2333 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) { 2334 if ((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY))) { 2335 ThrowSyntaxError("Class method can not be declare nor readonly"); 2336 } 2337 desc->classMethod = true; 2338 } else { 2339 if ((desc->modifiers & ir::ModifierFlags::ASYNC) || desc->isGenerator) { 2340 ThrowSyntaxError("Expected '('"); 2341 } 2342 desc->classField = true; 2343 2344 if (desc->invalidComputedProperty) { 2345 ThrowSyntaxError( 2346 "Computed property name must refer to a symbol or " 2347 "literal expression whos value is " 2348 "number or string"); 2349 } 2350 } 2351 } 2352 2353 if (desc->modifiers & ir::ModifierFlags::ASYNC) { 2354 desc->newStatus |= ParserStatus::ASYNC_FUNCTION; 2355 } 2356 2357 if (desc->isGenerator) { 2358 desc->newStatus |= ParserStatus::GENERATOR_FUNCTION; 2359 } 2360 } 2361 ValidateClassSetter(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::ScriptFunction * func,bool hasDecorator,lexer::SourcePosition errorInfo)2362 void ParserImpl::ValidateClassSetter(ClassElmentDescriptor *desc, const ArenaVector<ir::Statement *> &properties, 2363 ir::Expression *propName, ir::ScriptFunction *func, bool hasDecorator, 2364 lexer::SourcePosition errorInfo) 2365 { 2366 if (func->Params().size() != 1) { 2367 ThrowSyntaxError("Setter must have exactly one formal parameter"); 2368 } 2369 2370 if (Extension() == ScriptExtension::TS && !(desc->modifiers & ir::ModifierFlags::STATIC)) { 2371 ir::ModifierFlags access = GetAccessability(desc->modifiers); 2372 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access, hasDecorator, errorInfo); 2373 } 2374 } 2375 ValidateClassGetter(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::ScriptFunction * func,bool hasDecorator,lexer::SourcePosition errorInfo)2376 void ParserImpl::ValidateClassGetter(ClassElmentDescriptor *desc, const ArenaVector<ir::Statement *> &properties, 2377 ir::Expression *propName, ir::ScriptFunction *func, bool hasDecorator, 2378 lexer::SourcePosition errorInfo) 2379 { 2380 if (!func->Params().empty()) { 2381 ThrowSyntaxError("Getter must not have formal parameters"); 2382 } 2383 2384 if (Extension() == ScriptExtension::TS && !(desc->modifiers & ir::ModifierFlags::STATIC)) { 2385 ir::ModifierFlags access = GetAccessability(desc->modifiers); 2386 2387 CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access, hasDecorator, errorInfo); 2388 } 2389 } 2390 ParseClassMethod(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,lexer::SourcePosition * propEnd,ArenaVector<ir::Decorator * > && decorators,bool isDeclare)2391 ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElmentDescriptor *desc, 2392 const ArenaVector<ir::Statement *> &properties, 2393 ir::Expression *propName, lexer::SourcePosition *propEnd, 2394 ArenaVector<ir::Decorator *> &&decorators, bool isDeclare) 2395 { 2396 if (Extension() == ScriptExtension::TS) { 2397 if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) { 2398 desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION; 2399 } 2400 2401 desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION; 2402 } 2403 2404 if (isDeclare && (desc->newStatus & ParserStatus::ASYNC_FUNCTION)) { 2405 ThrowSyntaxError("'async' modifier cannot be used in an ambient context."); 2406 } 2407 2408 if (isDeclare && desc->isGenerator) { 2409 ThrowSyntaxError("Generators are not allowed in an ambient context."); 2410 } 2411 2412 ArenaVector<ir::ParamDecorators> paramDecorators(Allocator()->Adapter()); 2413 ir::ScriptFunction *func = ParseFunction(desc->newStatus, isDeclare, ¶mDecorators); 2414 if (func->Body() != nullptr) { 2415 lexer_->NextToken(); 2416 } 2417 2418 if (func->IsOverload() && !decorators.empty()) { 2419 ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.", 2420 decorators.front()->Start()); 2421 } 2422 2423 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 2424 funcExpr->SetRange(func->Range()); 2425 2426 lexer::SourcePosition errorInfo = decorators.empty() ? func->Start() : decorators[0]->Start(); 2427 2428 if (desc->methodKind == ir::MethodDefinitionKind::SET) { 2429 ValidateClassSetter(desc, properties, propName, func, !decorators.empty(), errorInfo); 2430 } else if (desc->methodKind == ir::MethodDefinitionKind::GET) { 2431 ValidateClassGetter(desc, properties, propName, func, !decorators.empty(), errorInfo); 2432 } 2433 2434 *propEnd = func->End(); 2435 func->AddFlag(ir::ScriptFunctionFlags::METHOD); 2436 auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), 2437 std::move(decorators), std::move(paramDecorators), 2438 desc->isComputed); 2439 method->SetRange(funcExpr->Range()); 2440 return method; 2441 } 2442 ParseClassProperty(ClassElmentDescriptor * desc,const ArenaVector<ir::Statement * > & properties,ir::Expression * propName,ir::Expression * typeAnnotation,ArenaVector<ir::Decorator * > && decorators,bool isDeclare)2443 ir::Statement *ParserImpl::ParseClassProperty(ClassElmentDescriptor *desc, 2444 const ArenaVector<ir::Statement *> &properties, ir::Expression *propName, 2445 ir::Expression *typeAnnotation, ArenaVector<ir::Decorator *> &&decorators, 2446 bool isDeclare) 2447 { 2448 lexer::SourcePosition propEnd = propName->End(); 2449 ir::Statement *property = nullptr; 2450 2451 if (desc->classMethod) { 2452 property = ParseClassMethod(desc, properties, propName, &propEnd, std::move(decorators), isDeclare); 2453 property->SetRange({desc->propStart, propEnd}); 2454 return property; 2455 } 2456 2457 ir::Expression *value = nullptr; 2458 2459 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 2460 lexer_->NextToken(); // eat equals 2461 2462 if (isDeclare) { 2463 ThrowSyntaxError("Initializers are not allowed in ambient contexts."); 2464 } 2465 // TODO(songqi):static classProperty's value can use super keyword in TypeScript4.4. 2466 // Currently only Parser is supported, Compiler support requires Transformer. 2467 context_.Status() |= ParserStatus::ALLOW_SUPER; 2468 value = ParseExpression(); 2469 context_.Status() &= ~ParserStatus::ALLOW_SUPER; 2470 propEnd = value->End(); 2471 } 2472 2473 ir::Expression *privateId = nullptr; 2474 2475 if (Extension() == ScriptExtension::JS) { 2476 if (desc->isPrivateIdent) { 2477 ThrowSyntaxError("Private js fields are not supported"); 2478 } 2479 } else { 2480 if (desc->isPrivateIdent) { 2481 privateId = AllocNode<ir::TSPrivateIdentifier>(propName, value, typeAnnotation); 2482 privateId->SetRange({desc->propStart, propName->End()}); 2483 } 2484 } 2485 2486 property = AllocNode<ir::ClassProperty>(desc->isPrivateIdent ? privateId : propName, value, typeAnnotation, 2487 desc->modifiers, std::move(decorators), desc->isComputed, 2488 desc->modifiers & ir::ModifierFlags::DEFINITE); 2489 2490 property->SetRange({desc->propStart, propEnd}); 2491 return property; 2492 } 2493 CheckClassGeneratorMethod(ClassElmentDescriptor * desc)2494 void ParserImpl::CheckClassGeneratorMethod(ClassElmentDescriptor *desc) 2495 { 2496 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MULTIPLY) { 2497 return; 2498 } 2499 2500 ThrowIfPrivateIdent(desc, "Unexpected character in private identifier"); 2501 2502 desc->isGenerator = true; 2503 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2504 } 2505 CheckClassPrivateIdentifier(ClassElmentDescriptor * desc)2506 void ParserImpl::CheckClassPrivateIdentifier(ClassElmentDescriptor *desc) 2507 { 2508 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_HASH_MARK) { 2509 return; 2510 } 2511 2512 if (Extension() == ScriptExtension::JS) { 2513 ThrowSyntaxError("JS private class fields are not supported."); 2514 } 2515 2516 if (Extension() == ScriptExtension::AS) { 2517 return; 2518 } 2519 2520 if (desc->modifiers & ~ir::ModifierFlags::READONLY) { 2521 ThrowSyntaxError("Unexpected modifier on private identifier"); 2522 } 2523 2524 desc->isPrivateIdent = true; 2525 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2526 } 2527 ParseClassKeyAnnotation()2528 ir::Expression *ParserImpl::ParseClassKeyAnnotation() 2529 { 2530 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 2531 lexer_->NextToken(); // eat ':' 2532 TypeAnnotationParsingOptions options = 2533 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 2534 return ParseTsTypeAnnotation(&options); 2535 } 2536 2537 return nullptr; 2538 } 2539 ParseDecorator()2540 ir::Decorator *ParserImpl::ParseDecorator() 2541 { 2542 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT); 2543 2544 lexer::SourcePosition start = lexer_->GetToken().Start(); 2545 lexer_->NextToken(); // eat '@' 2546 2547 ir::Expression *expr = ParseLeftHandSideExpression(); 2548 auto *result = AllocNode<ir::Decorator>(expr); 2549 result->SetRange({start, expr->End()}); 2550 2551 return result; 2552 } 2553 ParseDecorators()2554 ArenaVector<ir::Decorator *> ParserImpl::ParseDecorators() 2555 { 2556 ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter()); 2557 auto savedStatus = context_.Status(); 2558 context_.Status() |= ParserStatus::IN_DECORATOR; 2559 2560 while (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { 2561 decorators.push_back(ParseDecorator()); 2562 } 2563 2564 if (!decorators.empty() && lexer_->GetToken().Type() != lexer::TokenType::KEYW_CLASS && 2565 (context_.Status() & ParserStatus::IN_CLASS_BODY) == 0 && 2566 lexer_->GetToken().Type() != lexer::TokenType::KEYW_EXPORT && 2567 !(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && 2568 (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE || 2569 lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT))) { 2570 ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start()); 2571 } 2572 2573 context_.Status() = savedStatus; 2574 return decorators; 2575 } 2576 ParseClassElement(const ArenaVector<ir::Statement * > & properties,ArenaVector<ir::TSIndexSignature * > * indexSignatures,bool hasSuperClass,bool isDeclare,bool isAbstractClass)2577 ir::Statement *ParserImpl::ParseClassElement(const ArenaVector<ir::Statement *> &properties, 2578 ArenaVector<ir::TSIndexSignature *> *indexSignatures, bool hasSuperClass, 2579 bool isDeclare, bool isAbstractClass) 2580 { 2581 ClassElmentDescriptor desc; 2582 2583 desc.methodKind = ir::MethodDefinitionKind::METHOD; 2584 desc.newStatus = ParserStatus::ALLOW_SUPER; 2585 desc.hasSuperClass = hasSuperClass; 2586 desc.propStart = lexer_->GetToken().Start(); 2587 2588 auto decorators = ParseDecorators(); 2589 2590 desc.modifiers = ParseModifiers(); 2591 2592 if ((desc.modifiers & ir::ModifierFlags::ABSTRACT) && !isAbstractClass) { 2593 ThrowSyntaxError("Abstract methods can only appear within an abstract class."); 2594 } 2595 2596 CheckClassPrivateIdentifier(&desc); 2597 CheckClassGeneratorMethod(&desc); 2598 ParseClassKeyModifiers(&desc); 2599 2600 if (!(desc.modifiers & ir::ModifierFlags::STATIC)) { 2601 context_.Status() |= ParserStatus::ALLOW_THIS_TYPE; 2602 } 2603 2604 ir::Expression *propName = ParseClassKey(&desc, isDeclare); 2605 2606 if (desc.methodKind == ir::MethodDefinitionKind::CONSTRUCTOR && !decorators.empty()) { 2607 ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start()); 2608 } 2609 2610 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 2611 if (desc.isIndexSignature) { 2612 ThrowSyntaxError("';' expected"); 2613 } 2614 2615 if (desc.methodKind == ir::MethodDefinitionKind::CONSTRUCTOR) { 2616 ThrowSyntaxError("'(' expected"); 2617 } 2618 2619 desc.modifiers |= ir::ModifierFlags::OPTIONAL; 2620 lexer_->NextToken(); 2621 } else if (Extension() == ScriptExtension::TS && 2622 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { 2623 if (desc.isIndexSignature || lexer_->Lookahead() != LEX_CHAR_COLON) { 2624 ThrowSyntaxError("';' expected"); 2625 } 2626 2627 desc.modifiers |= ir::ModifierFlags::DEFINITE; 2628 lexer_->NextToken(); 2629 } 2630 2631 ir::Expression *typeAnnotation = ParseClassKeyAnnotation(); 2632 2633 ir::Statement *property = nullptr; 2634 if (desc.isIndexSignature) { 2635 if (!decorators.empty()) { 2636 ThrowSyntaxError("Decorators are not valid here.", decorators.front()->Start()); 2637 } 2638 2639 if (!typeAnnotation) { 2640 ThrowSyntaxError("An index signature must have a type annotation"); 2641 } 2642 2643 auto *indexSignature = 2644 AllocNode<ir::TSIndexSignature>(propName, typeAnnotation, desc.modifiers & ir::ModifierFlags::READONLY); 2645 2646 indexSignature->SetRange({indexSignature->Param()->Start(), indexSignature->TypeAnnotation()->End()}); 2647 2648 indexSignatures->push_back(indexSignature); 2649 2650 property = AllocNode<ir::EmptyStatement>(); 2651 } else { 2652 ValidateClassMethodStart(&desc, typeAnnotation); 2653 property = ParseClassProperty(&desc, properties, propName, typeAnnotation, std::move(decorators), 2654 isDeclare || (desc.modifiers & ir::ModifierFlags::DECLARE)); 2655 } 2656 2657 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 2658 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE && 2659 !(lexer_->GetToken().Flags() & lexer::TokenFlags::NEW_LINE) && 2660 !(property->IsMethodDefinition() && property->AsMethodDefinition()->Value()->Function()->Body())) { 2661 ThrowSyntaxError("';' expected."); 2662 } 2663 2664 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 2665 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2666 } 2667 2668 context_.Status() &= ~ParserStatus::ALLOW_THIS_TYPE; 2669 2670 return property; 2671 } 2672 IsConstructor(ir::Statement * stmt)2673 static bool IsConstructor(ir::Statement *stmt) 2674 { 2675 if (!stmt->IsMethodDefinition()) { 2676 return false; 2677 } 2678 2679 ir::MethodDefinition *def = stmt->AsMethodDefinition(); 2680 return def->Kind() == ir::MethodDefinitionKind::CONSTRUCTOR; 2681 } 2682 CreateImplicitConstructor(ir::Expression * superClass,bool hasSuperClass,bool isDeclare)2683 ir::MethodDefinition *ParserImpl::CreateImplicitConstructor(ir::Expression *superClass, 2684 bool hasSuperClass, bool isDeclare) 2685 { 2686 ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 2687 ArenaVector<ir::Statement *> statements(Allocator()->Adapter()); 2688 2689 auto *paramScope = Binder()->Allocator()->New<binder::FunctionParamScope>(Allocator(), Binder()->GetScope()); 2690 auto *scope = Binder()->Allocator()->New<binder::FunctionScope>(Allocator(), paramScope); 2691 2692 if (hasSuperClass) { 2693 if (Extension() != ScriptExtension::TS || !superClass->IsNullLiteral()) { 2694 util::StringView argsStr = "args"; 2695 params.push_back(AllocNode<ir::SpreadElement>(ir::AstNodeType::REST_ELEMENT, 2696 AllocNode<ir::Identifier>(argsStr))); 2697 paramScope->AddParamDecl(Allocator(), params.back()); 2698 2699 ArenaVector<ir::Expression *> callArgs(Allocator()->Adapter()); 2700 auto *superExpr = AllocNode<ir::SuperExpression>(); 2701 callArgs.push_back(AllocNode<ir::SpreadElement>(ir::AstNodeType::SPREAD_ELEMENT, 2702 AllocNode<ir::Identifier>(argsStr))); 2703 2704 auto *callExpr = AllocNode<ir::CallExpression>(superExpr, std::move(callArgs), nullptr, false); 2705 statements.push_back(AllocNode<ir::ExpressionStatement>(callExpr)); 2706 } 2707 } 2708 2709 auto *body = AllocNode<ir::BlockStatement>(scope, std::move(statements)); 2710 auto *func = AllocNode<ir::ScriptFunction>(scope, std::move(params), nullptr, isDeclare ? nullptr : body, nullptr, 2711 ir::ScriptFunctionFlags::CONSTRUCTOR, isDeclare, 2712 Extension() == ScriptExtension::TS); 2713 scope->BindNode(func); 2714 paramScope->BindNode(func); 2715 scope->BindParamScope(paramScope); 2716 paramScope->BindFunctionScope(scope); 2717 2718 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 2719 auto *key = AllocNode<ir::Identifier>("constructor"); 2720 2721 ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter()); 2722 ArenaVector<ir::ParamDecorators> paramDecorators(Allocator()->Adapter()); 2723 auto *ctor = AllocNode<ir::MethodDefinition>(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, 2724 ir::ModifierFlags::NONE, Allocator(), std::move(decorators), 2725 std::move(paramDecorators), false); 2726 2727 return ctor; 2728 } 2729 IsPropertyKeysAreSame(const ir::Expression * exp1,const ir::Expression * exp2)2730 bool ParserImpl::IsPropertyKeysAreSame(const ir::Expression *exp1, const ir::Expression *exp2) 2731 { 2732 if (exp1->IsIdentifier() && exp2->IsIdentifier()) { 2733 return exp1->AsIdentifier()->Name() == exp2->AsIdentifier()->Name(); 2734 } 2735 2736 if (exp1->IsIdentifier() && exp2->IsStringLiteral()) { 2737 return exp1->AsIdentifier()->Name() == exp2->AsStringLiteral()->Str(); 2738 } 2739 2740 if (exp1->IsStringLiteral() && exp2->IsStringLiteral()) { 2741 return *exp1->AsStringLiteral() == *exp2->AsStringLiteral(); 2742 } 2743 2744 if (exp1->IsStringLiteral() && exp2->IsIdentifier()) { 2745 return exp1->AsStringLiteral()->Str() == exp2->AsIdentifier()->Name(); 2746 } 2747 2748 if (exp1->IsStringLiteral() && exp2->IsNumberLiteral()) { 2749 std::string exp2String = std::to_string(exp2->AsNumberLiteral()->Number<double>()); 2750 exp2String.erase(exp2String.find_last_not_of('0'), std::string::npos); 2751 return exp1->AsStringLiteral()->Str().Utf8() == exp2String; 2752 } 2753 2754 if (exp1->IsNumberLiteral() && exp2->IsNumberLiteral()) { 2755 return exp1->AsNumberLiteral()->Number<double>() == exp2->AsNumberLiteral()->Number<double>(); 2756 } 2757 2758 if (exp1->IsNumberLiteral() && exp2->IsStringLiteral()) { 2759 std::string exp1String = std::to_string(exp1->AsNumberLiteral()->Number<double>()); 2760 exp1String.erase(exp1String.find_last_not_of('0'), std::string::npos); 2761 return exp1String == exp2->AsStringLiteral()->Str().Utf8(); 2762 } 2763 2764 return false; 2765 } 2766 IsMemberExpressionsAreSame(const ir::MemberExpression * mExp1,const ir::MemberExpression * mExp2)2767 bool ParserImpl::IsMemberExpressionsAreSame(const ir::MemberExpression *mExp1, const ir::MemberExpression *mExp2) 2768 { 2769 if (!IsPropertyKeysAreSame(mExp1->Property(), mExp2->Property())) { 2770 return false; 2771 } 2772 2773 if (mExp1->Object()->IsMemberExpression() && mExp2->Object()->IsMemberExpression()) { 2774 return IsMemberExpressionsAreSame(mExp1->Object()->AsMemberExpression(), mExp2->Object()->AsMemberExpression()); 2775 } 2776 2777 return IsPropertyKeysAreSame(mExp1->Object(), mExp2->Object()); 2778 } 2779 IsMethodDefinitionsAreSame(const ir::MethodDefinition * property,ir::MethodDefinition * overload)2780 bool ParserImpl::IsMethodDefinitionsAreSame(const ir::MethodDefinition *property, ir::MethodDefinition *overload) 2781 { 2782 if (property->Kind() != overload->Kind() || property->IsStatic() != overload->IsStatic()) { 2783 return false; 2784 } 2785 2786 if (property->Key()->IsMemberExpression() && overload->Key()->IsMemberExpression()) { 2787 return IsMemberExpressionsAreSame(property->Key()->AsMemberExpression(), overload->Key()->AsMemberExpression()); 2788 } 2789 2790 return IsPropertyKeysAreSame(property->Key(), overload->Key()); 2791 } 2792 SetIdentNodeInClassDefinition(bool isDeclare,binder::ConstDecl ** decl)2793 ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition(bool isDeclare, binder::ConstDecl **decl) 2794 { 2795 lexer::TokenType keywType = lexer_->GetToken().KeywordType(); 2796 CheckStrictReservedWord(); 2797 2798 if (keywType == lexer::TokenType::KEYW_AWAIT && context_.IsModule()) { 2799 ThrowSyntaxError("Unexpected reserved word"); 2800 } 2801 2802 const util::StringView &identStr = lexer_->GetToken().Ident(); 2803 2804 *decl = Binder()->AddDecl<binder::ConstDecl>(lexer_->GetToken().Start(), isDeclare, identStr); 2805 2806 auto *identNode = AllocNode<ir::Identifier>(identStr); 2807 identNode->SetRange(lexer_->GetToken().Loc()); 2808 2809 lexer_->NextToken(); 2810 2811 return identNode; 2812 } 2813 ParseClassDefinition(bool isDeclaration,bool idRequired,bool isDeclare,bool isAbstract)2814 ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool idRequired, bool isDeclare, 2815 bool isAbstract) 2816 { 2817 isDeclare = isDeclare | (context_.Status() & ParserStatus::IN_AMBIENT_CONTEXT); 2818 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 2819 lexer_->NextToken(); 2820 2821 binder::ConstDecl *decl = nullptr; 2822 ir::Identifier *identNode = nullptr; 2823 2824 auto classCtx = binder::LexicalScope<binder::LocalScope>(Binder()); 2825 2826 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && (Extension() != ScriptExtension::TS || 2827 lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_IMPLEMENTS)) { 2828 identNode = SetIdentNodeInClassDefinition(isDeclare, &decl); 2829 } else if (isDeclaration && idRequired) { 2830 ThrowSyntaxError("Unexpected token, expected an identifier."); 2831 } 2832 2833 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 2834 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 2835 typeParamDecl = ParseTsTypeParameterDeclaration(); 2836 } 2837 2838 // Parse SuperClass 2839 ir::Expression *superClass = nullptr; 2840 bool hasSuperClass = false; 2841 2842 if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { 2843 lexer_->NextToken(); 2844 hasSuperClass = true; 2845 superClass = ParseLeftHandSideExpression(); 2846 } 2847 2848 ir::TSTypeParameterInstantiation *superTypeParams = nullptr; 2849 if (Extension() == ScriptExtension::TS && (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || 2850 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT)) { 2851 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 2852 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 2853 } 2854 2855 superTypeParams = ParseTsTypeParameterInstantiation(); 2856 } 2857 2858 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter()); 2859 if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IMPLEMENTS) { 2860 lexer_->NextToken(); 2861 2862 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 2863 lexer::SourcePosition implStart = lexer_->GetToken().Start(); 2864 2865 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 2866 ThrowSyntaxError("Identifier expected"); 2867 } 2868 2869 ir::Expression *expr = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 2870 expr->SetRange(lexer_->GetToken().Loc()); 2871 expr->AsIdentifier()->SetReference(); 2872 2873 lexer_->NextToken(); 2874 2875 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 2876 expr = ParseTsQualifiedReference(expr); 2877 } 2878 2879 ir::TSTypeParameterInstantiation *implTypeParams = nullptr; 2880 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 2881 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 2882 } 2883 2884 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || 2885 lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 2886 implTypeParams = ParseTsTypeParameterInstantiation(); 2887 } 2888 2889 auto *impl = AllocNode<ir::TSClassImplements>(expr, implTypeParams); 2890 impl->SetRange({implStart, lexer_->GetToken().End()}); 2891 implements.push_back(impl); 2892 2893 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 2894 lexer_->NextToken(); 2895 continue; 2896 } 2897 2898 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 2899 ThrowSyntaxError("',' expected"); 2900 } 2901 } 2902 2903 if (implements.empty()) { 2904 ThrowSyntaxError("Implements clause can not be empty"); 2905 } 2906 } 2907 2908 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 2909 ThrowSyntaxError("Unexpected token, expected '{'"); 2910 } 2911 2912 // Parse ClassBody 2913 auto savedStatus = context_.Status(); 2914 context_.Status() |= ParserStatus::IN_CLASS_BODY; 2915 context_.Status() &= ~(ParserStatus::CONSTRUCTOR_FUNCTION); 2916 lexer::SourcePosition classBodyStartLoc = lexer_->GetToken().Start(); 2917 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); 2918 2919 ir::MethodDefinition *ctor = nullptr; 2920 ArenaVector<ir::Statement *> properties(Allocator()->Adapter()); 2921 ArenaVector<ir::TSIndexSignature *> indexSignatures(Allocator()->Adapter()); 2922 bool hasConstructorFuncBody = false; 2923 bool isCtorContinuousDefined = true; 2924 2925 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 2926 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 2927 lexer_->NextToken(); 2928 continue; 2929 } 2930 2931 ir::Statement *property = ParseClassElement(properties, &indexSignatures, hasSuperClass, isDeclare, isAbstract); 2932 2933 if (property->IsEmptyStatement()) { 2934 continue; 2935 } 2936 2937 if (IsConstructor(property)) { 2938 if (!isDeclare && !isCtorContinuousDefined) { 2939 ThrowSyntaxError("Constructor implementation is missing.", property->Start()); 2940 } 2941 2942 if (hasConstructorFuncBody) { 2943 ThrowSyntaxError("Multiple constructor implementations are not allowed.", property->Start()); 2944 } 2945 ctor = property->AsMethodDefinition(); 2946 hasConstructorFuncBody = ctor->Value()->Function()->Body() != nullptr; 2947 continue; 2948 } 2949 isCtorContinuousDefined = ctor == nullptr; 2950 properties.push_back(property); 2951 } 2952 2953 context_.Status() = savedStatus; 2954 2955 lexer::SourcePosition classBodyEndLoc = lexer_->GetToken().End(); 2956 if (ctor == nullptr) { 2957 ctor = CreateImplicitConstructor(superClass, hasSuperClass, isDeclare); 2958 ctor->SetRange({startLoc, classBodyEndLoc}); 2959 hasConstructorFuncBody = !isDeclare; 2960 } 2961 lexer_->NextToken(); 2962 2963 ValidateClassConstructor(ctor, properties, superClass, isDeclare, hasConstructorFuncBody, hasSuperClass); 2964 2965 auto *classDefinition = AllocNode<ir::ClassDefinition>( 2966 classCtx.GetScope(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, 2967 std::move(properties), std::move(indexSignatures), isDeclare, isAbstract); 2968 2969 classDefinition->SetRange({classBodyStartLoc, classBodyEndLoc}); 2970 if (decl != nullptr) { 2971 decl->BindNode(classDefinition); 2972 } 2973 2974 return classDefinition; 2975 } 2976 ValidateClassConstructor(ir::MethodDefinition * ctor,ArenaVector<ir::Statement * > & properties,ir::Expression * superClass,bool isDeclare,bool hasConstructorFuncBody,bool hasSuperClass)2977 void ParserImpl::ValidateClassConstructor(ir::MethodDefinition *ctor, 2978 ArenaVector<ir::Statement *> &properties, 2979 ir::Expression *superClass, 2980 bool isDeclare, bool hasConstructorFuncBody, bool hasSuperClass) 2981 { 2982 if (!hasConstructorFuncBody) { 2983 if (isDeclare) { 2984 return; 2985 } 2986 ThrowSyntaxError("Constructor implementation is missing.", ctor->Start()); 2987 } 2988 2989 if (Extension() != ScriptExtension::TS || !hasSuperClass) { 2990 return; 2991 } 2992 2993 bool hasSuperCall = false; 2994 FindSuperCallInConstructor(ctor, &hasSuperCall); 2995 if (hasSuperCall) { 2996 if (superClass->IsNullLiteral()) { 2997 ThrowSyntaxError("A constructor cannot contain a super call when its class extends null.", ctor->Start()); 2998 } 2999 3000 if (SuperCallShouldBeFirst(ctor, properties)) { 3001 ir::Statement *firstStat = nullptr; 3002 ASSERT(ctor->Function()->Body()->IsBlockStatement()); 3003 ir::BlockStatement *blockStat = ctor->Function()->Body()->AsBlockStatement(); 3004 for (auto iter = blockStat->Statements().begin(); iter != blockStat->Statements().end();) { 3005 if ((*iter)->IsExpressionStatement() && 3006 (*iter)->AsExpressionStatement()->GetExpression()->IsStringLiteral()) { 3007 iter++; 3008 } else { 3009 firstStat = *iter; 3010 break; 3011 } 3012 } 3013 3014 if (firstStat == nullptr || !firstStat->IsExpressionStatement() || 3015 !firstStat->AsExpressionStatement()->GetExpression()->IsCallExpression() || 3016 !firstStat->AsExpressionStatement()->GetExpression()->AsCallExpression() 3017 ->Callee()->IsSuperExpression()) { 3018 ThrowSyntaxError("A super call must be the first statement in the constructor when a class contains " 3019 "initialized properties, parameter properties, or private identifiers.", 3020 ctor->Start()); 3021 } 3022 } 3023 } else if (!superClass->IsNullLiteral()) { 3024 ThrowSyntaxError("Constructors for derived classes must contain a super call.", ctor->Start()); 3025 } 3026 } 3027 SuperCallShouldBeFirst(ir::MethodDefinition * ctor,ArenaVector<ir::Statement * > & properties)3028 bool ParserImpl::SuperCallShouldBeFirst(ir::MethodDefinition *ctor, ArenaVector<ir::Statement *> &properties) 3029 { 3030 for (const auto *property : properties) { 3031 if (property->IsClassProperty() && (property->AsClassProperty()->Value() != nullptr || 3032 property->AsClassProperty()->Key()->IsTSPrivateIdentifier())) { 3033 return true; 3034 } 3035 } 3036 3037 for (const auto ¶m : ctor->Function()->Params()) { 3038 if (param->IsTSParameterProperty() && 3039 (param->AsTSParameterProperty()->Accessibility() != ir::AccessibilityOption::NO_OPTS || 3040 param->AsTSParameterProperty()->Readonly())) { 3041 return true; 3042 } 3043 } 3044 return false; 3045 } 3046 FindSuperCallInConstructor(const ir::AstNode * parent,bool * hasSuperCall)3047 void ParserImpl::FindSuperCallInConstructor(const ir::AstNode *parent, bool *hasSuperCall) 3048 { 3049 parent->Iterate([this, hasSuperCall](auto *childNode) { 3050 FindSuperCallInConstructorChildNode(childNode, hasSuperCall); 3051 }); 3052 } 3053 FindSuperCallInConstructorChildNode(const ir::AstNode * childNode,bool * hasSuperCall)3054 void ParserImpl::FindSuperCallInConstructorChildNode(const ir::AstNode *childNode, bool *hasSuperCall) 3055 { 3056 if (*hasSuperCall) { 3057 return; 3058 } 3059 switch (childNode->Type()) { 3060 case ir::AstNodeType::CALL_EXPRESSION: { 3061 if (childNode->AsCallExpression()->Callee()->IsSuperExpression()) { 3062 *hasSuperCall = true; 3063 } 3064 break; 3065 } 3066 case ir::AstNodeType::CLASS_DEFINITION: { 3067 break; 3068 } 3069 default: { 3070 FindSuperCallInConstructor(childNode, hasSuperCall); 3071 break; 3072 } 3073 } 3074 } 3075 ParseEnumMembers(ir::Identifier * key,const lexer::SourcePosition & enumStart,bool isExport,bool isDeclare,bool isConst)3076 ir::TSEnumDeclaration *ParserImpl::ParseEnumMembers(ir::Identifier *key, const lexer::SourcePosition &enumStart, 3077 bool isExport, bool isDeclare, bool isConst) 3078 { 3079 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 3080 ThrowSyntaxError("'{' expected"); 3081 } 3082 3083 ArenaVector<ir::TSEnumMember *> members(Allocator()->Adapter()); 3084 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); // eat '{' 3085 3086 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 3087 ir::Expression *memberKey = nullptr; 3088 const auto &keyStartLoc = lexer_->GetToken().Start(); 3089 binder::EnumDecl *decl {}; 3090 3091 if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 3092 memberKey = AllocNode<ir::Identifier>(lexer_->GetToken().Ident()); 3093 decl = Binder()->AddDecl<binder::EnumDecl>(keyStartLoc, isDeclare, lexer_->GetToken().Ident()); 3094 memberKey->SetRange(lexer_->GetToken().Loc()); 3095 lexer_->NextToken(); 3096 } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { 3097 memberKey = AllocNode<ir::StringLiteral>(lexer_->GetToken().String()); 3098 decl = Binder()->AddDecl<binder::EnumDecl>(keyStartLoc, isDeclare, lexer_->GetToken().String()); 3099 memberKey->SetRange(lexer_->GetToken().Loc()); 3100 lexer_->NextToken(); 3101 } else { 3102 ThrowSyntaxError("Unexpected token in enum member"); 3103 } 3104 3105 ir::Expression *memberInit = nullptr; 3106 lexer::SourcePosition initStart = lexer_->GetToken().Start(); 3107 3108 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 3109 lexer_->NextToken(); // eat '=' 3110 initStart = lexer_->GetToken().Start(); 3111 memberInit = ParseExpression(); 3112 } 3113 3114 auto *member = AllocNode<ir::TSEnumMember>(memberKey, memberInit); 3115 decl->BindNode(member); 3116 member->SetRange({initStart, lexer_->GetToken().End()}); 3117 members.push_back(member); 3118 3119 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 3120 lexer_->NextToken(lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT); // eat ',' 3121 } 3122 } 3123 3124 auto *enumDeclaration = AllocNode<ir::TSEnumDeclaration>( 3125 Binder()->GetScope()->AsTSEnumScope(), key, std::move(members), isExport, isDeclare, isConst); 3126 enumDeclaration->SetRange({enumStart, lexer_->GetToken().End()}); 3127 Binder()->GetScope()->BindNode(enumDeclaration); 3128 lexer_->NextToken(); // eat '}' 3129 3130 return enumDeclaration; 3131 } 3132 ParseEnumDeclaration(bool isExport,bool isDeclare,bool isConst)3133 ir::TSEnumDeclaration *ParserImpl::ParseEnumDeclaration(bool isExport, bool isDeclare, bool isConst) 3134 { 3135 ASSERT(lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ENUM); 3136 lexer::SourcePosition enumStart = lexer_->GetToken().Start(); 3137 lexer_->NextToken(); // eat enum keyword 3138 3139 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 3140 ThrowSyntaxError("Identifier expected"); 3141 } 3142 3143 const util::StringView &ident = lexer_->GetToken().Ident(); 3144 auto *currentScope = Binder()->GetScope(); 3145 binder::Variable *res = currentScope->FindLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident); 3146 if (res == nullptr && isExport && currentScope->IsTSModuleScope()) { 3147 res = currentScope->AsTSModuleScope()->FindExportTSVariable<binder::TSBindingType::ENUMLITERAL>(ident); 3148 if (res != nullptr) { 3149 currentScope->AddLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident, res); 3150 } 3151 } 3152 if (res == nullptr) { 3153 Binder()->AddTsDecl<binder::EnumLiteralDecl>(lexer_->GetToken().Start(), isDeclare, 3154 Allocator(), ident, isExport, isConst); 3155 res = currentScope->FindLocalTSVariable<binder::TSBindingType::ENUMLITERAL>(ident); 3156 if (isExport && currentScope->IsTSModuleScope()) { 3157 currentScope->AsTSModuleScope()->AddExportTSVariable<binder::TSBindingType::ENUMLITERAL>(ident, res); 3158 } 3159 res->AsEnumLiteralVariable()->SetEnumMembers(Allocator()->New<binder::VariableMap>(Allocator()->Adapter())); 3160 } 3161 binder::VariableMap *enumMemberBindings = res->AsEnumLiteralVariable()->GetEnumMembers(); 3162 3163 auto *key = AllocNode<ir::Identifier>(ident); 3164 key->SetRange(lexer_->GetToken().Loc()); 3165 key->SetReference(); 3166 lexer_->NextToken(); 3167 3168 if (!res->Declaration()->IsEnumLiteralDecl() || 3169 (isConst ^ res->Declaration()->AsEnumLiteralDecl()->IsConst())) { 3170 Binder()->ThrowRedeclaration(lexer_->GetToken().Start(), ident); 3171 } 3172 3173 auto enumCtx = binder::LexicalScope<binder::TSEnumScope>(Binder(), enumMemberBindings); 3174 auto *enumDeclaration = ParseEnumMembers(key, enumStart, isExport, isDeclare, isConst); 3175 res->Declaration()->AsEnumLiteralDecl()->Add(enumDeclaration); 3176 3177 return enumDeclaration; 3178 } 3179 ValidateFunctionParam(const ArenaVector<ir::Expression * > & params,const ir::Expression * parameter,bool * seenOptional)3180 void ParserImpl::ValidateFunctionParam(const ArenaVector<ir::Expression *> ¶ms, const ir::Expression *parameter, 3181 bool *seenOptional) 3182 { 3183 if (!parameter->IsIdentifier()) { 3184 context_.Status() |= ParserStatus::HAS_COMPLEX_PARAM; 3185 if (!parameter->IsRestElement()) { 3186 return; 3187 } 3188 3189 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 3190 const char *msg = (Extension() == ScriptExtension::JS ? "Rest parameter must be last formal parameter" 3191 : "A rest parameter must be last in parameter list"); 3192 ThrowSyntaxError(msg); 3193 } 3194 return; 3195 } 3196 3197 if (Extension() != ScriptExtension::TS) { 3198 return; 3199 } 3200 3201 bool currentIsOptinal = parameter->AsIdentifier()->IsOptional(); 3202 if (*seenOptional && !currentIsOptinal) { 3203 ThrowSyntaxError("A required parameter cannot follow an optional parameter"); 3204 } 3205 3206 *seenOptional |= currentIsOptinal; 3207 const util::StringView ¶mName = parameter->AsIdentifier()->Name(); 3208 3209 if (paramName.Is("this")) { 3210 if (!params.empty()) { 3211 ThrowSyntaxError("A 'this' parameter must be the first parameter"); 3212 } 3213 3214 if (context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) { 3215 ThrowSyntaxError("A constructor cannot have a 'this' parameter"); 3216 } 3217 3218 if (context_.Status() & ParserStatus::ARROW_FUNCTION) { 3219 ThrowSyntaxError("An arrow function cannot have a 'this' parameter"); 3220 } 3221 3222 if (context_.Status() & ParserStatus::ACCESSOR_FUNCTION) { 3223 ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters"); 3224 } 3225 } 3226 3227 if (paramName.Is("constructor") && (context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION)) { 3228 ThrowSyntaxError("'constructor' cannot be used as a parameter property name"); 3229 } 3230 } 3231 ParseFunctionParams(bool isDeclare,ArenaVector<ir::ParamDecorators> * paramDecorators)3232 ArenaVector<ir::Expression *> ParserImpl::ParseFunctionParams(bool isDeclare, 3233 ArenaVector<ir::ParamDecorators> *paramDecorators) 3234 { 3235 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 3236 lexer_->NextToken(); 3237 3238 ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 3239 bool seenOptional = false; 3240 3241 size_t index = 0; 3242 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 3243 if (context_.Status() & ParserStatus::IN_METHOD_DEFINITION) { 3244 auto decorators = ParseDecorators(); 3245 if (!decorators.empty()) { 3246 ASSERT(paramDecorators != nullptr); 3247 paramDecorators->push_back({index, std::move(decorators)}); 3248 } 3249 } 3250 3251 ir::Expression *parameter = ParseFunctionParameter(isDeclare); 3252 ValidateFunctionParam(params, parameter, &seenOptional); 3253 3254 params.push_back(parameter); 3255 3256 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 3257 lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 3258 ThrowSyntaxError(", expected"); 3259 } 3260 3261 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 3262 lexer_->NextToken(); 3263 } 3264 3265 index++; 3266 } 3267 3268 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); 3269 lexer_->NextToken(); 3270 3271 return params; 3272 } 3273 CheckTypeNameIsReserved(const util::StringView & paramName)3274 bool ParserImpl::CheckTypeNameIsReserved(const util::StringView ¶mName) 3275 { 3276 return paramName.Is("number") || paramName.Is("any") || paramName.Is("unknown") || paramName.Is("never") || 3277 paramName.Is("bigint") || paramName.Is("boolean") || paramName.Is("string") || paramName.Is("string") || 3278 paramName.Is("void") || paramName.Is("object"); 3279 } 3280 ParseTsTypeParameter(bool throwError,bool addBinding)3281 ir::TSTypeParameter *ParserImpl::ParseTsTypeParameter(bool throwError, bool addBinding) 3282 { 3283 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 3284 3285 if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 3286 if (!throwError) { 3287 return nullptr; 3288 } 3289 3290 ThrowSyntaxError("Type parameter declaration expected"); 3291 } 3292 3293 const auto &ident = lexer_->GetToken().Ident(); 3294 3295 if (CheckTypeNameIsReserved(ident)) { 3296 if (!throwError) { 3297 return nullptr; 3298 } 3299 3300 ThrowSyntaxError("Invalid type parameter name"); 3301 } 3302 3303 auto *paramIdent = AllocNode<ir::Identifier>(ident); 3304 3305 if (addBinding) { 3306 Binder()->AddDecl<binder::LetDecl>(lexer_->GetToken().Start(), false, ident); 3307 } 3308 3309 paramIdent->SetRange({lexer_->GetToken().Start(), lexer_->GetToken().End()}); 3310 3311 lexer_->NextToken(); 3312 3313 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 3314 3315 if (throwError) { 3316 options |= TypeAnnotationParsingOptions::THROW_ERROR; 3317 } 3318 3319 ir::Expression *constraint = nullptr; 3320 if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { 3321 lexer_->NextToken(); 3322 constraint = ParseTsTypeAnnotation(&options); 3323 } 3324 3325 ir::Expression *defaultType = nullptr; 3326 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 3327 lexer_->NextToken(); 3328 defaultType = ParseTsTypeAnnotation(&options); 3329 } 3330 3331 auto *typeParam = AllocNode<ir::TSTypeParameter>(paramIdent, constraint, defaultType); 3332 3333 typeParam->SetRange({startLoc, lexer_->GetToken().End()}); 3334 3335 return typeParam; 3336 } 3337 ParseTsTypeParameterDeclaration(bool throwError)3338 ir::TSTypeParameterDeclaration *ParserImpl::ParseTsTypeParameterDeclaration(bool throwError) 3339 { 3340 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN); 3341 3342 auto localCtx = binder::LexicalScope<binder::LocalScope>(Binder()); 3343 3344 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 3345 ArenaVector<ir::TSTypeParameter *> params(Allocator()->Adapter()); 3346 bool seenDefault = false; 3347 size_t requiredParams = 0; 3348 lexer_->NextToken(); // eat '<' 3349 3350 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) { 3351 ir::TSTypeParameter *currentParam = ParseTsTypeParameter(throwError, true); 3352 3353 if (!currentParam) { 3354 ASSERT(!throwError); 3355 return nullptr; 3356 } 3357 3358 if (currentParam->DefaultType()) { 3359 seenDefault = true; 3360 } else if (seenDefault) { 3361 ThrowSyntaxError("Required type parameters may not follow optional type parameters."); 3362 } else { 3363 requiredParams++; 3364 } 3365 3366 params.push_back(currentParam); 3367 3368 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 3369 lexer_->NextToken(); 3370 continue; 3371 } 3372 3373 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) { 3374 if (!throwError) { 3375 return nullptr; 3376 } 3377 3378 ThrowSyntaxError("'>' expected"); 3379 } 3380 } 3381 3382 if (params.empty()) { 3383 ThrowSyntaxError("Type parameter list cannot be empty."); 3384 } 3385 3386 lexer::SourcePosition endLoc = lexer_->GetToken().End(); 3387 lexer_->NextToken(); // eat '>' 3388 3389 auto *typeParamDecl = 3390 AllocNode<ir::TSTypeParameterDeclaration>(localCtx.GetScope(), std::move(params), requiredParams); 3391 typeParamDecl->SetRange({startLoc, endLoc}); 3392 localCtx.GetScope()->BindNode(typeParamDecl); 3393 3394 return typeParamDecl; 3395 } 3396 ParseTsTypeParameterInstantiation(bool throwError)3397 ir::TSTypeParameterInstantiation *ParserImpl::ParseTsTypeParameterInstantiation(bool throwError) 3398 { 3399 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN); 3400 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 3401 ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 3402 lexer_->NextToken(); // eat '<' 3403 3404 while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) { 3405 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 3406 3407 if (throwError) { 3408 options |= TypeAnnotationParsingOptions::THROW_ERROR; 3409 } 3410 3411 ir::Expression *currentParam = ParseTsTypeAnnotation(&options); 3412 3413 if (!currentParam) { 3414 return nullptr; 3415 } 3416 3417 params.push_back(currentParam); 3418 3419 switch (lexer_->GetToken().Type()) { 3420 case lexer::TokenType::PUNCTUATOR_COMMA: { 3421 lexer_->NextToken(); 3422 continue; 3423 } 3424 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: { 3425 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 1); 3426 break; 3427 } 3428 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: { 3429 lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 2); 3430 break; 3431 } 3432 case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { 3433 break; 3434 } 3435 default: { 3436 if (throwError) { 3437 ThrowSyntaxError("'>' expected"); 3438 } 3439 3440 return nullptr; 3441 } 3442 } 3443 } 3444 3445 lexer::SourcePosition endLoc = lexer_->GetToken().End(); 3446 lexer_->NextToken(); 3447 3448 auto *typeParamInst = AllocNode<ir::TSTypeParameterInstantiation>(std::move(params)); 3449 3450 typeParamInst->SetRange({startLoc, endLoc}); 3451 3452 return typeParamInst; 3453 } 3454 ParseFunction(ParserStatus newStatus,bool isDeclare,ArenaVector<ir::ParamDecorators> * paramDecorators)3455 ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus, 3456 bool isDeclare, 3457 ArenaVector<ir::ParamDecorators> *paramDecorators) 3458 { 3459 FunctionContext functionContext(this, newStatus | ParserStatus::FUNCTION | ParserStatus::ALLOW_NEW_TARGET); 3460 3461 FunctionParameterContext funcParamContext(&context_, Binder()); 3462 auto *funcParamScope = funcParamContext.LexicalScope().GetScope(); 3463 3464 lexer::SourcePosition startLoc = lexer_->GetToken().Start(); 3465 3466 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 3467 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 3468 typeParamDecl = ParseTsTypeParameterDeclaration(); 3469 } 3470 3471 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 3472 ThrowSyntaxError("Unexpected token, expected '('"); 3473 } 3474 3475 if (newStatus & (ParserStatus::ASYNC_FUNCTION | ParserStatus::FUNCTION_DECLARATION)) { 3476 context_.Status() |= ParserStatus::DISALLOW_AWAIT; 3477 } 3478 3479 ArenaVector<ir::Expression *> params = ParseFunctionParams(isDeclare, paramDecorators); 3480 3481 ir::Expression *returnTypeAnnotation = nullptr; 3482 3483 if (Extension() == ScriptExtension::TS && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 3484 lexer_->NextToken(); // eat ':' 3485 TypeAnnotationParsingOptions options = 3486 TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 3487 returnTypeAnnotation = ParseTsTypeAnnotation(&options); 3488 } 3489 3490 auto functionCtx = binder::LexicalScope<binder::FunctionScope>(Binder()); 3491 auto *functionScope = functionCtx.GetScope(); 3492 functionScope->BindParamScope(funcParamScope); 3493 funcParamScope->BindFunctionScope(functionScope); 3494 3495 ir::BlockStatement *body = nullptr; 3496 lexer::SourcePosition endLoc = lexer_->GetToken().End(); 3497 bool letDeclare = true; 3498 3499 if (newStatus & ParserStatus::ASYNC_FUNCTION) { 3500 context_.Status() &= ~ParserStatus::DISALLOW_AWAIT; 3501 } else { 3502 context_.Status() |= ParserStatus::DISALLOW_AWAIT; 3503 } 3504 3505 if (newStatus & ParserStatus::GENERATOR_FUNCTION) { 3506 context_.Status() |= ParserStatus::ALLOW_YIELD; 3507 } 3508 3509 if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 3510 if (Extension() == ScriptExtension::TS && (newStatus & ParserStatus::FUNCTION_DECLARATION)) { 3511 ValidateTsFunctionOverloadParams(params); 3512 functionContext.AddFlag(ir::ScriptFunctionFlags::OVERLOAD); 3513 } else if (!isDeclare && !(context_.Status() & ParserStatus::IN_METHOD_DEFINITION)) { 3514 ThrowSyntaxError("Unexpected token, expected '{'"); 3515 } else { 3516 letDeclare = false; 3517 functionContext.AddFlag(ir::ScriptFunctionFlags::OVERLOAD); 3518 } 3519 } else if (isDeclare) { 3520 ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); 3521 } else { 3522 body = ParseBlockStatement(functionScope); 3523 endLoc = body->End(); 3524 } 3525 3526 auto *funcNode = 3527 AllocNode<ir::ScriptFunction>(functionScope, std::move(params), typeParamDecl, body, returnTypeAnnotation, 3528 functionContext.Flags(), isDeclare && letDeclare, 3529 Extension() == ScriptExtension::TS); 3530 functionScope->BindNode(funcNode); 3531 funcParamScope->BindNode(funcNode); 3532 funcNode->SetRange({startLoc, endLoc}); 3533 3534 return funcNode; 3535 } 3536 ValidateTsFunctionOverloadParams(const ArenaVector<ir::Expression * > & params)3537 void ParserImpl::ValidateTsFunctionOverloadParams(const ArenaVector<ir::Expression *> ¶ms) 3538 { 3539 for (auto *it : params) { 3540 if (it->IsAssignmentPattern()) { 3541 ThrowSyntaxError( 3542 "A parameter initializer is only allowed in a function " 3543 "or constructor implementation.", 3544 it->Start()); 3545 } 3546 } 3547 } 3548 ParseSpreadElement(ExpressionParseFlags flags)3549 ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags) 3550 { 3551 ASSERT(lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD); 3552 lexer::SourcePosition startLocation = lexer_->GetToken().Start(); 3553 bool inPattern = (flags & ExpressionParseFlags::MUST_BE_PATTERN); 3554 lexer_->NextToken(); 3555 3556 ir::Expression *argument {}; 3557 if (inPattern) { 3558 argument = ParsePatternElement(ExpressionParseFlags::IN_REST); 3559 if ((flags & ExpressionParseFlags::OBJECT_PATTERN) && !argument->IsIdentifier()) { 3560 ThrowSyntaxError("RestParameter must be followed by an identifier in declaration contexts"); 3561 } 3562 } else { 3563 argument = ParseExpression(flags); 3564 } 3565 3566 ir::Expression *typeAnnotation = nullptr; 3567 3568 if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 3569 lexer_->NextToken(); // eat ':' 3570 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; 3571 typeAnnotation = ParseTsTypeAnnotation(&options); 3572 } 3573 3574 if (inPattern && argument->IsAssignmentExpression()) { 3575 ThrowSyntaxError("RestParameter does not support an initializer"); 3576 } 3577 3578 lexer::SourcePosition endLoc = typeAnnotation ? typeAnnotation->End() : argument->End(); 3579 3580 auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT; 3581 auto *spreadElementNode = AllocNode<ir::SpreadElement>(nodeType, argument); 3582 spreadElementNode->SetRange({startLocation, endLoc}); 3583 3584 if (typeAnnotation) { 3585 spreadElementNode->SetTsTypeAnnotation(typeAnnotation); 3586 } 3587 3588 return spreadElementNode; 3589 } 3590 CreateTsParameterProperty(ir::Expression * parameter,ir::ModifierFlags modifiers)3591 ir::TSParameterProperty *ParserImpl::CreateTsParameterProperty(ir::Expression *parameter, ir::ModifierFlags modifiers) 3592 { 3593 auto accessibility = ir::AccessibilityOption::NO_OPTS; 3594 bool readonly = false; 3595 bool isStatic = false; 3596 bool isExport = false; 3597 3598 if (modifiers & ir::ModifierFlags::PRIVATE) { 3599 accessibility = ir::AccessibilityOption::PRIVATE; 3600 } else if ((modifiers & ir::ModifierFlags::PUBLIC)) { 3601 accessibility = ir::AccessibilityOption::PUBLIC; 3602 } else if (modifiers & ir::ModifierFlags::PROTECTED) { 3603 accessibility = ir::AccessibilityOption::PROTECTED; 3604 } 3605 3606 if (modifiers & ir::ModifierFlags::READONLY) { 3607 readonly = true; 3608 } 3609 3610 if (modifiers & ir::ModifierFlags::STATIC) { 3611 isStatic = true; 3612 } 3613 3614 // TODO(Csaba Repasi): Handle export property of TSParameterProperty 3615 3616 return AllocNode<ir::TSParameterProperty>(accessibility, parameter, readonly, isStatic, isExport); 3617 } 3618 ParseFunctionParameter(bool isDeclare)3619 ir::Expression *ParserImpl::ParseFunctionParameter(bool isDeclare) 3620 { 3621 if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_THIS) { 3622 lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); 3623 } 3624 3625 lexer::SourcePosition parameterStart = lexer_->GetToken().Start(); 3626 ir::ModifierFlags modifiers = ParseModifiers(); 3627 // TODO(Csaba Repasi): throw error if using strick mode reserved keyword here 3628 if (!(context_.Status() & ParserStatus::CONSTRUCTOR_FUNCTION) && modifiers != ir::ModifierFlags::NONE) { 3629 ThrowSyntaxError("A parameter property is only allowed in a constructor implementation.", parameterStart); 3630 } 3631 3632 lexer::TokenType tokenType = lexer_->GetToken().Type(); 3633 if (tokenType == lexer::TokenType::LITERAL_IDENT && 3634 (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ARGUMENTS || 3635 lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_EVAL)) { 3636 ThrowSyntaxError( 3637 "'eval' or 'arguments' can't be defined or assigned to " 3638 "in strict mode code", 3639 lexer_->GetToken().Start()); 3640 } 3641 3642 ir::Expression *functionParameter = ParsePatternElement(ExpressionParseFlags::NO_OPTS, true, isDeclare); 3643 3644 if (modifiers != ir::ModifierFlags::NONE && functionParameter->IsRestElement()) { 3645 ThrowSyntaxError("A parameter property cannot be declared using a rest parameter.", parameterStart); 3646 } 3647 3648 if (modifiers != ir::ModifierFlags::NONE && 3649 (functionParameter->IsArrayPattern() || functionParameter->IsObjectPattern() || 3650 (functionParameter->IsAssignmentPattern() && 3651 (functionParameter->AsAssignmentPattern()->Left()->IsArrayPattern() || 3652 functionParameter->AsAssignmentPattern()->Left()->IsObjectPattern())))) { 3653 ThrowSyntaxError("A parameter property may not be declared using a binding pattern.", parameterStart); 3654 } 3655 3656 if (modifiers != ir::ModifierFlags::NONE) { 3657 functionParameter = CreateTsParameterProperty(functionParameter, modifiers); 3658 functionParameter->SetRange({parameterStart, functionParameter->AsTSParameterProperty()->Parameter()->End()}); 3659 } 3660 3661 Binder()->AddParamDecl(functionParameter); 3662 3663 return functionParameter; 3664 } 3665 ValidateLvalueAssignmentTarget(ir::Expression * node) const3666 void ParserImpl::ValidateLvalueAssignmentTarget(ir::Expression *node) const 3667 { 3668 switch (node->Type()) { 3669 case ir::AstNodeType::IDENTIFIER: { 3670 // Check the prevoius ident name 3671 if (node->AsIdentifier()->Name().Is("arguments")) { 3672 ThrowSyntaxError("Assigning to 'arguments' in strict mode is invalid"); 3673 } else if (node->AsIdentifier()->Name().Is("eval")) { 3674 ThrowSyntaxError("Assigning to 'eval' in strict mode is invalid"); 3675 } 3676 break; 3677 } 3678 case ir::AstNodeType::MEMBER_EXPRESSION: { 3679 break; 3680 } 3681 case ir::AstNodeType::TS_AS_EXPRESSION: { 3682 ValidateLvalueAssignmentTarget(node->AsTSAsExpression()->Expr()); 3683 break; 3684 } 3685 case ir::AstNodeType::TS_TYPE_ASSERTION: { 3686 ValidateLvalueAssignmentTarget(node->AsTSTypeAssertion()->GetExpression()); 3687 break; 3688 } 3689 default: { 3690 ThrowSyntaxError("Invalid left-hand side in assignment expression"); 3691 } 3692 } 3693 } 3694 ValidateAssignmentTarget(ExpressionParseFlags flags,ir::Expression * node)3695 void ParserImpl::ValidateAssignmentTarget(ExpressionParseFlags flags, ir::Expression *node) 3696 { 3697 switch (node->Type()) { 3698 case ir::AstNodeType::ARRAY_PATTERN: 3699 case ir::AstNodeType::OBJECT_PATTERN: { 3700 break; 3701 } 3702 case ir::AstNodeType::ARRAY_EXPRESSION: 3703 case ir::AstNodeType::OBJECT_EXPRESSION: { 3704 if (flags & ExpressionParseFlags::POTENTIALLY_IN_PATTERN) { 3705 return; 3706 } 3707 3708 [[fallthrough]]; 3709 } 3710 default: { 3711 return ValidateLvalueAssignmentTarget(node); 3712 } 3713 } 3714 } 3715 ValidateArrowParameterBindings(const ir::Expression * node)3716 void ParserImpl::ValidateArrowParameterBindings(const ir::Expression *node) 3717 { 3718 switch (node->Type()) { 3719 case ir::AstNodeType::IDENTIFIER: { 3720 const util::StringView &identifier = node->AsIdentifier()->Name(); 3721 3722 if (context_.IsAsync() && identifier.Is("await")) { 3723 ThrowSyntaxError("'await' in formal parameter is invalid.", node->Start()); 3724 } 3725 break; 3726 } 3727 case ir::AstNodeType::OMITTED_EXPRESSION: { 3728 break; 3729 } 3730 case ir::AstNodeType::REST_ELEMENT: { 3731 ValidateArrowParameterBindings(node->AsRestElement()->Argument()); 3732 break; 3733 } 3734 case ir::AstNodeType::PROPERTY: { 3735 break; 3736 } 3737 case ir::AstNodeType::OBJECT_PATTERN: { 3738 const auto &props = node->AsObjectPattern()->Properties(); 3739 3740 for (auto *it : props) { 3741 ValidateArrowParameterBindings(it); 3742 } 3743 break; 3744 } 3745 case ir::AstNodeType::ARRAY_PATTERN: { 3746 const auto &elements = node->AsArrayPattern()->Elements(); 3747 3748 for (auto *it : elements) { 3749 ValidateArrowParameterBindings(it); 3750 } 3751 break; 3752 } 3753 case ir::AstNodeType::ASSIGNMENT_PATTERN: { 3754 ValidateArrowParameterBindings(node->AsAssignmentPattern()->Left()); 3755 break; 3756 } 3757 default: { 3758 ThrowSyntaxError("Unexpected ArrowParameter element"); 3759 } 3760 } 3761 } 3762 CurrentTokenIsModifier(char32_t nextCp) const3763 bool ParserImpl::CurrentTokenIsModifier(char32_t nextCp) const 3764 { 3765 return (Extension() == ScriptExtension::TS && 3766 (nextCp != LEX_CHAR_EQUALS || nextCp != LEX_CHAR_SEMICOLON || nextCp != LEX_CHAR_LEFT_PAREN)); 3767 } 3768 ThrowParameterModifierError(ir::ModifierFlags status) const3769 void ParserImpl::ThrowParameterModifierError(ir::ModifierFlags status) const 3770 { 3771 ThrowSyntaxError( 3772 {"'", (status & ir::ModifierFlags::STATIC) ? "static" : ((status & ir::ModifierFlags::ASYNC) ? "async" : "declare") , 3773 "' modifier cannot appear on a parameter."}, 3774 lexer_->GetToken().Start()); 3775 } 3776 ThrowSyntaxError(std::string_view errorMessage) const3777 void ParserImpl::ThrowSyntaxError(std::string_view errorMessage) const 3778 { 3779 ThrowSyntaxError(errorMessage, lexer_->GetToken().Start()); 3780 } 3781 ThrowSyntaxError(std::initializer_list<std::string_view> list) const3782 void ParserImpl::ThrowSyntaxError(std::initializer_list<std::string_view> list) const 3783 { 3784 ThrowSyntaxError(list, lexer_->GetToken().Start()); 3785 } 3786 ThrowSyntaxError(std::initializer_list<std::string_view> list,const lexer::SourcePosition & pos) const3787 void ParserImpl::ThrowSyntaxError(std::initializer_list<std::string_view> list, const lexer::SourcePosition &pos) const 3788 { 3789 std::stringstream ss; 3790 3791 for (const auto &it : list) { 3792 ss << it; 3793 } 3794 3795 std::string err = ss.str(); 3796 3797 ThrowSyntaxError(std::string_view {err}, pos); 3798 } 3799 ThrowSyntaxError(std::string_view errorMessage,const lexer::SourcePosition & pos) const3800 void ParserImpl::ThrowSyntaxError(std::string_view errorMessage, const lexer::SourcePosition &pos) const 3801 { 3802 lexer::LineIndex index(program_.SourceCode()); 3803 lexer::SourceLocation loc = index.GetLocation(pos); 3804 3805 throw Error {ErrorType::SYNTAX, errorMessage, loc.line, loc.col}; 3806 } 3807 Extension() const3808 ScriptExtension ParserImpl::Extension() const 3809 { 3810 return program_.Extension(); 3811 } 3812 GetSourceTextModuleRecord()3813 parser::SourceTextModuleRecord *ParserImpl::GetSourceTextModuleRecord() 3814 { 3815 return Binder()->Program()->ModuleRecord(); 3816 } 3817 GetSourceTextTypeModuleRecord()3818 parser::SourceTextModuleRecord *ParserImpl::GetSourceTextTypeModuleRecord() 3819 { 3820 return Binder()->Program()->TypeModuleRecord(); 3821 } 3822 AddPatchFixHelper(util::PatchFix * patchFixHelper)3823 void ParserImpl::AddPatchFixHelper(util::PatchFix *patchFixHelper) 3824 { 3825 program_.AddPatchFixHelper(patchFixHelper); 3826 } 3827 IsDtsFile() const3828 bool ParserImpl::IsDtsFile() const 3829 { 3830 return program_.IsDtsFile(); 3831 } 3832 CheckStrictReservedWord() const3833 void ParserImpl::CheckStrictReservedWord() const 3834 { 3835 if (Extension() == ScriptExtension::JS) { 3836 if (lexer_->GetToken().IsJsStrictReservedWord()) { 3837 ThrowSyntaxError("Unexpected reserved word in strict mode."); 3838 } 3839 } else { 3840 if (lexer_->GetToken().KeywordType() >= lexer::TokenType::KEYW_ARGUMENTS) { 3841 ThrowSyntaxError("Unexpected reserved word in strict mode."); 3842 } 3843 } 3844 } 3845 3846 } // namespace panda::es2panda::parser 3847