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