1/** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ETSparser.h" 17#include "ETSNolintParser.h" 18#include <utility> 19 20#include "macros.h" 21#include "parser/parserFlags.h" 22#include "parser/parserStatusContext.h" 23#include "util/helpers.h" 24#include "util/language.h" 25#include "utils/arena_containers.h" 26#include "varbinder/varbinder.h" 27#include "varbinder/ETSBinder.h" 28#include "lexer/lexer.h" 29#include "lexer/ETSLexer.h" 30#include "checker/types/ets/etsEnumType.h" 31#include "ir/astNode.h" 32#include "ir/base/classDefinition.h" 33#include "ir/base/decorator.h" 34#include "ir/base/catchClause.h" 35#include "ir/base/classProperty.h" 36#include "ir/base/scriptFunction.h" 37#include "ir/base/methodDefinition.h" 38#include "ir/base/classStaticBlock.h" 39#include "ir/base/spreadElement.h" 40#include "ir/expressions/identifier.h" 41#include "ir/expressions/functionExpression.h" 42#include "ir/expressions/dummyNode.h" 43#include "ir/module/importDeclaration.h" 44#include "ir/module/importDefaultSpecifier.h" 45#include "ir/module/importSpecifier.h" 46#include "ir/module/exportSpecifier.h" 47#include "ir/module/exportNamedDeclaration.h" 48#include "ir/statements/assertStatement.h" 49#include "ir/statements/blockStatement.h" 50#include "ir/statements/ifStatement.h" 51#include "ir/statements/labelledStatement.h" 52#include "ir/statements/namespaceDeclaration.h" 53#include "ir/statements/switchStatement.h" 54#include "ir/statements/throwStatement.h" 55#include "ir/statements/tryStatement.h" 56#include "ir/statements/whileStatement.h" 57#include "ir/statements/forOfStatement.h" 58#include "ir/statements/doWhileStatement.h" 59#include "ir/statements/breakStatement.h" 60#include "ir/statements/debuggerStatement.h" 61#include "ir/ets/etsLaunchExpression.h" 62#include "ir/ets/etsClassLiteral.h" 63#include "ir/ets/etsPrimitiveType.h" 64#include "ir/ets/etsPackageDeclaration.h" 65#include "ir/ets/etsReExportDeclaration.h" 66#include "ir/ets/etsWildcardType.h" 67#include "ir/ets/etsNewArrayInstanceExpression.h" 68#include "ir/ets/etsTuple.h" 69#include "ir/ets/etsFunctionType.h" 70#include "ir/ets/etsNewClassInstanceExpression.h" 71#include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" 72#include "ir/ets/etsScript.h" 73#include "ir/ets/etsTypeReference.h" 74#include "ir/ets/etsTypeReferencePart.h" 75#include "ir/ets/etsNullishTypes.h" 76#include "ir/ets/etsUnionType.h" 77#include "ir/ets/etsImportSource.h" 78#include "ir/ets/etsImportDeclaration.h" 79#include "ir/ets/etsStructDeclaration.h" 80#include "ir/ets/etsParameterExpression.h" 81#include "ir/module/importNamespaceSpecifier.h" 82#include "ir/ts/tsAsExpression.h" 83#include "ir/ts/tsInterfaceDeclaration.h" 84#include "ir/ts/tsEnumDeclaration.h" 85#include "ir/ts/tsTypeParameterInstantiation.h" 86#include "ir/ts/tsInterfaceBody.h" 87#include "ir/ts/tsImportEqualsDeclaration.h" 88#include "ir/ts/tsArrayType.h" 89#include "ir/ts/tsQualifiedName.h" 90#include "ir/ts/tsTypeReference.h" 91#include "ir/ts/tsTypeParameter.h" 92#include "ir/ts/tsInterfaceHeritage.h" 93#include "ir/ts/tsFunctionType.h" 94#include "ir/ts/tsClassImplements.h" 95#include "ir/ts/tsEnumMember.h" 96#include "ir/ts/tsTypeAliasDeclaration.h" 97#include "ir/ts/tsTypeParameterDeclaration.h" 98#include "ir/ts/tsNonNullExpression.h" 99#include "ir/ts/tsThisType.h" 100#include "generated/signatures.h" 101 102namespace ark::es2panda::parser { 103class FunctionContext; 104 105using namespace std::literals::string_literals; 106 107static bool IsClassModifier(lexer::TokenType type) 108{ 109 return type == lexer::TokenType::KEYW_STATIC || type == lexer::TokenType::KEYW_ABSTRACT || 110 type == lexer::TokenType::KEYW_FINAL; 111} 112 113ir::ModifierFlags ETSParser::ParseClassModifiers() 114{ 115 ir::ModifierFlags flags = ir::ModifierFlags::NONE; 116 117 while (IsClassModifier(Lexer()->GetToken().KeywordType())) { 118 ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; 119 120 lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); 121 if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { 122 ThrowSyntaxError("Keyword must not contain escaped characters"); 123 } 124 125 switch (Lexer()->GetToken().KeywordType()) { 126 case lexer::TokenType::KEYW_STATIC: { 127 currentFlag = ir::ModifierFlags::STATIC; 128 break; 129 } 130 case lexer::TokenType::KEYW_FINAL: { 131 currentFlag = ir::ModifierFlags::FINAL; 132 break; 133 } 134 case lexer::TokenType::KEYW_ABSTRACT: { 135 currentFlag = ir::ModifierFlags::ABSTRACT; 136 break; 137 } 138 default: { 139 UNREACHABLE(); 140 } 141 } 142 143 if ((flags & currentFlag) != 0) { 144 ThrowSyntaxError("Duplicated modifier is not allowed"); 145 } 146 147 Lexer()->NextToken(); 148 flags |= currentFlag; 149 } 150 151 return flags; 152} 153 154std::tuple<ir::Expression *, ir::TSTypeParameterInstantiation *> ETSParser::ParseClassImplementsElement() 155{ 156 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | 157 TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | 158 TypeAnnotationParsingOptions::ALLOW_WILDCARD; 159 return {ParseTypeReference(&options), nullptr}; 160} 161 162ir::Expression *ETSParser::ParseSuperClassReference() 163{ 164 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { 165 Lexer()->NextToken(); 166 167 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | 168 TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | 169 TypeAnnotationParsingOptions::ALLOW_WILDCARD; 170 return ParseTypeReference(&options); 171 } 172 173 return nullptr; 174} 175 176ir::TypeNode *ETSParser::ParseInterfaceExtendsElement() 177{ 178 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | 179 TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | 180 TypeAnnotationParsingOptions::ALLOW_WILDCARD; 181 return ParseTypeReference(&options); 182} 183 184static bool IsClassMemberAccessModifier(lexer::TokenType type) 185{ 186 return type == lexer::TokenType::KEYW_PUBLIC || type == lexer::TokenType::KEYW_PRIVATE || 187 type == lexer::TokenType::KEYW_PROTECTED || type == lexer::TokenType::KEYW_INTERNAL; 188} 189 190std::tuple<ir::ModifierFlags, bool> ETSParser::ParseClassMemberAccessModifiers() 191{ 192 if (!IsClassMemberAccessModifier(Lexer()->GetToken().Type())) { 193 return {ir::ModifierFlags::PUBLIC, false}; 194 } 195 196 char32_t nextCp = Lexer()->Lookahead(); 197 if (!(nextCp != lexer::LEX_CHAR_EQUALS && nextCp != lexer::LEX_CHAR_COLON && 198 nextCp != lexer::LEX_CHAR_LEFT_PAREN)) { 199 return {ir::ModifierFlags::NONE, false}; 200 } 201 202 lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); 203 if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { 204 ThrowSyntaxError("Keyword must not contain escaped characters"); 205 } 206 207 ir::ModifierFlags accessFlag = ir::ModifierFlags::NONE; 208 209 switch (Lexer()->GetToken().KeywordType()) { 210 case lexer::TokenType::KEYW_PUBLIC: { 211 accessFlag = ir::ModifierFlags::PUBLIC; 212 break; 213 } 214 case lexer::TokenType::KEYW_PRIVATE: { 215 accessFlag = ir::ModifierFlags::PRIVATE; 216 break; 217 } 218 case lexer::TokenType::KEYW_PROTECTED: { 219 accessFlag = ir::ModifierFlags::PROTECTED; 220 break; 221 } 222 case lexer::TokenType::KEYW_INTERNAL: { 223 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 224 if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_PROTECTED) { 225 accessFlag = ir::ModifierFlags::INTERNAL; 226 return {accessFlag, true}; 227 } 228 accessFlag = ir::ModifierFlags::INTERNAL_PROTECTED; 229 break; 230 } 231 default: { 232 UNREACHABLE(); 233 } 234 } 235 if (((GetContext().Status() & ParserStatus::FUNCTION) != 0) && 236 (accessFlag == ir::ModifierFlags::PUBLIC || accessFlag == ir::ModifierFlags::PRIVATE || 237 accessFlag == ir::ModifierFlags::PROTECTED)) { 238 ThrowSyntaxError("Local class declaration members can not have access modifies", Lexer()->GetToken().Start()); 239 } 240 241 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 242 return {accessFlag, true}; 243} 244 245static bool IsClassFieldModifier(lexer::TokenType type) 246{ 247 return type == lexer::TokenType::KEYW_STATIC || type == lexer::TokenType::KEYW_READONLY; 248} 249 250ir::ModifierFlags ETSParser::ParseClassFieldModifiers(bool seenStatic) 251{ 252 ir::ModifierFlags flags = seenStatic ? ir::ModifierFlags::STATIC : ir::ModifierFlags::NONE; 253 254 while (IsClassFieldModifier(Lexer()->GetToken().KeywordType())) { 255 char32_t nextCp = Lexer()->Lookahead(); 256 if (!(nextCp != lexer::LEX_CHAR_EQUALS && nextCp != lexer::LEX_CHAR_COLON)) { 257 return flags; 258 } 259 260 ir::ModifierFlags currentFlag; 261 262 lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); 263 if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { 264 ThrowSyntaxError("Keyword must not contain escaped characters"); 265 } 266 267 switch (Lexer()->GetToken().KeywordType()) { 268 case lexer::TokenType::KEYW_STATIC: { 269 currentFlag = ir::ModifierFlags::STATIC; 270 break; 271 } 272 case lexer::TokenType::KEYW_READONLY: { 273 currentFlag = ir::ModifierFlags::READONLY; 274 break; 275 } 276 default: { 277 UNREACHABLE(); 278 } 279 } 280 281 if ((flags & currentFlag) != 0) { 282 ThrowSyntaxError("Duplicated modifier is not allowed"); 283 } 284 285 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 286 flags |= currentFlag; 287 } 288 289 return flags; 290} 291 292bool ETSParser::IsClassMethodModifier(lexer::TokenType type) noexcept 293{ 294 switch (type) { 295 case lexer::TokenType::KEYW_STATIC: 296 case lexer::TokenType::KEYW_FINAL: 297 case lexer::TokenType::KEYW_NATIVE: 298 case lexer::TokenType::KEYW_ASYNC: 299 case lexer::TokenType::KEYW_OVERRIDE: 300 case lexer::TokenType::KEYW_ABSTRACT: { 301 return true; 302 } 303 default: { 304 break; 305 } 306 } 307 308 return false; 309} 310 311// Helper method for ir::ModifierFlags ETSParser::ParseClassMethodModifiers(bool seenStatic) 312ir::ModifierFlags ETSParser::ParseClassMethodModifierFlag() 313{ 314 ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; 315 316 switch (Lexer()->GetToken().KeywordType()) { 317 case lexer::TokenType::KEYW_STATIC: { 318 currentFlag = ir::ModifierFlags::STATIC; 319 break; 320 } 321 case lexer::TokenType::KEYW_FINAL: { 322 currentFlag = ir::ModifierFlags::FINAL; 323 break; 324 } 325 case lexer::TokenType::KEYW_NATIVE: { 326 currentFlag = ir::ModifierFlags::NATIVE; 327 break; 328 } 329 case lexer::TokenType::KEYW_ASYNC: { 330 currentFlag = ir::ModifierFlags::ASYNC; 331 break; 332 } 333 case lexer::TokenType::KEYW_OVERRIDE: { 334 currentFlag = ir::ModifierFlags::OVERRIDE; 335 break; 336 } 337 case lexer::TokenType::KEYW_ABSTRACT: { 338 currentFlag = ir::ModifierFlags::ABSTRACT; 339 break; 340 } 341 case lexer::TokenType::KEYW_DECLARE: { 342 currentFlag = ir::ModifierFlags::DECLARE; 343 break; 344 } 345 default: { 346 UNREACHABLE(); 347 } 348 } 349 350 return currentFlag; 351} 352 353ir::ModifierFlags ETSParser::ParseClassMethodModifiers(bool seenStatic) 354{ 355 ir::ModifierFlags flags = seenStatic ? ir::ModifierFlags::STATIC : ir::ModifierFlags::NONE; 356 357 while (IsClassMethodModifier(Lexer()->GetToken().KeywordType())) { 358 char32_t nextCp = Lexer()->Lookahead(); 359 if (!(nextCp != lexer::LEX_CHAR_LEFT_PAREN)) { 360 return flags; 361 } 362 363 ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; 364 365 lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); 366 if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { 367 ThrowSyntaxError("Keyword must not contain escaped characters"); 368 } 369 370 currentFlag = ParseClassMethodModifierFlag(); 371 if ((flags & currentFlag) != 0) { 372 ThrowSyntaxError("Duplicated modifier is not allowed"); 373 } 374 375 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 376 flags |= currentFlag; 377 if ((flags & ir::ModifierFlags::ASYNC) != 0) { 378 if ((flags & ir::ModifierFlags::NATIVE) != 0) { 379 ThrowSyntaxError("Native method cannot be async"); 380 } else if ((flags & ir::ModifierFlags::ABSTRACT) != 0) { 381 ThrowSyntaxError("Abstract method cannot be async"); 382 } 383 } 384 } 385 386 return flags; 387} 388 389// NOLINTNEXTLINE(google-default-arguments) 390void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::ModifierFlags modifiers, 391 ArenaVector<ir::AstNode *> *declarations) 392{ 393 lexer::SourcePosition endLoc = fieldName->End(); 394 ir::TypeNode *typeAnnotation = nullptr; 395 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 396 bool optionalField = false; 397 398 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 399 Lexer()->NextToken(); // eat '?' 400 optionalField = true; 401 } 402 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 403 Lexer()->NextToken(); // eat ':' 404 typeAnnotation = ParseTypeAnnotation(&options); 405 endLoc = typeAnnotation->End(); 406 } 407 408 ir::Expression *initializer = nullptr; 409 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 410 Lexer()->NextToken(); // eat '=' 411 initializer = ParseExpression(); 412 } else if (typeAnnotation == nullptr) { 413 ThrowSyntaxError("Field type annotation expected"); 414 } 415 416 bool isDeclare = (modifiers & ir::ModifierFlags::DECLARE) != 0; 417 418 if (isDeclare && initializer != nullptr) { 419 ThrowSyntaxError("Initializers are not allowed in ambient contexts."); 420 } 421 422 auto *field = AllocNode<ir::ClassProperty>(fieldName, initializer, typeAnnotation, modifiers, Allocator(), false); 423 field->SetRange({fieldName->Start(), initializer != nullptr ? initializer->End() : endLoc}); 424 if (optionalField) { 425 field->AddModifier(ir::ModifierFlags::OPTIONAL); 426 } 427 428 declarations->push_back(field); 429 430 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 431 Lexer()->NextToken(); 432 ir::Identifier *nextName = ExpectIdentifier(false, true); 433 ParseClassFieldDefinition(nextName, modifiers, declarations); 434 } 435} 436 437ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers, 438 ir::Identifier *className) 439{ 440 auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ALLOW_SUPER; 441 auto methodKind = ir::MethodDefinitionKind::METHOD; 442 443 if (className != nullptr) { 444 methodKind = ir::MethodDefinitionKind::EXTENSION_METHOD; 445 newStatus |= ParserStatus::IN_EXTENSION_FUNCTION; 446 } 447 448 if ((modifiers & ir::ModifierFlags::CONSTRUCTOR) != 0) { 449 newStatus = ParserStatus::CONSTRUCTOR_FUNCTION | ParserStatus::ALLOW_SUPER | ParserStatus::ALLOW_SUPER_CALL; 450 methodKind = ir::MethodDefinitionKind::CONSTRUCTOR; 451 } 452 453 if ((modifiers & ir::ModifierFlags::ASYNC) != 0) { 454 newStatus |= ParserStatus::ASYNC_FUNCTION; 455 } 456 457 if ((modifiers & ir::ModifierFlags::STATIC) == 0) { 458 newStatus |= ParserStatus::ALLOW_THIS_TYPE; 459 } 460 461 ir::ScriptFunction *func = ParseFunction(newStatus, className); 462 func->SetIdent(methodName); 463 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 464 funcExpr->SetRange(func->Range()); 465 func->AddModifier(modifiers); 466 467 if (className != nullptr) { 468 func->AddFlag(ir::ScriptFunctionFlags::INSTANCE_EXTENSION_METHOD); 469 } 470 auto *method = AllocNode<ir::MethodDefinition>(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), 471 funcExpr, modifiers, Allocator(), false); 472 method->SetRange(funcExpr->Range()); 473 func->Id()->SetReference(); 474 return method; 475} 476 477ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, 478 const ArenaVector<ir::AstNode *> &properties, 479 ir::Expression *propName, lexer::SourcePosition *propEnd) 480{ 481 if (desc->methodKind != ir::MethodDefinitionKind::SET && 482 (desc->newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) == 0) { 483 desc->newStatus |= ParserStatus::NEED_RETURN_TYPE; 484 } 485 486 ir::ScriptFunction *func = ParseFunction(desc->newStatus); 487 if (propName->IsIdentifier()) { 488 func->SetIdent(propName->AsIdentifier()->Clone(Allocator(), nullptr)); 489 func->Id()->SetReference(); 490 } 491 492 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 493 funcExpr->SetRange(func->Range()); 494 495 if (desc->methodKind == ir::MethodDefinitionKind::SET) { 496 ValidateClassSetter(desc, properties, propName, func); 497 } else if (desc->methodKind == ir::MethodDefinitionKind::GET) { 498 ValidateClassGetter(desc, properties, propName, func); 499 } 500 501 *propEnd = func->End(); 502 func->AddFlag(ir::ScriptFunctionFlags::METHOD); 503 auto *method = 504 AllocNode<ir::MethodDefinition>(desc->methodKind, propName->Clone(Allocator(), nullptr)->AsExpression(), 505 funcExpr, desc->modifiers, Allocator(), desc->isComputed); 506 method->SetRange(funcExpr->Range()); 507 508 return method; 509} 510 511bool IsParseClassElementSeenStatic(lexer::Lexer *lexer) 512{ 513 char32_t nextCp = lexer->Lookahead(); 514 if (lexer->GetToken().KeywordType() == lexer::TokenType::KEYW_STATIC && nextCp != lexer::LEX_CHAR_EQUALS && 515 nextCp != lexer::LEX_CHAR_COLON && nextCp != lexer::LEX_CHAR_LEFT_PAREN && 516 nextCp != lexer::LEX_CHAR_LESS_THAN) { 517 lexer->NextToken(); 518 return true; 519 } 520 return false; 521} 522 523ir::AstNode *ETSParser::ParseClassElement(const ArenaVector<ir::AstNode *> &properties, 524 ir::ClassDefinitionModifiers modifiers, 525 [[maybe_unused]] ir::ModifierFlags flags) 526{ 527 auto startLoc = Lexer()->GetToken().Start(); 528 ir::ModifierFlags memberModifiers = ir::ModifierFlags::NONE; 529 if ((GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0 && 530 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXPORT) { 531 Lexer()->NextToken(); // eat exported 532 memberModifiers |= ir::ModifierFlags::EXPORTED; 533 } 534 auto savedPos = Lexer()->Save(); // NOLINT(clang-analyzer-deadcode.DeadStores) 535 536 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_STATIC && 537 Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_BRACE) { 538 return ParseClassStaticBlock(); 539 } 540 541 auto [modifierFlags, isStepToken] = ParseClassMemberAccessModifiers(); 542 memberModifiers |= modifierFlags; 543 544 if (InAmbientContext()) { 545 memberModifiers |= ir::ModifierFlags::DECLARE; 546 } 547 548 bool seenStatic = IsParseClassElementSeenStatic(Lexer()); 549 if (seenStatic) { 550 memberModifiers |= ir::ModifierFlags::STATIC; 551 } 552 553 if (IsClassFieldModifier(Lexer()->GetToken().KeywordType())) { 554 memberModifiers |= ParseClassFieldModifiers(seenStatic); 555 } else if (IsClassMethodModifier(Lexer()->GetToken().Type())) { 556 memberModifiers |= ParseClassMethodModifiers(seenStatic); 557 } 558 559 switch (Lexer()->GetToken().Type()) { 560 case lexer::TokenType::KEYW_INTERFACE: 561 case lexer::TokenType::KEYW_CLASS: 562 case lexer::TokenType::KEYW_ENUM: { 563 return ParseInnerTypeDeclaration(memberModifiers, savedPos, isStepToken, seenStatic); 564 } 565 case lexer::TokenType::KEYW_CONSTRUCTOR: { 566 return ParseInnerConstructorDeclaration(memberModifiers, startLoc); 567 } 568 case lexer::TokenType::KEYW_NAMESPACE: { 569 return ParseNamespaceDeclaration(memberModifiers); 570 } 571 case lexer::TokenType::KEYW_PUBLIC: 572 case lexer::TokenType::KEYW_PRIVATE: 573 case lexer::TokenType::KEYW_PROTECTED: { 574 ThrowSyntaxError("Access modifier must precede field and method modifiers."); 575 } 576 default: { 577 return ParseInnerRest(properties, modifiers, memberModifiers, startLoc); 578 } 579 } 580} 581 582ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector<ir::AstNode *> &properties, 583 const ir::ClassDefinitionModifiers modifiers, 584 const ir::ModifierFlags memberModifiers) 585{ 586 ClassElementDescriptor desc(Allocator()); 587 desc.methodKind = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET ? ir::MethodDefinitionKind::GET 588 : ir::MethodDefinitionKind::SET; 589 Lexer()->NextToken(); // eat get/set 590 auto *methodName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 591 if (desc.methodKind == ir::MethodDefinitionKind::GET) { 592 methodName->SetAccessor(); 593 } else { 594 methodName->SetMutator(); 595 } 596 597 Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 598 599 desc.newStatus = ParserStatus::ALLOW_SUPER; 600 desc.hasSuperClass = (modifiers & ir::ClassDefinitionModifiers::HAS_SUPER) != 0U; 601 desc.propStart = Lexer()->GetToken().Start(); 602 desc.modifiers = memberModifiers; 603 604 lexer::SourcePosition propEnd = methodName->End(); 605 ir::MethodDefinition *method = ParseClassMethod(&desc, properties, methodName, &propEnd); 606 method->Function()->AddModifier(desc.modifiers); 607 method->SetRange({desc.propStart, propEnd}); 608 if (desc.methodKind == ir::MethodDefinitionKind::GET) { 609 method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); 610 } else { 611 method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); 612 } 613 614 return method; 615} 616 617ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::ModifierFlags modifiers) 618{ 619 auto methodKind = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET ? ir::MethodDefinitionKind::GET 620 : ir::MethodDefinitionKind::SET; 621 Lexer()->NextToken(); // eat get/set 622 ExpectToken(lexer::TokenType::LITERAL_IDENT, false); 623 ir::MethodDefinition *method = ParseInterfaceMethod(modifiers, methodKind); 624 method->AddModifier(ir::ModifierFlags::PUBLIC); 625 method->SetRange({Lexer()->GetToken().Start(), method->Id()->End()}); 626 if (methodKind == ir::MethodDefinitionKind::GET) { 627 method->Id()->SetAccessor(); 628 method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); 629 } else { 630 method->Id()->SetMutator(); 631 method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); 632 } 633 method->AddModifier(ir::ModifierFlags::PUBLIC); 634 635 method->Function()->SetIdent(method->Id()->Clone(Allocator(), nullptr)); 636 method->Function()->AddModifier(method->Modifiers()); 637 638 return method; 639} 640 641ir::TSInterfaceDeclaration *ETSParser::ParseInterfaceBody(ir::Identifier *name, bool isStatic) 642{ 643 GetContext().Status() |= ParserStatus::ALLOW_THIS_TYPE; 644 645 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 646 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 647 auto options = 648 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ALLOW_DECLARATION_SITE_VARIANCE; 649 typeParamDecl = ParseTypeParameterDeclaration(&options); 650 } 651 652 ArenaVector<ir::TSInterfaceHeritage *> extends(Allocator()->Adapter()); 653 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { 654 extends = ParseInterfaceExtendsClause(); 655 } 656 657 lexer::SourcePosition bodyStart = Lexer()->GetToken().Start(); 658 auto members = ParseTypeLiteralOrInterface(); 659 660 for (auto &member : members) { 661 if (member->Type() == ir::AstNodeType::CLASS_DECLARATION || 662 member->Type() == ir::AstNodeType::STRUCT_DECLARATION || 663 member->Type() == ir::AstNodeType::TS_ENUM_DECLARATION || 664 member->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) { 665 ThrowSyntaxError( 666 "Local type declaration (class, struct, interface and enum) support is not yet implemented."); 667 } 668 } 669 670 auto *body = AllocNode<ir::TSInterfaceBody>(std::move(members)); 671 body->SetRange({bodyStart, Lexer()->GetToken().End()}); 672 673 const auto isExternal = IsExternal(); 674 auto *interfaceDecl = AllocNode<ir::TSInterfaceDeclaration>( 675 Allocator(), std::move(extends), 676 ir::TSInterfaceDeclaration::ConstructorData {name, typeParamDecl, body, isStatic, isExternal, 677 GetContext().GetLanguage()}); 678 679 Lexer()->NextToken(); 680 GetContext().Status() &= ~ParserStatus::ALLOW_THIS_TYPE; 681 682 return interfaceDecl; 683} 684 685ir::Statement *ETSParser::ParseInterfaceDeclaration(bool isStatic) 686{ 687 lexer::SourcePosition interfaceStart = Lexer()->GetToken().Start(); 688 Lexer()->NextToken(); // eat interface keyword 689 690 auto *id = ExpectIdentifier(false, true); 691 692 auto *declNode = ParseInterfaceBody(id, isStatic); 693 694 declNode->SetRange({interfaceStart, Lexer()->GetToken().End()}); 695 return declNode; 696} 697 698// NOLINTNEXTLINE(google-default-arguments) 699ir::ClassDefinition *ETSParser::ParseClassDefinition(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags) 700{ 701 Lexer()->NextToken(); 702 703 ir::Identifier *identNode = ParseClassIdent(modifiers); 704 if (identNode == nullptr && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 705 Lexer()->NextToken(); // Error processing. 706 } 707 708 ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 709 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 710 auto options = 711 TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ALLOW_DECLARATION_SITE_VARIANCE; 712 typeParamDecl = ParseTypeParameterDeclaration(&options); 713 } 714 715 // Parse SuperClass 716 auto [superClass, superTypeParams] = ParseSuperClass(); 717 718 if (superClass != nullptr) { 719 modifiers |= ir::ClassDefinitionModifiers::HAS_SUPER; 720 GetContext().Status() |= ParserStatus::ALLOW_SUPER; 721 } 722 723 if (InAmbientContext()) { 724 flags |= ir::ModifierFlags::DECLARE; 725 } 726 727 // Parse implements clause 728 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter()); 729 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IMPLEMENTS) { 730 Lexer()->NextToken(); 731 implements = ParseClassImplementClause(); 732 } 733 734 ArenaVector<ir::AstNode *> properties(Allocator()->Adapter()); 735 ir::MethodDefinition *ctor = nullptr; 736 lexer::SourceRange bodyRange; 737 738 if ((flags & ir::ModifierFlags::DECLARE) != 0U && 739 Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 740 // without ClassBody 741 bodyRange = lexer::SourceRange {Lexer()->GetToken().Start(), Lexer()->GetToken().Start()}; 742 } else { 743 ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE, false); 744 745 // Parse ClassBody 746 std::tie(ctor, properties, bodyRange) = ParseClassBody(modifiers, flags); 747 } 748 749 auto *classDefinition = AllocNode<ir::ClassDefinition>( 750 util::StringView(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, 751 std::move(properties), modifiers, flags, GetContext().GetLanguage()); 752 753 classDefinition->SetRange(bodyRange); 754 755 GetContext().Status() &= ~ParserStatus::ALLOW_SUPER; 756 757 return classDefinition; 758} 759 760static bool IsInterfaceMethodModifier(lexer::TokenType type) 761{ 762 // NOTE (psiket) Rewrite this 763 return type == lexer::TokenType::KEYW_STATIC || type == lexer::TokenType::KEYW_PRIVATE || 764 type == lexer::TokenType::KEYW_PROTECTED || type == lexer::TokenType::KEYW_PUBLIC; 765} 766 767ir::ModifierFlags ETSParser::ParseInterfaceMethodModifiers() 768{ 769 ir::ModifierFlags flags = ir::ModifierFlags::NONE; 770 771 while (IsInterfaceMethodModifier(Lexer()->GetToken().Type())) { 772 ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; 773 774 if ((GetContext().Status() & ParserStatus::FUNCTION) != 0) { 775 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_PUBLIC || 776 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_PROTECTED || 777 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_PRIVATE) { 778 ThrowSyntaxError("Local interface declaration members can not have access modifies", 779 Lexer()->GetToken().Start()); 780 } 781 } else if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_PUBLIC || 782 Lexer()->GetToken().Type() == lexer::TokenType::KEYW_PROTECTED) { 783 break; 784 } 785 switch (Lexer()->GetToken().Type()) { 786 case lexer::TokenType::KEYW_STATIC: { 787 currentFlag = ir::ModifierFlags::STATIC; 788 break; 789 } 790 case lexer::TokenType::KEYW_PRIVATE: { 791 currentFlag = ir::ModifierFlags::PRIVATE; 792 break; 793 } 794 default: { 795 UNREACHABLE(); 796 } 797 } 798 799 char32_t nextCp = Lexer()->Lookahead(); 800 if (nextCp == lexer::LEX_CHAR_COLON || nextCp == lexer::LEX_CHAR_LEFT_PAREN || 801 nextCp == lexer::LEX_CHAR_EQUALS) { 802 break; 803 } 804 805 if ((flags & currentFlag) != 0) { 806 ThrowSyntaxError("Duplicated modifier is not allowed"); 807 } 808 809 Lexer()->NextToken(); 810 flags |= currentFlag; 811 } 812 813 return flags; 814} 815 816ir::ClassProperty *ETSParser::ParseInterfaceField() 817{ 818 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); 819 auto *name = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 820 name->SetRange(Lexer()->GetToken().Loc()); 821 Lexer()->NextToken(); 822 bool optionalField = false; 823 824 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 825 Lexer()->NextToken(); // eat '?' 826 optionalField = true; 827 } 828 829 ir::TypeNode *typeAnnotation = nullptr; 830 if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { 831 ThrowSyntaxError("Interface fields must have type annotation."); 832 } 833 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 834 typeAnnotation = ParseTypeAnnotation(&options); 835 if (typeAnnotation == nullptr) { // Error processing. 836 return nullptr; 837 } 838 839 name->SetTsTypeAnnotation(typeAnnotation); 840 typeAnnotation->SetParent(name); 841 842 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL) { 843 ThrowSyntaxError("Initializers are not allowed on interface properties."); 844 } 845 846 ir::ModifierFlags fieldModifiers = ir::ModifierFlags::PUBLIC; 847 848 if (InAmbientContext()) { 849 fieldModifiers |= ir::ModifierFlags::DECLARE; 850 } 851 852 auto *field = AllocNode<ir::ClassProperty>(name, nullptr, typeAnnotation->Clone(Allocator(), nullptr), 853 fieldModifiers, Allocator(), false); 854 if (optionalField) { 855 field->AddModifier(ir::ModifierFlags::OPTIONAL); 856 } 857 field->SetEnd(Lexer()->GetToken().End()); 858 859 return field; 860} 861 862ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind) 863{ 864 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); 865 auto *name = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 866 name->SetRange(Lexer()->GetToken().Loc()); 867 Lexer()->NextToken(); 868 869 FunctionContext functionContext(this, ParserStatus::FUNCTION); 870 871 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 872 873 auto [signature, throwMarker] = ParseFunctionSignature(ParserStatus::NEED_RETURN_TYPE); 874 875 ir::BlockStatement *body = nullptr; 876 877 bool isDeclare = InAmbientContext(); 878 if (isDeclare) { 879 flags |= ir::ModifierFlags::DECLARE; 880 } 881 882 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 883 if (methodKind == ir::MethodDefinitionKind::SET || methodKind == ir::MethodDefinitionKind::GET) { 884 ThrowSyntaxError("Getter and setter methods must be abstracts in the interface body", startLoc); 885 } 886 body = ParseBlockStatement(); 887 } else if ((flags & (ir::ModifierFlags::PRIVATE | ir::ModifierFlags::STATIC)) != 0 && !isDeclare) { 888 ThrowSyntaxError("Private or static interface methods must have body", startLoc); 889 } 890 891 functionContext.AddFlag(throwMarker); 892 893 if ((GetContext().Status() & ParserStatus::FUNCTION_HAS_RETURN_STATEMENT) != 0) { 894 functionContext.AddFlag(ir::ScriptFunctionFlags::HAS_RETURN); 895 GetContext().Status() ^= ParserStatus::FUNCTION_HAS_RETURN_STATEMENT; 896 } 897 898 auto *func = AllocNode<ir::ScriptFunction>( 899 Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(signature), functionContext.Flags(), flags, 900 true, GetContext().GetLanguage()}); 901 902 if ((flags & ir::ModifierFlags::STATIC) == 0 && body == nullptr) { 903 func->AddModifier(ir::ModifierFlags::ABSTRACT); 904 } 905 func->SetRange({startLoc, body != nullptr ? body->End() 906 : func->ReturnTypeAnnotation() != nullptr ? func->ReturnTypeAnnotation()->End() 907 : func->Params().empty() ? Lexer()->GetToken().End() 908 : (*func->Params().end())->End()}); 909 910 auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 911 funcExpr->SetRange(func->Range()); 912 func->AddFlag(ir::ScriptFunctionFlags::METHOD); 913 914 func->SetIdent(name); 915 auto *method = AllocNode<ir::MethodDefinition>(methodKind, name->Clone(Allocator(), nullptr)->AsExpression(), 916 funcExpr, flags, Allocator(), false); 917 method->SetRange(funcExpr->Range()); 918 919 func->Id()->SetReference(); 920 921 ConsumeSemicolon(method); 922 923 return method; 924} 925 926ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() 927{ 928 auto startLoc = Lexer()->GetToken().Start(); 929 ir::ModifierFlags methodFlags = ParseInterfaceMethodModifiers(); 930 if (methodFlags != ir::ModifierFlags::NONE) { 931 if ((methodFlags & ir::ModifierFlags::PRIVATE) == 0) { 932 methodFlags |= ir::ModifierFlags::PUBLIC; 933 } 934 935 auto *method = ParseInterfaceMethod(methodFlags, ir::MethodDefinitionKind::METHOD); 936 method->SetStart(startLoc); 937 return method; 938 } 939 940 if (Lexer()->Lookahead() != lexer::LEX_CHAR_LEFT_PAREN && Lexer()->Lookahead() != lexer::LEX_CHAR_LESS_THAN && 941 (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET || 942 Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_SET)) { 943 return ParseInterfaceGetterSetterMethod(methodFlags); 944 } 945 946 if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY)) { 947 auto *field = ParseInterfaceField(); 948 field->SetStart(startLoc); 949 field->AddModifier(ir::ModifierFlags::READONLY); 950 return field; 951 } 952 953 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 954 char32_t nextCp = Lexer()->Lookahead(); 955 if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { 956 auto *method = ParseInterfaceMethod(ir::ModifierFlags::PUBLIC, ir::MethodDefinitionKind::METHOD); 957 method->SetStart(startLoc); 958 return method; 959 } 960 961 auto *field = ParseInterfaceField(); 962 if (field != nullptr) { // Error processing. 963 field->SetStart(startLoc); 964 } 965 966 return field; 967 } 968 969 return ParseTypeDeclaration(true); 970} 971 972bool ETSParser::CheckClassElement(ir::AstNode *property, [[maybe_unused]] ir::MethodDefinition *&ctor, 973 [[maybe_unused]] ArenaVector<ir::AstNode *> &properties) 974{ 975 if (property->IsClassStaticBlock()) { 976 if (std::any_of(properties.cbegin(), properties.cend(), 977 [](const auto *prop) { return prop->IsClassStaticBlock(); })) { 978 ThrowSyntaxError("Only one static block is allowed", property->Start()); 979 } 980 981 auto *id = AllocNode<ir::Identifier>(compiler::Signatures::CCTOR, Allocator()); 982 property->AsClassStaticBlock()->Function()->SetIdent(id); 983 } 984 985 if (property->IsTSInterfaceBody()) { 986 return CheckClassElementInterfaceBody(property, properties); 987 } 988 989 if (!property->IsMethodDefinition()) { 990 return false; 991 } 992 993 auto const *const method = property->AsMethodDefinition(); 994 auto const *const function = method->Function(); 995 996 // Check the special '$_get' and '$_set' methods using for object's index access 997 if (method->Kind() == ir::MethodDefinitionKind::METHOD) { 998 CheckPredefinedMethods(function, property->Start()); 999 } 1000 1001 return false; // resolve overloads later on scopes stage 1002} 1003 1004void ETSParser::CheckPredefinedMethods(ir::ScriptFunction const *function, const lexer::SourcePosition &position) const 1005{ 1006 auto const name = function->Id()->Name(); 1007 1008 auto const checkAsynchronous = [this, function, &name, &position]() -> void { 1009 if (function->IsAsyncFunc()) { 1010 ThrowSyntaxError(std::string {ir::PREDEFINED_METHOD} + std::string {name.Utf8()} + 1011 std::string {"' cannot be asynchronous."}, 1012 position); 1013 } 1014 }; 1015 1016 if (name.Is(compiler::Signatures::GET_INDEX_METHOD)) { 1017 checkAsynchronous(); 1018 1019 bool isValid = function->Params().size() == 1U; 1020 if (isValid) { 1021 auto const *const param = function->Params()[0]->AsETSParameterExpression(); 1022 isValid = !param->IsDefault() && !param->IsRestParameter(); 1023 } 1024 1025 if (!isValid) { 1026 ThrowSyntaxError(std::string {ir::PREDEFINED_METHOD} + std::string {name.Utf8()} + 1027 std::string {"' should have exactly one required parameter."}, 1028 position); 1029 } 1030 } else if (name.Is(compiler::Signatures::SET_INDEX_METHOD)) { 1031 checkAsynchronous(); 1032 1033 bool isValid = function->Params().size() == 2U; 1034 if (isValid) { 1035 auto const *const param1 = function->Params()[0]->AsETSParameterExpression(); 1036 auto const *const param2 = function->Params()[1]->AsETSParameterExpression(); 1037 isValid = !param1->IsDefault() && !param1->IsRestParameter() && !param2->IsDefault() && 1038 !param2->IsRestParameter(); 1039 } 1040 1041 if (!isValid) { 1042 ThrowSyntaxError(std::string {ir::PREDEFINED_METHOD} + std::string {name.Utf8()} + 1043 std::string {"' should have exactly two required parameters."}, 1044 position); 1045 } 1046 } else if (name.Is(compiler::Signatures::ITERATOR_METHOD)) { 1047 checkAsynchronous(); 1048 1049 if (!function->Params().empty()) { 1050 ThrowSyntaxError(std::string {ir::PREDEFINED_METHOD} + std::string {name.Utf8()} + 1051 std::string {"' should not have parameters."}, 1052 position); 1053 } 1054 } 1055} 1056 1057void ETSParser::CreateImplicitConstructor([[maybe_unused]] ir::MethodDefinition *&ctor, 1058 ArenaVector<ir::AstNode *> &properties, 1059 [[maybe_unused]] ir::ClassDefinitionModifiers modifiers, 1060 const lexer::SourcePosition &startLoc) 1061{ 1062 if (std::any_of(properties.cbegin(), properties.cend(), [](ir::AstNode *prop) { 1063 return prop->IsMethodDefinition() && prop->AsMethodDefinition()->IsConstructor(); 1064 })) { 1065 return; 1066 } 1067 1068 if ((modifiers & ir::ClassDefinitionModifiers::ANONYMOUS) != 0) { 1069 return; 1070 } 1071 1072 auto *methodDef = BuildImplicitConstructor(ir::ClassDefinitionModifiers::SET_CTOR_ID, startLoc); 1073 properties.push_back(methodDef); 1074} 1075 1076std::pair<ir::ModifierFlags, lexer::SourcePosition> ETSParser::ParseMemberModifiers() 1077{ 1078 auto memberModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC; 1079 1080 if (Lexer()->TryEatTokenType(lexer::TokenType::KEYW_EXPORT)) { 1081 const auto savedPos = Lexer()->Save(); 1082 if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_DEFAULT)) { 1083 memberModifiers |= ir::ModifierFlags::DEFAULT_EXPORT; 1084 } else if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_TYPE)) { 1085 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 1086 Lexer()->Rewind(savedPos); 1087 } 1088 memberModifiers |= ir::ModifierFlags::EXPORT_TYPE; 1089 } else { 1090 memberModifiers |= ir::ModifierFlags::EXPORT; 1091 } 1092 } 1093 1094 lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 1095 1096 if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { 1097 CheckDeclare(); 1098 memberModifiers |= ir::ModifierFlags::DECLARE; 1099 } 1100 const auto tokenType = Lexer()->GetToken().KeywordType(); 1101 if (tokenType == lexer::TokenType::KEYW_ASYNC || tokenType == lexer::TokenType::KEYW_NATIVE) { 1102 bool isAsync = tokenType == lexer::TokenType::KEYW_ASYNC; 1103 1104 if (isAsync) { 1105 memberModifiers |= ir::ModifierFlags::ASYNC; 1106 } else { 1107 memberModifiers |= ir::ModifierFlags::NATIVE; 1108 } 1109 Lexer()->NextToken(); 1110 1111 if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_FUNCTION) { 1112 ThrowSyntaxError( 1113 {isAsync ? "'async'" : "'native'", " flags must be used for functions only at top-level."}); 1114 } 1115 } 1116 return std::make_pair(memberModifiers, startLoc); 1117} 1118 1119} // namespace ark::es2panda::parser 1120