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/statements/functionDeclaration.h" 43#include "ir/statements/expressionStatement.h" 44#include "ir/statements/classDeclaration.h" 45#include "ir/statements/variableDeclarator.h" 46#include "ir/statements/variableDeclaration.h" 47#include "ir/expressions/dummyNode.h" 48#include "ir/expressions/callExpression.h" 49#include "ir/expressions/thisExpression.h" 50#include "ir/expressions/typeofExpression.h" 51#include "ir/expressions/memberExpression.h" 52#include "ir/expressions/updateExpression.h" 53#include "ir/expressions/arrowFunctionExpression.h" 54#include "ir/expressions/unaryExpression.h" 55#include "ir/expressions/yieldExpression.h" 56#include "ir/expressions/awaitExpression.h" 57#include "ir/expressions/literals/nullLiteral.h" 58#include "ir/expressions/literals/numberLiteral.h" 59#include "ir/expressions/literals/stringLiteral.h" 60#include "ir/expressions/literals/undefinedLiteral.h" 61#include "ir/module/importDeclaration.h" 62#include "ir/module/importDefaultSpecifier.h" 63#include "ir/module/importSpecifier.h" 64#include "ir/module/exportSpecifier.h" 65#include "ir/module/exportNamedDeclaration.h" 66#include "ir/statements/assertStatement.h" 67#include "ir/statements/blockStatement.h" 68#include "ir/statements/ifStatement.h" 69#include "ir/statements/labelledStatement.h" 70#include "ir/statements/switchStatement.h" 71#include "ir/statements/throwStatement.h" 72#include "ir/statements/tryStatement.h" 73#include "ir/statements/whileStatement.h" 74#include "ir/statements/forOfStatement.h" 75#include "ir/statements/doWhileStatement.h" 76#include "ir/statements/breakStatement.h" 77#include "ir/statements/debuggerStatement.h" 78#include "ir/ets/etsLaunchExpression.h" 79#include "ir/ets/etsClassLiteral.h" 80#include "ir/ets/etsPrimitiveType.h" 81#include "ir/ets/etsPackageDeclaration.h" 82#include "ir/ets/etsReExportDeclaration.h" 83#include "ir/ets/etsWildcardType.h" 84#include "ir/ets/etsNewArrayInstanceExpression.h" 85#include "ir/ets/etsTuple.h" 86#include "ir/ets/etsFunctionType.h" 87#include "ir/ets/etsNewClassInstanceExpression.h" 88#include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" 89#include "ir/ets/etsScript.h" 90#include "ir/ets/etsTypeReference.h" 91#include "ir/ets/etsTypeReferencePart.h" 92#include "ir/ets/etsNullishTypes.h" 93#include "ir/ets/etsUnionType.h" 94#include "ir/ets/etsImportSource.h" 95#include "ir/ets/etsImportDeclaration.h" 96#include "ir/ets/etsStructDeclaration.h" 97#include "ir/ets/etsParameterExpression.h" 98#include "ir/module/importNamespaceSpecifier.h" 99#include "ir/ts/tsAsExpression.h" 100#include "ir/ts/tsInterfaceDeclaration.h" 101#include "ir/ts/tsEnumDeclaration.h" 102#include "ir/ts/tsTypeParameterInstantiation.h" 103#include "ir/ts/tsInterfaceBody.h" 104#include "ir/ts/tsImportEqualsDeclaration.h" 105#include "ir/ts/tsArrayType.h" 106#include "ir/ts/tsQualifiedName.h" 107#include "ir/ts/tsTypeReference.h" 108#include "ir/ts/tsTypeParameter.h" 109#include "ir/ts/tsInterfaceHeritage.h" 110#include "ir/ts/tsFunctionType.h" 111#include "ir/ts/tsClassImplements.h" 112#include "ir/ts/tsEnumMember.h" 113#include "ir/ts/tsTypeAliasDeclaration.h" 114#include "ir/ts/tsTypeParameterDeclaration.h" 115#include "ir/ts/tsNonNullExpression.h" 116#include "ir/ts/tsThisType.h" 117#include "generated/signatures.h" 118 119namespace ark::es2panda::parser { 120class FunctionContext; 121 122using namespace std::literals::string_literals; 123 124ir::Expression *ETSParser::ParseLaunchExpression(ExpressionParseFlags flags) 125{ 126 lexer::SourcePosition start = Lexer()->GetToken().Start(); 127 Lexer()->NextToken(); // eat launch 128 129 ir::Expression *expr = ParseLeftHandSideExpression(flags); 130 if (!expr->IsCallExpression()) { 131 ThrowSyntaxError("Only call expressions are allowed after 'launch'", expr->Start()); 132 } 133 auto call = expr->AsCallExpression(); 134 auto *launchExpression = AllocNode<ir::ETSLaunchExpression>(call); 135 launchExpression->SetRange({start, call->End()}); 136 137 return launchExpression; 138} 139 140// NOLINTBEGIN(modernize-avoid-c-arrays) 141static constexpr char const NO_DEFAULT_FOR_REST[] = "Rest parameter cannot have the default value."; 142// NOLINTEND(modernize-avoid-c-arrays) 143 144ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent, 145 ir::ETSUndefinedType *defaultUndef) 146{ 147 ir::ETSParameterExpression *paramExpression; 148 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 149 if (paramIdent->IsRestElement()) { 150 ThrowSyntaxError(NO_DEFAULT_FOR_REST); 151 } 152 153 auto const lexerPos = Lexer()->Save().Iterator(); 154 Lexer()->NextToken(); // eat '=' 155 156 if ((GetContext().Status() & ParserStatus::ALLOW_DEFAULT_VALUE) != 0) { 157 ThrowSyntaxError("Default value is allowed only for optional parameters"); 158 } 159 160 if (defaultUndef != nullptr) { 161 ThrowSyntaxError("Not enable default value with default undefined"); 162 } 163 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS || 164 Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 165 ThrowSyntaxError("You didn't set the value."); 166 } 167 168 paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), ParseExpression()); 169 170 std::string value = Lexer()->SourceView(lexerPos.Index(), Lexer()->Save().Iterator().Index()).Mutf8(); 171 while (value.back() == ' ') { 172 value.pop_back(); 173 } 174 if (value.back() == ')' || value.back() == ',') { 175 value.pop_back(); 176 } 177 paramExpression->SetLexerSaved(util::UString(value, Allocator()).View()); 178 179 paramExpression->SetRange({paramIdent->Start(), paramExpression->Initializer()->End()}); 180 } else if (paramIdent->IsIdentifier()) { 181 auto *typeAnnotation = paramIdent->AsIdentifier()->TypeAnnotation(); 182 183 const auto typeAnnotationValue = [this, typeAnnotation, 184 defaultUndef]() -> std::pair<ir::Expression *, std::string> { 185 if (typeAnnotation == nullptr) { 186 return std::make_pair(nullptr, ""); 187 } 188 return std::make_pair(defaultUndef != nullptr ? AllocNode<ir::UndefinedLiteral>() : nullptr, "undefined"); 189 }(); 190 191 paramExpression = 192 AllocNode<ir::ETSParameterExpression>(paramIdent->AsIdentifier(), std::get<0>(typeAnnotationValue)); 193 if (defaultUndef != nullptr) { 194 paramExpression->SetLexerSaved(util::UString(std::get<1>(typeAnnotationValue), Allocator()).View()); 195 } 196 paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); 197 } else { 198 paramExpression = AllocNode<ir::ETSParameterExpression>(paramIdent->AsRestElement(), nullptr); 199 paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); 200 } 201 return paramExpression; 202} 203 204ir::Expression *ETSParser::ResolveArgumentUnaryExpr(ExpressionParseFlags flags) 205{ 206 switch (Lexer()->GetToken().Type()) { 207 case lexer::TokenType::PUNCTUATOR_PLUS: 208 case lexer::TokenType::PUNCTUATOR_MINUS: 209 case lexer::TokenType::PUNCTUATOR_TILDE: 210 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: 211 case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR: 212 case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: 213 case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: 214 case lexer::TokenType::KEYW_TYPEOF: { 215 return ParseUnaryOrPrefixUpdateExpression(); 216 } 217 default: { 218 return ParseLeftHandSideExpression(flags); 219 } 220 } 221} 222 223// NOLINTNEXTLINE(google-default-arguments) 224ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags) 225{ 226 switch (Lexer()->GetToken().Type()) { 227 case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: 228 case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: 229 case lexer::TokenType::PUNCTUATOR_PLUS: 230 case lexer::TokenType::PUNCTUATOR_MINUS: 231 case lexer::TokenType::PUNCTUATOR_TILDE: 232 case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR: 233 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: 234 case lexer::TokenType::KEYW_TYPEOF: { 235 break; 236 } 237 case lexer::TokenType::KEYW_LAUNCH: { 238 return ParseLaunchExpression(flags); 239 } 240 default: { 241 return ParseLeftHandSideExpression(flags); 242 } 243 } 244 245 lexer::TokenType operatorType = Lexer()->GetToken().Type(); 246 auto start = Lexer()->GetToken().Start(); 247 Lexer()->NextToken(); 248 249 ir::Expression *argument = ResolveArgumentUnaryExpr(flags); 250 251 if (lexer::Token::IsUpdateToken(operatorType)) { 252 if (!argument->IsIdentifier() && !argument->IsMemberExpression()) { 253 ThrowSyntaxError("Invalid left-hand side in prefix operation"); 254 } 255 } 256 257 lexer::SourcePosition end = argument->End(); 258 259 ir::Expression *returnExpr = nullptr; 260 if (lexer::Token::IsUpdateToken(operatorType)) { 261 returnExpr = AllocNode<ir::UpdateExpression>(argument, operatorType, true); 262 } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) { 263 returnExpr = AllocNode<ir::TypeofExpression>(argument); 264 } else { 265 returnExpr = AllocNode<ir::UnaryExpression>(argument, operatorType); 266 } 267 268 returnExpr->SetRange({start, end}); 269 270 return returnExpr; 271} 272 273// NOLINTNEXTLINE(google-default-arguments) 274ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags) 275{ 276 auto startLoc = Lexer()->GetToken().Start(); 277 auto savedPos = Lexer()->Save(); 278 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL | 279 TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | 280 TypeAnnotationParsingOptions::DISALLOW_UNION; 281 ir::TypeNode *potentialType = ParseTypeAnnotation(&options); 282 283 if (potentialType != nullptr) { 284 if (potentialType->IsTSArrayType()) { 285 return potentialType; 286 } 287 288 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 289 Lexer()->NextToken(); // eat '.' 290 } 291 292 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) { 293 Lexer()->NextToken(); // eat 'class' and 'struct' 294 auto *classLiteral = AllocNode<ir::ETSClassLiteral>(potentialType); 295 classLiteral->SetRange({startLoc, Lexer()->GetToken().End()}); 296 return classLiteral; 297 } 298 } 299 300 Lexer()->Rewind(savedPos); 301 302 Lexer()->NextToken(); 303 bool pretendArrow = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW; 304 Lexer()->Rewind(savedPos); 305 306 if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !pretendArrow) { 307 return ParsePrimaryExpressionIdent(flags); 308 } 309 310 ThrowSyntaxError({"Unexpected token '", lexer::TokenToString(Lexer()->GetToken().Type()), "'."}); 311 return nullptr; 312} 313 314ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFlags flags) 315{ 316 switch (Lexer()->GetToken().Type()) { 317 case lexer::TokenType::LITERAL_TRUE: 318 case lexer::TokenType::LITERAL_FALSE: { 319 return ParseBooleanLiteral(); 320 } 321 case lexer::TokenType::LITERAL_NULL: { 322 return ParseNullLiteral(); 323 } 324 case lexer::TokenType::KEYW_UNDEFINED: { 325 return ParseUndefinedLiteral(); 326 } 327 case lexer::TokenType::LITERAL_NUMBER: { 328 return ParseCoercedNumberLiteral(); 329 } 330 case lexer::TokenType::LITERAL_STRING: { 331 return ParseStringLiteral(); 332 } 333 case lexer::TokenType::LITERAL_CHAR: { 334 return ParseCharLiteral(); 335 } 336 default: { 337 return ParseDefaultPrimaryExpression(flags); 338 } 339 } 340} 341 342// NOLINTNEXTLINE(google-default-arguments) 343ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) 344{ 345 switch (Lexer()->GetToken().Type()) { 346 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 347 return ParseCoverParenthesizedExpressionAndArrowParameterList(flags); 348 } 349 case lexer::TokenType::KEYW_THIS: { 350 return ParseThisExpression(); 351 } 352 case lexer::TokenType::KEYW_SUPER: { 353 return ParseSuperExpression(); 354 } 355 case lexer::TokenType::KEYW_NEW: { 356 return ParseNewExpression(); 357 } 358 case lexer::TokenType::KEYW_ASYNC: { 359 return ParseAsyncExpression(); 360 } 361 case lexer::TokenType::KEYW_AWAIT: { 362 return ParseAwaitExpression(); 363 } 364 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 365 return ParseArrayExpression(CarryPatternFlags(flags)); 366 } 367 case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 368 return ParseObjectExpression(CarryPatternFlags(flags)); 369 } 370 case lexer::TokenType::PUNCTUATOR_BACK_TICK: { 371 return ParseTemplateLiteral(); 372 } 373 case lexer::TokenType::KEYW_TYPE: { 374 ThrowSyntaxError("Type alias is allowed only as top-level declaration"); 375 } 376 case lexer::TokenType::PUNCTUATOR_FORMAT: { 377 return ParseExpressionFormatPlaceholder(); 378 } 379 case lexer::TokenType::KEYW_TYPEOF: { 380 return ParseUnaryOrPrefixUpdateExpression(); 381 } 382 default: { 383 return ParsePrimaryExpressionWithLiterals(flags); 384 } 385 } 386} 387 388bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType) 389{ 390 switch (tokenType) { 391 case lexer::TokenType::PUNCTUATOR_COLON: 392 case lexer::TokenType::PUNCTUATOR_COMMA: 393 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: 394 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: 395 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: 396 case lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET: 397 case lexer::TokenType::PUNCTUATOR_LESS_THAN: 398 case lexer::TokenType::PUNCTUATOR_GREATER_THAN: 399 case lexer::TokenType::PUNCTUATOR_BITWISE_OR: 400 return true; 401 default: 402 return false; 403 } 404} 405 406bool ETSParser::IsArrowFunctionExpressionStart() 407{ 408 const auto savedPos = Lexer()->Save(); 409 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 410 Lexer()->NextToken(); 411 auto tokenType = Lexer()->GetToken().Type(); 412 413 size_t openBrackets = 1; 414 bool expectIdentifier = true; 415 while (tokenType != lexer::TokenType::EOS && openBrackets > 0) { 416 switch (tokenType) { 417 case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS: 418 --openBrackets; 419 break; 420 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: 421 ++openBrackets; 422 break; 423 case lexer::TokenType::PUNCTUATOR_COMMA: 424 expectIdentifier = true; 425 break; 426 case lexer::TokenType::PUNCTUATOR_SEMI_COLON: 427 Lexer()->Rewind(savedPos); 428 return false; 429 default: 430 if (!expectIdentifier) { 431 break; 432 } 433 if (tokenType != lexer::TokenType::LITERAL_IDENT && 434 tokenType != lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { 435 Lexer()->Rewind(savedPos); 436 return false; 437 } 438 expectIdentifier = false; 439 } 440 Lexer()->NextToken(); 441 tokenType = Lexer()->GetToken().Type(); 442 } 443 444 while (tokenType != lexer::TokenType::EOS && tokenType != lexer::TokenType::PUNCTUATOR_ARROW) { 445 if (lexer::Token::IsPunctuatorToken(tokenType) && !IsPunctuartorSpecialCharacter(tokenType)) { 446 break; 447 } 448 Lexer()->NextToken(); 449 tokenType = Lexer()->GetToken().Type(); 450 } 451 Lexer()->Rewind(savedPos); 452 return tokenType == lexer::TokenType::PUNCTUATOR_ARROW; 453} 454 455ir::ArrowFunctionExpression *ETSParser::ParseArrowFunctionExpression() 456{ 457 auto newStatus = ParserStatus::ARROW_FUNCTION; 458 auto *func = ParseFunction(newStatus); 459 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func); 460 arrowFuncNode->SetRange(func->Range()); 461 return arrowFuncNode; 462} 463 464// NOLINTNEXTLINE(google-default-arguments) 465ir::Expression *ETSParser::ParseCoverParenthesizedExpressionAndArrowParameterList(ExpressionParseFlags flags) 466{ 467 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 468 if (IsArrowFunctionExpressionStart()) { 469 return ParseArrowFunctionExpression(); 470 } 471 472 lexer::SourcePosition start = Lexer()->GetToken().Start(); 473 Lexer()->NextToken(); 474 475 ExpressionParseFlags newFlags = ExpressionParseFlags::ACCEPT_COMMA; 476 if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) { 477 newFlags |= ExpressionParseFlags::INSTANCEOF; 478 }; 479 480 ir::Expression *expr = ParseExpression(newFlags); 481 482 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 483 ThrowSyntaxError("Unexpected token, expected ')'"); 484 } 485 486 expr->SetGrouped(); 487 expr->SetRange({start, Lexer()->GetToken().End()}); 488 Lexer()->NextToken(); 489 490 return expr; 491} 492 493std::optional<ir::Expression *> ETSParser::GetPostPrimaryExpression(ir::Expression *returnExpression, 494 lexer::SourcePosition startLoc, 495 bool ignoreCallExpression, 496 [[maybe_unused]] bool *isChainExpression) 497{ 498 switch (Lexer()->GetToken().Type()) { 499 case lexer::TokenType::PUNCTUATOR_QUESTION_DOT: 500 if (*isChainExpression) { 501 return std::nullopt; // terminate current chain 502 } 503 *isChainExpression = true; 504 Lexer()->NextToken(); // eat ?. 505 506 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 507 return ParseElementAccess(returnExpression, true); 508 } 509 510 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 511 return ParseCallExpression(returnExpression, true, false); 512 } 513 514 return ParsePropertyAccess(returnExpression, true); 515 case lexer::TokenType::PUNCTUATOR_PERIOD: 516 Lexer()->NextToken(); // eat period 517 518 return ParsePropertyAccess(returnExpression); 519 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: 520 return ParseElementAccess(returnExpression); 521 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: 522 case lexer::TokenType::PUNCTUATOR_LESS_THAN: 523 if (ParsePotentialGenericFunctionCall(returnExpression, &returnExpression, startLoc, 524 ignoreCallExpression)) { 525 return std::nullopt; 526 } 527 528 return returnExpression; 529 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: 530 if (ignoreCallExpression) { 531 return std::nullopt; 532 } 533 return ParseCallExpression(returnExpression, false, false); 534 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { 535 const bool shouldBreak = ParsePotentialNonNullExpression(&returnExpression, startLoc); 536 if (shouldBreak) { 537 return std::nullopt; 538 } 539 540 return returnExpression; 541 } 542 case lexer::TokenType::PUNCTUATOR_FORMAT: 543 ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_FORMAT); 544 case lexer::TokenType::PUNCTUATOR_ARROW: 545 ThrowUnexpectedToken(lexer::TokenType::PUNCTUATOR_ARROW); 546 default: 547 return std::nullopt; 548 } 549} 550 551ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, 552 bool ignoreCallExpression, 553 [[maybe_unused]] bool *isChainExpression) 554{ 555 ir::Expression *returnExpression = primaryExpr; 556 557 while (true) { 558 auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression); 559 if (expr.has_value()) { 560 returnExpression = expr.value(); 561 continue; 562 } 563 564 break; 565 } 566 567 return returnExpression; 568} 569 570ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExpr) 571{ 572 ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS); 573 Lexer()->NextToken(); 574 575 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 576 ir::TypeNode *type = ParseTypeAnnotation(&options); 577 578 auto *asExpression = AllocNode<ir::TSAsExpression>(primaryExpr, type, false); 579 asExpression->SetRange(primaryExpr->Range()); 580 return asExpression; 581} 582 583// Extracted from 'ParseNewExpression()' to reduce function's size 584ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector<ir::Expression *> &arguments, 585 ir::TypeNode *typeReference, 586 ir::TypeNode *baseTypeReference) 587{ 588 lexer::SourcePosition endLoc = typeReference->End(); 589 590 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 591 if (baseTypeReference != nullptr) { 592 ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start()); 593 } 594 595 Lexer()->NextToken(); 596 597 while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 598 ir::Expression *argument = ParseExpression(); 599 arguments.push_back(argument); 600 601 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 602 Lexer()->NextToken(); 603 continue; 604 } 605 } 606 607 endLoc = Lexer()->GetToken().End(); 608 Lexer()->NextToken(); 609 } 610 611 ir::ClassDefinition *classDefinition {}; 612 613 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 614 ArenaVector<ir::TSClassImplements *> implements(Allocator()->Adapter()); 615 auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER; 616 auto [ctor, properties, bodyRange] = ParseClassBody(modifiers); 617 618 auto newIdent = AllocNode<ir::Identifier>("#0", Allocator()); 619 classDefinition = AllocNode<ir::ClassDefinition>( 620 "#0", newIdent, nullptr, nullptr, std::move(implements), ctor, // remove name 621 typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE, 622 Language(Language::Id::ETS)); 623 624 classDefinition->SetRange(bodyRange); 625 } 626 627 return classDefinition; 628} 629 630ir::Expression *ETSParser::ParseNewExpression() 631{ 632 lexer::SourcePosition start = Lexer()->GetToken().Start(); 633 634 Lexer()->NextToken(); // eat new 635 636 TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 637 ir::TypeNode *baseTypeReference = ParseBaseTypeReference(&options); 638 ir::TypeNode *typeReference = baseTypeReference; 639 if (typeReference == nullptr) { 640 options |= TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE | TypeAnnotationParsingOptions::ALLOW_WILDCARD | 641 TypeAnnotationParsingOptions::POTENTIAL_NEW_ARRAY; 642 typeReference = ParseTypeReference(&options); 643 if (typeReference == nullptr) { 644 typeReference = ParseTypeAnnotation(&options); 645 } 646 } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 647 ThrowSyntaxError("Invalid { after base types."); 648 } 649 650 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 651 Lexer()->NextToken(); 652 ir::Expression *dimension = ParseExpression(); 653 654 auto endLoc = Lexer()->GetToken().End(); 655 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); 656 657 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 658 auto *arrInstance = AllocNode<ir::ETSNewArrayInstanceExpression>(typeReference, dimension); 659 arrInstance->SetRange({start, endLoc}); 660 return arrInstance; 661 } 662 663 ArenaVector<ir::Expression *> dimensions(Allocator()->Adapter()); 664 dimensions.push_back(dimension); 665 666 do { 667 Lexer()->NextToken(); 668 dimensions.push_back(ParseExpression()); 669 670 endLoc = Lexer()->GetToken().End(); 671 ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); 672 } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 673 674 auto *multiArray = AllocNode<ir::ETSNewMultiDimArrayInstanceExpression>(typeReference, std::move(dimensions)); 675 multiArray->SetRange({start, endLoc}); 676 return multiArray; 677 } 678 679 ArenaVector<ir::Expression *> arguments(Allocator()->Adapter()); 680 ir::ClassDefinition *classDefinition = 681 CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference); 682 683 auto *newExprNode = 684 AllocNode<ir::ETSNewClassInstanceExpression>(typeReference, std::move(arguments), classDefinition); 685 newExprNode->SetRange({start, Lexer()->GetToken().End()}); 686 687 return newExprNode; 688} 689 690ir::Expression *ETSParser::ParseAsyncExpression() 691{ 692 Lexer()->NextToken(); // eat 'async' 693 if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 694 !IsArrowFunctionExpressionStart()) { 695 ThrowSyntaxError("Unexpected token. expected '('"); 696 } 697 698 auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ARROW_FUNCTION | ParserStatus::ASYNC_FUNCTION; 699 auto *func = ParseFunction(newStatus); 700 auto *arrowFuncNode = AllocNode<ir::ArrowFunctionExpression>(func); 701 arrowFuncNode->SetRange(func->Range()); 702 return arrowFuncNode; 703} 704 705ir::Expression *ETSParser::ParseAwaitExpression() 706{ 707 lexer::SourcePosition start = Lexer()->GetToken().Start(); 708 Lexer()->NextToken(); 709 ir::Expression *argument = ParseExpression(); 710 auto *awaitExpression = AllocNode<ir::AwaitExpression>(argument); 711 awaitExpression->SetRange({start, Lexer()->GetToken().End()}); 712 return awaitExpression; 713} 714 715ir::ThisExpression *ETSParser::ParseThisExpression() 716{ 717 auto *thisExpression = TypedParser::ParseThisExpression(); 718 719 if (Lexer()->GetToken().NewLine()) { 720 return thisExpression; 721 } 722 723 switch (Lexer()->GetToken().Type()) { 724 case lexer::TokenType::PUNCTUATOR_PERIOD: 725 case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: 726 case lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS: 727 case lexer::TokenType::PUNCTUATOR_SEMI_COLON: 728 case lexer::TokenType::PUNCTUATOR_COLON: 729 case lexer::TokenType::PUNCTUATOR_EQUAL: 730 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: 731 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: 732 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: 733 case lexer::TokenType::PUNCTUATOR_COMMA: 734 case lexer::TokenType::PUNCTUATOR_QUESTION_MARK: 735 case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: 736 case lexer::TokenType::KEYW_INSTANCEOF: 737 case lexer::TokenType::KEYW_AS: { 738 break; 739 } 740 default: { 741 ThrowUnexpectedToken(Lexer()->GetToken().Type()); 742 break; 743 } 744 } 745 746 return thisExpression; 747} 748 749ir::Expression *ETSParser::ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags) 750{ 751 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && 752 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0 && (flags & ExpressionParseFlags::IN_FOR) != 0U) { 753 return ParseSequenceExpression(expr, (flags & ExpressionParseFlags::ACCEPT_REST) != 0); 754 } 755 756 return expr; 757} 758 759bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, const lexer::SourcePosition startLoc) 760{ 761 if (expression == nullptr || Lexer()->GetToken().NewLine()) { 762 return true; 763 } 764 765 const auto nonNullExpr = AllocNode<ir::TSNonNullExpression>(*expression); 766 nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()}); 767 768 *expression = nonNullExpr; 769 770 Lexer()->NextToken(); 771 772 return false; 773} 774 775void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr) 776{ 777 ValidateGroupedExpression(expr); 778 lexer::TokenType tokenType = Lexer()->GetToken().Type(); 779 if (tokenType == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 780 auto options = TypeAnnotationParsingOptions::NO_OPTS; 781 782 // Run checks to validate type declarations 783 // Should provide helpful messages with incorrect declarations like the following: 784 // `instanceof A<String;` 785 ParseTypeParameterDeclaration(&options); 786 787 // Display error message even when type declaration is correct 788 // `instanceof A<String>;` 789 ThrowSyntaxError("Invalid right-hand side in 'instanceof' expression"); 790 } 791} 792 793// NOLINTNEXTLINE(google-default-arguments) 794ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags) 795{ 796 if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD && 797 (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) { 798 ir::YieldExpression *yieldExpr = ParseYieldExpression(); 799 800 return ParsePotentialExpressionSequence(yieldExpr, flags); 801 } 802 803 ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags); 804 if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) { 805 ValidateInstanceOfExpression(unaryExpressionNode); 806 } 807 808 ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags); 809 810 if (Lexer()->GetToken().NewLine()) { 811 return assignmentExpression; 812 } 813 814 if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && 815 (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) { 816 return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U); 817 } 818 819 return assignmentExpression; 820} 821 822} // namespace ark::es2panda::parser 823