13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "TSparser.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "parser/parserStatusContext.h" 193af6ab5fSopenharmony_ci#include "macros.h" 203af6ab5fSopenharmony_ci#include "parserFlags.h" 213af6ab5fSopenharmony_ci#include "util/helpers.h" 223af6ab5fSopenharmony_ci#include "varbinder/privateBinding.h" 233af6ab5fSopenharmony_ci#include "varbinder/scope.h" 243af6ab5fSopenharmony_ci#include "varbinder/tsBinding.h" 253af6ab5fSopenharmony_ci#include "lexer/TSLexer.h" 263af6ab5fSopenharmony_ci#include "ir/base/spreadElement.h" 273af6ab5fSopenharmony_ci#include "ir/base/decorator.h" 283af6ab5fSopenharmony_ci#include "ir/base/classElement.h" 293af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h" 303af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h" 313af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h" 323af6ab5fSopenharmony_ci#include "ir/module/importDefaultSpecifier.h" 333af6ab5fSopenharmony_ci#include "ir/module/exportDefaultDeclaration.h" 343af6ab5fSopenharmony_ci#include "ir/module/exportAllDeclaration.h" 353af6ab5fSopenharmony_ci#include "ir/module/exportNamedDeclaration.h" 363af6ab5fSopenharmony_ci#include "ir/module/importDeclaration.h" 373af6ab5fSopenharmony_ci#include "ir/expressions/memberExpression.h" 383af6ab5fSopenharmony_ci#include "ir/expressions/sequenceExpression.h" 393af6ab5fSopenharmony_ci#include "ir/expressions/templateLiteral.h" 403af6ab5fSopenharmony_ci#include "ir/expressions/taggedTemplateExpression.h" 413af6ab5fSopenharmony_ci#include "ir/expressions/callExpression.h" 423af6ab5fSopenharmony_ci#include "ir/expressions/functionExpression.h" 433af6ab5fSopenharmony_ci#include "ir/expressions/arrowFunctionExpression.h" 443af6ab5fSopenharmony_ci#include "ir/expressions/yieldExpression.h" 453af6ab5fSopenharmony_ci#include "ir/expressions/assignmentExpression.h" 463af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 473af6ab5fSopenharmony_ci#include "ir/expressions/objectExpression.h" 483af6ab5fSopenharmony_ci#include "ir/expressions/arrayExpression.h" 493af6ab5fSopenharmony_ci#include "ir/expressions/literals/bigIntLiteral.h" 503af6ab5fSopenharmony_ci#include "ir/expressions/literals/booleanLiteral.h" 513af6ab5fSopenharmony_ci#include "ir/expressions/literals/nullLiteral.h" 523af6ab5fSopenharmony_ci#include "ir/expressions/literals/numberLiteral.h" 533af6ab5fSopenharmony_ci#include "ir/expressions/literals/stringLiteral.h" 543af6ab5fSopenharmony_ci#include "ir/statements/emptyStatement.h" 553af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h" 563af6ab5fSopenharmony_ci#include "ir/statements/ifStatement.h" 573af6ab5fSopenharmony_ci#include "ir/statements/doWhileStatement.h" 583af6ab5fSopenharmony_ci#include "ir/statements/whileStatement.h" 593af6ab5fSopenharmony_ci#include "ir/statements/tryStatement.h" 603af6ab5fSopenharmony_ci#include "ir/statements/breakStatement.h" 613af6ab5fSopenharmony_ci#include "ir/statements/continueStatement.h" 623af6ab5fSopenharmony_ci#include "ir/statements/throwStatement.h" 633af6ab5fSopenharmony_ci#include "ir/statements/switchStatement.h" 643af6ab5fSopenharmony_ci#include "ir/statements/returnStatement.h" 653af6ab5fSopenharmony_ci#include "ir/statements/debuggerStatement.h" 663af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h" 673af6ab5fSopenharmony_ci#include "ir/statements/labelledStatement.h" 683af6ab5fSopenharmony_ci#include "ir/statements/variableDeclarator.h" 693af6ab5fSopenharmony_ci#include "ir/statements/functionDeclaration.h" 703af6ab5fSopenharmony_ci#include "ir/ts/tsLiteralType.h" 713af6ab5fSopenharmony_ci#include "ir/ts/tsMappedType.h" 723af6ab5fSopenharmony_ci#include "ir/ts/tsImportType.h" 733af6ab5fSopenharmony_ci#include "ir/ts/tsThisType.h" 743af6ab5fSopenharmony_ci#include "ir/ts/tsConditionalType.h" 753af6ab5fSopenharmony_ci#include "ir/ts/tsTypeOperator.h" 763af6ab5fSopenharmony_ci#include "ir/ts/tsInferType.h" 773af6ab5fSopenharmony_ci#include "ir/ts/tsTupleType.h" 783af6ab5fSopenharmony_ci#include "ir/ts/tsNamedTupleMember.h" 793af6ab5fSopenharmony_ci#include "ir/ts/tsQualifiedName.h" 803af6ab5fSopenharmony_ci#include "ir/ts/tsIndexedAccessType.h" 813af6ab5fSopenharmony_ci#include "ir/ts/tsTypeQuery.h" 823af6ab5fSopenharmony_ci#include "ir/ts/tsTypeReference.h" 833af6ab5fSopenharmony_ci#include "ir/ts/tsTypePredicate.h" 843af6ab5fSopenharmony_ci#include "ir/ts/tsTypeLiteral.h" 853af6ab5fSopenharmony_ci#include "ir/ts/tsArrayType.h" 863af6ab5fSopenharmony_ci#include "ir/ts/tsUnionType.h" 873af6ab5fSopenharmony_ci#include "ir/ts/tsIntersectionType.h" 883af6ab5fSopenharmony_ci#include "ir/ts/tsAnyKeyword.h" 893af6ab5fSopenharmony_ci#include "ir/ts/tsUndefinedKeyword.h" 903af6ab5fSopenharmony_ci#include "ir/ts/tsVoidKeyword.h" 913af6ab5fSopenharmony_ci#include "ir/ts/tsNumberKeyword.h" 923af6ab5fSopenharmony_ci#include "ir/ts/tsStringKeyword.h" 933af6ab5fSopenharmony_ci#include "ir/ts/tsBooleanKeyword.h" 943af6ab5fSopenharmony_ci#include "ir/ts/tsBigintKeyword.h" 953af6ab5fSopenharmony_ci#include "ir/ts/tsUnknownKeyword.h" 963af6ab5fSopenharmony_ci#include "ir/ts/tsNullKeyword.h" 973af6ab5fSopenharmony_ci#include "ir/ts/tsNeverKeyword.h" 983af6ab5fSopenharmony_ci#include "ir/ts/tsObjectKeyword.h" 993af6ab5fSopenharmony_ci#include "ir/ts/tsFunctionType.h" 1003af6ab5fSopenharmony_ci#include "ir/ts/tsConstructorType.h" 1013af6ab5fSopenharmony_ci#include "ir/ts/tsParenthesizedType.h" 1023af6ab5fSopenharmony_ci#include "ir/ts/tsTypeAssertion.h" 1033af6ab5fSopenharmony_ci#include "ir/ts/tsAsExpression.h" 1043af6ab5fSopenharmony_ci#include "ir/ts/tsNonNullExpression.h" 1053af6ab5fSopenharmony_ci#include "ir/ts/tsEnumDeclaration.h" 1063af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceDeclaration.h" 1073af6ab5fSopenharmony_ci#include "ir/ts/tsTypeAliasDeclaration.h" 1083af6ab5fSopenharmony_ci#include "ir/ts/tsModuleDeclaration.h" 1093af6ab5fSopenharmony_ci#include "ir/ts/tsTypeParameterInstantiation.h" 1103af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceHeritage.h" 1113af6ab5fSopenharmony_ci#include "ir/base/tsSignatureDeclaration.h" 1123af6ab5fSopenharmony_ci#include "ir/base/tsIndexSignature.h" 1133af6ab5fSopenharmony_ci#include "ir/base/tsMethodSignature.h" 1143af6ab5fSopenharmony_ci#include "ir/base/tsPropertySignature.h" 1153af6ab5fSopenharmony_ci#include "ir/ts/tsParameterProperty.h" 1163af6ab5fSopenharmony_ci#include "ir/ts/tsClassImplements.h" 1173af6ab5fSopenharmony_ci#include "ir/ts/tsImportEqualsDeclaration.h" 1183af6ab5fSopenharmony_ci#include "ir/ts/tsExternalModuleReference.h" 1193af6ab5fSopenharmony_ci 1203af6ab5fSopenharmony_cinamespace ark::es2panda::parser { 1213af6ab5fSopenharmony_cistd::unique_ptr<lexer::Lexer> TSParser::InitLexer(const SourceFile &sourceFile) 1223af6ab5fSopenharmony_ci{ 1233af6ab5fSopenharmony_ci GetProgram()->SetSource(sourceFile); 1243af6ab5fSopenharmony_ci auto lexer = std::make_unique<lexer::TSLexer>(&GetContext()); 1253af6ab5fSopenharmony_ci SetLexer(lexer.get()); 1263af6ab5fSopenharmony_ci return lexer; 1273af6ab5fSopenharmony_ci} 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ciir::Decorator *TSParser::ParseDecorator() 1303af6ab5fSopenharmony_ci{ 1313af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT); 1323af6ab5fSopenharmony_ci 1333af6ab5fSopenharmony_ci lexer::SourcePosition start = Lexer()->GetToken().Start(); 1343af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '@' 1353af6ab5fSopenharmony_ci 1363af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 1373af6ab5fSopenharmony_ci ThrowSyntaxError("Identifier expected"); 1383af6ab5fSopenharmony_ci } 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci ir::Expression *expr = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 1413af6ab5fSopenharmony_ci expr->SetRange(Lexer()->GetToken().Loc()); 1423af6ab5fSopenharmony_ci Lexer()->NextToken(); 1433af6ab5fSopenharmony_ci 1443af6ab5fSopenharmony_ci while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 1453af6ab5fSopenharmony_ci Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 1463af6ab5fSopenharmony_ci 1473af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 1483af6ab5fSopenharmony_ci ThrowSyntaxError("Identifier expected"); 1493af6ab5fSopenharmony_ci } 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_ci auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 1523af6ab5fSopenharmony_ci identNode->SetRange(Lexer()->GetToken().Loc()); 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ci expr = 1553af6ab5fSopenharmony_ci AllocNode<ir::MemberExpression>(expr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); 1563af6ab5fSopenharmony_ci Lexer()->NextToken(); 1573af6ab5fSopenharmony_ci } 1583af6ab5fSopenharmony_ci 1593af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 1603af6ab5fSopenharmony_ci expr = ParseCallExpression(expr); 1613af6ab5fSopenharmony_ci } 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci auto *result = AllocNode<ir::Decorator>(expr); 1643af6ab5fSopenharmony_ci result->SetRange({start, expr->End()}); 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_ci return result; 1673af6ab5fSopenharmony_ci} 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_civoid TSParser::AddDecorators(ir::AstNode *node, ArenaVector<ir::Decorator *> &decorators) 1703af6ab5fSopenharmony_ci{ 1713af6ab5fSopenharmony_ci if (decorators.empty()) { 1723af6ab5fSopenharmony_ci return; 1733af6ab5fSopenharmony_ci } 1743af6ab5fSopenharmony_ci 1753af6ab5fSopenharmony_ci if (!node->CanHaveDecorator(true)) { 1763af6ab5fSopenharmony_ci ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start()); 1773af6ab5fSopenharmony_ci } 1783af6ab5fSopenharmony_ci 1793af6ab5fSopenharmony_ci node->AddDecorators(std::move(decorators)); 1803af6ab5fSopenharmony_ci} 1813af6ab5fSopenharmony_ci 1823af6ab5fSopenharmony_ciir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration() 1833af6ab5fSopenharmony_ci{ 1843af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE); 1853af6ab5fSopenharmony_ci lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); 1863af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat type keyword 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 1893af6ab5fSopenharmony_ci ThrowSyntaxError("Identifier expected"); 1903af6ab5fSopenharmony_ci } 1913af6ab5fSopenharmony_ci 1923af6ab5fSopenharmony_ci if (Lexer()->GetToken().IsReservedTypeName()) { 1933af6ab5fSopenharmony_ci std::string errMsg("Type alias name cannot be '"); 1943af6ab5fSopenharmony_ci errMsg.append(TokenToString(Lexer()->GetToken().KeywordType())); 1953af6ab5fSopenharmony_ci errMsg.append("'"); 1963af6ab5fSopenharmony_ci ThrowSyntaxError(errMsg.c_str()); 1973af6ab5fSopenharmony_ci } 1983af6ab5fSopenharmony_ci 1993af6ab5fSopenharmony_ci const util::StringView &ident = Lexer()->GetToken().Ident(); 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ci auto *id = AllocNode<ir::Identifier>(ident, Allocator()); 2023af6ab5fSopenharmony_ci id->SetRange(Lexer()->GetToken().Loc()); 2033af6ab5fSopenharmony_ci Lexer()->NextToken(); 2043af6ab5fSopenharmony_ci 2053af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 2063af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 2073af6ab5fSopenharmony_ci auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 2083af6ab5fSopenharmony_ci typeParamDecl = ParseTypeParameterDeclaration(&options); 2093af6ab5fSopenharmony_ci } 2103af6ab5fSopenharmony_ci 2113af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 2123af6ab5fSopenharmony_ci ThrowSyntaxError("'=' expected"); 2133af6ab5fSopenharmony_ci } 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '=' 2163af6ab5fSopenharmony_ci 2173af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 2183af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 2193af6ab5fSopenharmony_ci 2203af6ab5fSopenharmony_ci auto *typeAliasDecl = 2213af6ab5fSopenharmony_ci AllocNode<ir::TSTypeAliasDeclaration>(Allocator(), id, typeParamDecl, typeAnnotation, InAmbientContext()); 2223af6ab5fSopenharmony_ci typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()}); 2233af6ab5fSopenharmony_ci 2243af6ab5fSopenharmony_ci return typeAliasDecl; 2253af6ab5fSopenharmony_ci} 2263af6ab5fSopenharmony_ci 2273af6ab5fSopenharmony_cibool TSParser::CurrentLiteralIsBasicType() const 2283af6ab5fSopenharmony_ci{ 2293af6ab5fSopenharmony_ci switch (Lexer()->GetToken().KeywordType()) { 2303af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_ANY: 2313af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_BOOLEAN: 2323af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NUMBER: 2333af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_STRING: 2343af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_UNKNOWN: 2353af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_UNDEFINED: 2363af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NEVER: 2373af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_OBJECT: 2383af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_BIGINT: { 2393af6ab5fSopenharmony_ci return true; 2403af6ab5fSopenharmony_ci } 2413af6ab5fSopenharmony_ci default: { 2423af6ab5fSopenharmony_ci break; 2433af6ab5fSopenharmony_ci } 2443af6ab5fSopenharmony_ci } 2453af6ab5fSopenharmony_ci 2463af6ab5fSopenharmony_ci return false; 2473af6ab5fSopenharmony_ci} 2483af6ab5fSopenharmony_ci 2493af6ab5fSopenharmony_cibool TSParser::CurrentIsBasicType() 2503af6ab5fSopenharmony_ci{ 2513af6ab5fSopenharmony_ci switch (Lexer()->GetToken().Type()) { 2523af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: 2533af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: 2543af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_FALSE: 2553af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_TRUE: 2563af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NULL: 2573af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_THIS: 2583af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_VOID: { 2593af6ab5fSopenharmony_ci return true; 2603af6ab5fSopenharmony_ci } 2613af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 2623af6ab5fSopenharmony_ci return CurrentLiteralIsBasicType(); 2633af6ab5fSopenharmony_ci } 2643af6ab5fSopenharmony_ci default: { 2653af6ab5fSopenharmony_ci break; 2663af6ab5fSopenharmony_ci } 2673af6ab5fSopenharmony_ci } 2683af6ab5fSopenharmony_ci 2693af6ab5fSopenharmony_ci return false; 2703af6ab5fSopenharmony_ci} 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) 2733af6ab5fSopenharmony_ci{ 2743af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = nullptr; 2753af6ab5fSopenharmony_ci 2763af6ab5fSopenharmony_ci while (true) { 2773af6ab5fSopenharmony_ci ir::TypeNode *element = ParseTypeAnnotationElement(typeAnnotation, options); 2783af6ab5fSopenharmony_ci 2793af6ab5fSopenharmony_ci *options &= ~TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 2803af6ab5fSopenharmony_ci 2813af6ab5fSopenharmony_ci if (element == nullptr) { 2823af6ab5fSopenharmony_ci break; 2833af6ab5fSopenharmony_ci } 2843af6ab5fSopenharmony_ci 2853af6ab5fSopenharmony_ci typeAnnotation = element; 2863af6ab5fSopenharmony_ci 2873af6ab5fSopenharmony_ci if ((((*options) & TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE) != 0) && Lexer()->GetToken().NewLine()) { 2883af6ab5fSopenharmony_ci break; 2893af6ab5fSopenharmony_ci } 2903af6ab5fSopenharmony_ci } 2913af6ab5fSopenharmony_ci 2923af6ab5fSopenharmony_ci return typeAnnotation; 2933af6ab5fSopenharmony_ci} 2943af6ab5fSopenharmony_ci 2953af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseIdentifierReference() 2963af6ab5fSopenharmony_ci{ 2973af6ab5fSopenharmony_ci if (CurrentLiteralIsBasicType() && Lexer()->Lookahead() != lexer::LEX_CHAR_DOT) { 2983af6ab5fSopenharmony_ci return ParseBasicType(); 2993af6ab5fSopenharmony_ci } 3003af6ab5fSopenharmony_ci 3013af6ab5fSopenharmony_ci return ParseTypeReferenceOrQuery(); 3023af6ab5fSopenharmony_ci} 3033af6ab5fSopenharmony_ci 3043af6ab5fSopenharmony_cibool TSParser::IsStartOfMappedType() const 3053af6ab5fSopenharmony_ci{ 3063af6ab5fSopenharmony_ci auto pos = Lexer()->Save(); 3073af6ab5fSopenharmony_ci Lexer()->NextToken(); 3083af6ab5fSopenharmony_ci bool result = false; 3093af6ab5fSopenharmony_ci 3103af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 3113af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 3123af6ab5fSopenharmony_ci Lexer()->NextToken(); 3133af6ab5fSopenharmony_ci result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY; 3143af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3153af6ab5fSopenharmony_ci return result; 3163af6ab5fSopenharmony_ci } 3173af6ab5fSopenharmony_ci 3183af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 3193af6ab5fSopenharmony_ci Lexer()->NextToken(); 3203af6ab5fSopenharmony_ci } 3213af6ab5fSopenharmony_ci 3223af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 3233af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3243af6ab5fSopenharmony_ci return false; 3253af6ab5fSopenharmony_ci } 3263af6ab5fSopenharmony_ci 3273af6ab5fSopenharmony_ci Lexer()->NextToken(); 3283af6ab5fSopenharmony_ci 3293af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 3303af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3313af6ab5fSopenharmony_ci return false; 3323af6ab5fSopenharmony_ci } 3333af6ab5fSopenharmony_ci 3343af6ab5fSopenharmony_ci Lexer()->NextToken(); 3353af6ab5fSopenharmony_ci 3363af6ab5fSopenharmony_ci result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IN; 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3393af6ab5fSopenharmony_ci return result; 3403af6ab5fSopenharmony_ci} 3413af6ab5fSopenharmony_ci 3423af6ab5fSopenharmony_cibool TSParser::IsStartOfTypePredicate() const 3433af6ab5fSopenharmony_ci{ 3443af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 3453af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS); 3463af6ab5fSopenharmony_ci 3473af6ab5fSopenharmony_ci auto pos = Lexer()->Save(); 3483af6ab5fSopenharmony_ci bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 3493af6ab5fSopenharmony_ci if (isAsserts) { 3503af6ab5fSopenharmony_ci Lexer()->NextToken(); 3513af6ab5fSopenharmony_ci } 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && 3543af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::KEYW_THIS) { 3553af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3563af6ab5fSopenharmony_ci return false; 3573af6ab5fSopenharmony_ci } 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ci if (isAsserts) { 3603af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3613af6ab5fSopenharmony_ci return true; 3623af6ab5fSopenharmony_ci } 3633af6ab5fSopenharmony_ci 3643af6ab5fSopenharmony_ci Lexer()->NextToken(); 3653af6ab5fSopenharmony_ci 3663af6ab5fSopenharmony_ci bool result = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS; 3673af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3683af6ab5fSopenharmony_ci return result; 3693af6ab5fSopenharmony_ci} 3703af6ab5fSopenharmony_ci 3713af6ab5fSopenharmony_cibool TSParser::IsStartOfAbstractConstructorType() const 3723af6ab5fSopenharmony_ci{ 3733af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_ABSTRACT) { 3743af6ab5fSopenharmony_ci return false; 3753af6ab5fSopenharmony_ci } 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci lexer::LexerPosition pos = Lexer()->Save(); 3783af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'abstract' 3793af6ab5fSopenharmony_ci bool result = Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW; 3803af6ab5fSopenharmony_ci 3813af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 3823af6ab5fSopenharmony_ci 3833af6ab5fSopenharmony_ci return result; 3843af6ab5fSopenharmony_ci} 3853af6ab5fSopenharmony_ci 3863af6ab5fSopenharmony_ciir::TSImportType *TSParser::ParseImportType(const lexer::SourcePosition &startLoc, bool isTypeof) 3873af6ab5fSopenharmony_ci{ 3883af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT); 3893af6ab5fSopenharmony_ci 3903af6ab5fSopenharmony_ci Lexer()->NextToken(); 3913af6ab5fSopenharmony_ci 3923af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 3933af6ab5fSopenharmony_ci ThrowSyntaxError("'(' expected"); 3943af6ab5fSopenharmony_ci } 3953af6ab5fSopenharmony_ci 3963af6ab5fSopenharmony_ci Lexer()->NextToken(); 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 3993af6ab5fSopenharmony_ci ir::TypeNode *param = ParseTypeAnnotation(&options); 4003af6ab5fSopenharmony_ci 4013af6ab5fSopenharmony_ci if (!param->IsTSLiteralType() || !param->AsTSLiteralType()->Literal()->IsStringLiteral()) { 4023af6ab5fSopenharmony_ci ThrowSyntaxError("String literal expected"); 4033af6ab5fSopenharmony_ci } 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 4063af6ab5fSopenharmony_ci ThrowSyntaxError("')' expected"); 4073af6ab5fSopenharmony_ci } 4083af6ab5fSopenharmony_ci 4093af6ab5fSopenharmony_ci Lexer()->NextToken(); 4103af6ab5fSopenharmony_ci 4113af6ab5fSopenharmony_ci ir::Expression *qualifier = nullptr; 4123af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 4133af6ab5fSopenharmony_ci Lexer()->NextToken(); 4143af6ab5fSopenharmony_ci qualifier = ParseQualifiedName(); 4153af6ab5fSopenharmony_ci } 4163af6ab5fSopenharmony_ci 4173af6ab5fSopenharmony_ci ir::TSTypeParameterInstantiation *typeParams = nullptr; 4183af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || 4193af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 4203af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 4213af6ab5fSopenharmony_ci Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 4223af6ab5fSopenharmony_ci } 4233af6ab5fSopenharmony_ci 4243af6ab5fSopenharmony_ci typeParams = ParseTypeParameterInstantiation(&options); 4253af6ab5fSopenharmony_ci } 4263af6ab5fSopenharmony_ci 4273af6ab5fSopenharmony_ci auto *importType = AllocNode<ir::TSImportType>(param, typeParams, qualifier, isTypeof); 4283af6ab5fSopenharmony_ci 4293af6ab5fSopenharmony_ci importType->SetRange({startLoc, Lexer()->GetToken().End()}); 4303af6ab5fSopenharmony_ci 4313af6ab5fSopenharmony_ci return importType; 4323af6ab5fSopenharmony_ci} 4333af6ab5fSopenharmony_ci 4343af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseThisType(bool throwError) 4353af6ab5fSopenharmony_ci{ 4363af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS); 4373af6ab5fSopenharmony_ci 4383af6ab5fSopenharmony_ci if (throwError && ((GetContext().Status() & ParserStatus::ALLOW_THIS_TYPE) == 0)) { 4393af6ab5fSopenharmony_ci ThrowSyntaxError( 4403af6ab5fSopenharmony_ci "A 'this' type is available only in a non-static member " 4413af6ab5fSopenharmony_ci "of a class or interface."); 4423af6ab5fSopenharmony_ci } 4433af6ab5fSopenharmony_ci 4443af6ab5fSopenharmony_ci auto *returnType = AllocNode<ir::TSThisType>(); 4453af6ab5fSopenharmony_ci returnType->SetRange(Lexer()->GetToken().Loc()); 4463af6ab5fSopenharmony_ci 4473af6ab5fSopenharmony_ci Lexer()->NextToken(); 4483af6ab5fSopenharmony_ci 4493af6ab5fSopenharmony_ci return returnType; 4503af6ab5fSopenharmony_ci} 4513af6ab5fSopenharmony_ci 4523af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseConditionalType(ir::Expression *checkType, bool restrictExtends) 4533af6ab5fSopenharmony_ci{ 4543af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 4553af6ab5fSopenharmony_ci if (restrictExtends) { 4563af6ab5fSopenharmony_ci ThrowSyntaxError("'?' expected."); 4573af6ab5fSopenharmony_ci } 4583af6ab5fSopenharmony_ci 4593af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = checkType->Start(); 4603af6ab5fSopenharmony_ci 4613af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'extends' 4623af6ab5fSopenharmony_ci 4633af6ab5fSopenharmony_ci ParserStatus savedStatus = GetContext().Status(); 4643af6ab5fSopenharmony_ci GetContext().Status() |= ParserStatus::IN_EXTENDS; 4653af6ab5fSopenharmony_ci 4663af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 4673af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 4683af6ab5fSopenharmony_ci auto *extendsType = ParseTypeAnnotation(&options); 4693af6ab5fSopenharmony_ci 4703af6ab5fSopenharmony_ci GetContext().Status() = savedStatus; 4713af6ab5fSopenharmony_ci 4723af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 4733af6ab5fSopenharmony_ci ThrowSyntaxError("'?' expected."); 4743af6ab5fSopenharmony_ci } 4753af6ab5fSopenharmony_ci 4763af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '?' 4773af6ab5fSopenharmony_ci 4783af6ab5fSopenharmony_ci options &= ~TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 4793af6ab5fSopenharmony_ci auto *trueType = ParseTypeAnnotation(&options); 4803af6ab5fSopenharmony_ci 4813af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 4823af6ab5fSopenharmony_ci ThrowSyntaxError("':' expected."); 4833af6ab5fSopenharmony_ci } 4843af6ab5fSopenharmony_ci 4853af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 4863af6ab5fSopenharmony_ci 4873af6ab5fSopenharmony_ci auto *falseType = ParseTypeAnnotation(&options); 4883af6ab5fSopenharmony_ci 4893af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = falseType->End(); 4903af6ab5fSopenharmony_ci 4913af6ab5fSopenharmony_ci auto *conditionalType = AllocNode<ir::TSConditionalType>(checkType, extendsType, trueType, falseType); 4923af6ab5fSopenharmony_ci 4933af6ab5fSopenharmony_ci conditionalType->SetRange({startLoc, endLoc}); 4943af6ab5fSopenharmony_ci 4953af6ab5fSopenharmony_ci return conditionalType; 4963af6ab5fSopenharmony_ci} 4973af6ab5fSopenharmony_ci 4983af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() 4993af6ab5fSopenharmony_ci{ 5003af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 5013af6ab5fSopenharmony_ci 5023af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY) { 5033af6ab5fSopenharmony_ci lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start(); 5043af6ab5fSopenharmony_ci Lexer()->NextToken(); 5053af6ab5fSopenharmony_ci 5063af6ab5fSopenharmony_ci ir::TypeNode *type = ParseTypeAnnotation(&options); 5073af6ab5fSopenharmony_ci 5083af6ab5fSopenharmony_ci if (!type->IsTSArrayType() && !type->IsTSTupleType()) { 5093af6ab5fSopenharmony_ci ThrowSyntaxError( 5103af6ab5fSopenharmony_ci "'readonly' type modifier is only permitted on array " 5113af6ab5fSopenharmony_ci "and tuple literal types."); 5123af6ab5fSopenharmony_ci } 5133af6ab5fSopenharmony_ci 5143af6ab5fSopenharmony_ci auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::READONLY); 5153af6ab5fSopenharmony_ci 5163af6ab5fSopenharmony_ci typeOperator->SetRange({typeOperatorStart, type->End()}); 5173af6ab5fSopenharmony_ci 5183af6ab5fSopenharmony_ci return typeOperator; 5193af6ab5fSopenharmony_ci } 5203af6ab5fSopenharmony_ci 5213af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_KEYOF) { 5223af6ab5fSopenharmony_ci lexer::SourcePosition typeOperatorStart = Lexer()->GetToken().Start(); 5233af6ab5fSopenharmony_ci Lexer()->NextToken(); 5243af6ab5fSopenharmony_ci 5253af6ab5fSopenharmony_ci ir::TypeNode *type = ParseTypeAnnotation(&options); 5263af6ab5fSopenharmony_ci 5273af6ab5fSopenharmony_ci auto *typeOperator = AllocNode<ir::TSTypeOperator>(type, ir::TSOperatorType::KEYOF); 5283af6ab5fSopenharmony_ci 5293af6ab5fSopenharmony_ci typeOperator->SetRange({typeOperatorStart, type->End()}); 5303af6ab5fSopenharmony_ci 5313af6ab5fSopenharmony_ci return typeOperator; 5323af6ab5fSopenharmony_ci } 5333af6ab5fSopenharmony_ci 5343af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INFER) { 5353af6ab5fSopenharmony_ci if ((GetContext().Status() & ParserStatus::IN_EXTENDS) == 0) { 5363af6ab5fSopenharmony_ci ThrowSyntaxError( 5373af6ab5fSopenharmony_ci "'infer' declarations are only permitted in the " 5383af6ab5fSopenharmony_ci "'extends' clause of a conditional type."); 5393af6ab5fSopenharmony_ci } 5403af6ab5fSopenharmony_ci 5413af6ab5fSopenharmony_ci lexer::SourcePosition inferStart = Lexer()->GetToken().Start(); 5423af6ab5fSopenharmony_ci Lexer()->NextToken(); 5433af6ab5fSopenharmony_ci 5443af6ab5fSopenharmony_ci ir::TSTypeParameter *typeParam = ParseTypeParameter(&options); 5453af6ab5fSopenharmony_ci 5463af6ab5fSopenharmony_ci auto *inferType = AllocNode<ir::TSInferType>(typeParam); 5473af6ab5fSopenharmony_ci 5483af6ab5fSopenharmony_ci inferType->SetRange({inferStart, Lexer()->GetToken().End()}); 5493af6ab5fSopenharmony_ci 5503af6ab5fSopenharmony_ci return inferType; 5513af6ab5fSopenharmony_ci } 5523af6ab5fSopenharmony_ci 5533af6ab5fSopenharmony_ci return ParseIdentifierReference(); 5543af6ab5fSopenharmony_ci} 5553af6ab5fSopenharmony_ci 5563af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTupleElement(ir::TSTupleKind *kind, bool *seenOptional) 5573af6ab5fSopenharmony_ci{ 5583af6ab5fSopenharmony_ci lexer::SourcePosition elementStart = Lexer()->GetToken().Start(); 5593af6ab5fSopenharmony_ci ir::TypeNode *element = nullptr; 5603af6ab5fSopenharmony_ci bool isOptional = false; 5613af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 5623af6ab5fSopenharmony_ci 5633af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && !CurrentLiteralIsBasicType()) { 5643af6ab5fSopenharmony_ci auto *elementIdent = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 5653af6ab5fSopenharmony_ci elementIdent->SetRange(Lexer()->GetToken().Loc()); 5663af6ab5fSopenharmony_ci 5673af6ab5fSopenharmony_ci if (Lexer()->Lookahead() == lexer::LEX_CHAR_COLON || Lexer()->Lookahead() == lexer::LEX_CHAR_QUESTION) { 5683af6ab5fSopenharmony_ci if (*kind == ir::TSTupleKind::DEFAULT) { 5693af6ab5fSopenharmony_ci ThrowSyntaxError("Tuple members must all have names or all not have names"); 5703af6ab5fSopenharmony_ci } 5713af6ab5fSopenharmony_ci 5723af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ident 5733af6ab5fSopenharmony_ci 5743af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 5753af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '?' 5763af6ab5fSopenharmony_ci isOptional = true; 5773af6ab5fSopenharmony_ci *seenOptional = true; 5783af6ab5fSopenharmony_ci } else if (*seenOptional) { 5793af6ab5fSopenharmony_ci ThrowSyntaxError("A required element cannot follow an optional element"); 5803af6ab5fSopenharmony_ci } 5813af6ab5fSopenharmony_ci 5823af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 5833af6ab5fSopenharmony_ci ThrowSyntaxError("':' expected"); 5843af6ab5fSopenharmony_ci } 5853af6ab5fSopenharmony_ci 5863af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 5873af6ab5fSopenharmony_ci auto *elementType = ParseTypeAnnotation(&options); 5883af6ab5fSopenharmony_ci *kind = ir::TSTupleKind::NAMED; 5893af6ab5fSopenharmony_ci 5903af6ab5fSopenharmony_ci element = AllocNode<ir::TSNamedTupleMember>(elementIdent, elementType, isOptional); 5913af6ab5fSopenharmony_ci } else { 5923af6ab5fSopenharmony_ci element = ParseTypeReferenceOrQuery(); 5933af6ab5fSopenharmony_ci } 5943af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 5953af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 5963af6ab5fSopenharmony_ci element = ParseTypeAnnotationElement(element, &options); 5973af6ab5fSopenharmony_ci } 5983af6ab5fSopenharmony_ci } else { 5993af6ab5fSopenharmony_ci if (*kind == ir::TSTupleKind::NAMED) { 6003af6ab5fSopenharmony_ci ThrowSyntaxError("Tuple members must all have names or all not have names"); 6013af6ab5fSopenharmony_ci } 6023af6ab5fSopenharmony_ci 6033af6ab5fSopenharmony_ci *kind = ir::TSTupleKind::DEFAULT; 6043af6ab5fSopenharmony_ci element = ParseTypeAnnotation(&options); 6053af6ab5fSopenharmony_ci } 6063af6ab5fSopenharmony_ci 6073af6ab5fSopenharmony_ci if (element != nullptr) { 6083af6ab5fSopenharmony_ci element->SetRange({elementStart, Lexer()->GetToken().End()}); 6093af6ab5fSopenharmony_ci } 6103af6ab5fSopenharmony_ci return element; 6113af6ab5fSopenharmony_ci} 6123af6ab5fSopenharmony_ci 6133af6ab5fSopenharmony_ciir::TSTupleType *TSParser::ParseTupleType() 6143af6ab5fSopenharmony_ci{ 6153af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 6163af6ab5fSopenharmony_ci lexer::SourcePosition tupleStart = Lexer()->GetToken().Start(); 6173af6ab5fSopenharmony_ci ArenaVector<ir::TypeNode *> elements(Allocator()->Adapter()); 6183af6ab5fSopenharmony_ci ir::TSTupleKind kind = ir::TSTupleKind::NONE; 6193af6ab5fSopenharmony_ci bool seenOptional = false; 6203af6ab5fSopenharmony_ci 6213af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 6223af6ab5fSopenharmony_ci 6233af6ab5fSopenharmony_ci while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 6243af6ab5fSopenharmony_ci ir::TypeNode *element = ParseTupleElement(&kind, &seenOptional); 6253af6ab5fSopenharmony_ci elements.push_back(element); 6263af6ab5fSopenharmony_ci 6273af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 6283af6ab5fSopenharmony_ci break; 6293af6ab5fSopenharmony_ci } 6303af6ab5fSopenharmony_ci 6313af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) { 6323af6ab5fSopenharmony_ci ThrowSyntaxError("',' expected."); 6333af6ab5fSopenharmony_ci } 6343af6ab5fSopenharmony_ci 6353af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ',' 6363af6ab5fSopenharmony_ci } 6373af6ab5fSopenharmony_ci 6383af6ab5fSopenharmony_ci lexer::SourcePosition tupleEnd = Lexer()->GetToken().End(); 6393af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ']' 6403af6ab5fSopenharmony_ci 6413af6ab5fSopenharmony_ci auto *tupleType = AllocNode<ir::TSTupleType>(std::move(elements)); 6423af6ab5fSopenharmony_ci tupleType->SetRange({tupleStart, tupleEnd}); 6433af6ab5fSopenharmony_ci return tupleType; 6443af6ab5fSopenharmony_ci} 6453af6ab5fSopenharmony_ci 6463af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseIndexAccessType(ir::TypeNode *typeName) 6473af6ab5fSopenharmony_ci{ 6483af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 6493af6ab5fSopenharmony_ci 6503af6ab5fSopenharmony_ci do { 6513af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 6523af6ab5fSopenharmony_ci 6533af6ab5fSopenharmony_ci ir::TypeNode *indexType = ParseTypeAnnotation(&options); 6543af6ab5fSopenharmony_ci 6553af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 6563af6ab5fSopenharmony_ci ThrowSyntaxError("']' expected"); 6573af6ab5fSopenharmony_ci } 6583af6ab5fSopenharmony_ci 6593af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ']' 6603af6ab5fSopenharmony_ci 6613af6ab5fSopenharmony_ci typeName = AllocNode<ir::TSIndexedAccessType>(typeName, indexType); 6623af6ab5fSopenharmony_ci typeName->SetRange({typeName->AsTSIndexedAccessType()->ObjectType()->Start(), Lexer()->GetToken().End()}); 6633af6ab5fSopenharmony_ci } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 6643af6ab5fSopenharmony_ci Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE); 6653af6ab5fSopenharmony_ci 6663af6ab5fSopenharmony_ci return typeName; 6673af6ab5fSopenharmony_ci} 6683af6ab5fSopenharmony_ci 6693af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery) 6703af6ab5fSopenharmony_ci{ 6713af6ab5fSopenharmony_ci lexer::SourcePosition referenceStartLoc = Lexer()->GetToken().Start(); 6723af6ab5fSopenharmony_ci 6733af6ab5fSopenharmony_ci if (parseQuery) { 6743af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_TYPEOF); 6753af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'typeof' 6763af6ab5fSopenharmony_ci 6773af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) { 6783af6ab5fSopenharmony_ci lexer::SourcePosition &startLoc = referenceStartLoc; 6793af6ab5fSopenharmony_ci return ParseImportType(startLoc, true); 6803af6ab5fSopenharmony_ci } 6813af6ab5fSopenharmony_ci 6823af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 6833af6ab5fSopenharmony_ci ThrowSyntaxError("Identifier expected."); 6843af6ab5fSopenharmony_ci } 6853af6ab5fSopenharmony_ci } 6863af6ab5fSopenharmony_ci 6873af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || 6883af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); 6893af6ab5fSopenharmony_ci 6903af6ab5fSopenharmony_ci ir::Expression *typeName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 6913af6ab5fSopenharmony_ci typeName->SetRange(Lexer()->GetToken().Loc()); 6923af6ab5fSopenharmony_ci typeName->AsIdentifier()->SetReference(); 6933af6ab5fSopenharmony_ci 6943af6ab5fSopenharmony_ci if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { 6953af6ab5fSopenharmony_ci Lexer()->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 6963af6ab5fSopenharmony_ci } else { 6973af6ab5fSopenharmony_ci Lexer()->NextToken(); 6983af6ab5fSopenharmony_ci } 6993af6ab5fSopenharmony_ci 7003af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { 7013af6ab5fSopenharmony_ci typeName = ParseQualifiedReference(typeName); 7023af6ab5fSopenharmony_ci } 7033af6ab5fSopenharmony_ci 7043af6ab5fSopenharmony_ci ir::TSTypeParameterInstantiation *typeParamInst = nullptr; 7053af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 7063af6ab5fSopenharmony_ci if (parseQuery) { 7073af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token."); 7083af6ab5fSopenharmony_ci } 7093af6ab5fSopenharmony_ci 7103af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 7113af6ab5fSopenharmony_ci typeParamInst = ParseTypeParameterInstantiation(&options); 7123af6ab5fSopenharmony_ci } 7133af6ab5fSopenharmony_ci 7143af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 7153af6ab5fSopenharmony_ci Lexer()->Lookahead() != lexer::LEX_CHAR_RIGHT_SQUARE) { 7163af6ab5fSopenharmony_ci ir::TypeNode *typeRef = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode() 7173af6ab5fSopenharmony_ci : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode(); 7183af6ab5fSopenharmony_ci 7193af6ab5fSopenharmony_ci typeRef->SetRange({referenceStartLoc, Lexer()->GetToken().End()}); 7203af6ab5fSopenharmony_ci 7213af6ab5fSopenharmony_ci return ParseIndexAccessType(typeRef); 7223af6ab5fSopenharmony_ci } 7233af6ab5fSopenharmony_ci 7243af6ab5fSopenharmony_ci ir::TypeNode *returnNode = parseQuery ? AllocNode<ir::TSTypeQuery>(typeName)->AsTypeNode() 7253af6ab5fSopenharmony_ci : AllocNode<ir::TSTypeReference>(typeName, typeParamInst)->AsTypeNode(); 7263af6ab5fSopenharmony_ci 7273af6ab5fSopenharmony_ci returnNode->SetRange({referenceStartLoc, typeName->End()}); 7283af6ab5fSopenharmony_ci 7293af6ab5fSopenharmony_ci return returnNode; 7303af6ab5fSopenharmony_ci} 7313af6ab5fSopenharmony_ci 7323af6ab5fSopenharmony_ciir::TSTypeParameter *TSParser::ParseMappedTypeParameter() 7333af6ab5fSopenharmony_ci{ 7343af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 7353af6ab5fSopenharmony_ci 7363af6ab5fSopenharmony_ci auto *paramName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 7373af6ab5fSopenharmony_ci paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); 7383af6ab5fSopenharmony_ci 7393af6ab5fSopenharmony_ci Lexer()->NextToken(); 7403af6ab5fSopenharmony_ci 7413af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'in' 7423af6ab5fSopenharmony_ci 7433af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 7443af6ab5fSopenharmony_ci ir::TypeNode *constraint = ParseTypeAnnotation(&options); 7453af6ab5fSopenharmony_ci 7463af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = constraint->End(); 7473af6ab5fSopenharmony_ci 7483af6ab5fSopenharmony_ci auto *typeParameter = AllocNode<ir::TSTypeParameter>(paramName, constraint, nullptr); 7493af6ab5fSopenharmony_ci 7503af6ab5fSopenharmony_ci typeParameter->SetRange({startLoc, endLoc}); 7513af6ab5fSopenharmony_ci 7523af6ab5fSopenharmony_ci return typeParameter; 7533af6ab5fSopenharmony_ci} 7543af6ab5fSopenharmony_ci 7553af6ab5fSopenharmony_ciir::MappedOption TSParser::ParseMappedOption(lexer::TokenType tokenType) 7563af6ab5fSopenharmony_ci{ 7573af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MINUS && 7583af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_PLUS && 7593af6ab5fSopenharmony_ci Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) { 7603af6ab5fSopenharmony_ci return ir::MappedOption::NO_OPTS; 7613af6ab5fSopenharmony_ci } 7623af6ab5fSopenharmony_ci 7633af6ab5fSopenharmony_ci auto result = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS ? ir::MappedOption::MINUS 7643af6ab5fSopenharmony_ci : ir::MappedOption::PLUS; 7653af6ab5fSopenharmony_ci 7663af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS || 7673af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PLUS) { 7683af6ab5fSopenharmony_ci Lexer()->NextToken(); 7693af6ab5fSopenharmony_ci } 7703af6ab5fSopenharmony_ci 7713af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() != tokenType && Lexer()->GetToken().Type() != tokenType) { 7723af6ab5fSopenharmony_ci ThrowSyntaxError({"'", TokenToString(tokenType), "' expected."}); 7733af6ab5fSopenharmony_ci } 7743af6ab5fSopenharmony_ci 7753af6ab5fSopenharmony_ci Lexer()->NextToken(); 7763af6ab5fSopenharmony_ci 7773af6ab5fSopenharmony_ci return result; 7783af6ab5fSopenharmony_ci} 7793af6ab5fSopenharmony_ci 7803af6ab5fSopenharmony_ciir::TSMappedType *TSParser::ParseMappedType() 7813af6ab5fSopenharmony_ci{ 7823af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); 7833af6ab5fSopenharmony_ci 7843af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 7853af6ab5fSopenharmony_ci Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat '{' 7863af6ab5fSopenharmony_ci 7873af6ab5fSopenharmony_ci ir::MappedOption readonly = ParseMappedOption(lexer::TokenType::KEYW_READONLY); 7883af6ab5fSopenharmony_ci 7893af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 7903af6ab5fSopenharmony_ci 7913af6ab5fSopenharmony_ci ir::TSTypeParameter *typeParameter = ParseMappedTypeParameter(); 7923af6ab5fSopenharmony_ci 7933af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 7943af6ab5fSopenharmony_ci ThrowSyntaxError("']' expected"); 7953af6ab5fSopenharmony_ci } 7963af6ab5fSopenharmony_ci 7973af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ']' 7983af6ab5fSopenharmony_ci 7993af6ab5fSopenharmony_ci ir::MappedOption optional = ParseMappedOption(lexer::TokenType::PUNCTUATOR_QUESTION_MARK); 8003af6ab5fSopenharmony_ci 8013af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = nullptr; 8023af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 8033af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 8043af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 8053af6ab5fSopenharmony_ci typeAnnotation = ParseTypeAnnotation(&options); 8063af6ab5fSopenharmony_ci } 8073af6ab5fSopenharmony_ci 8083af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON && 8093af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 8103af6ab5fSopenharmony_ci ThrowSyntaxError("';' expected"); 8113af6ab5fSopenharmony_ci } 8123af6ab5fSopenharmony_ci 8133af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { 8143af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ';' 8153af6ab5fSopenharmony_ci } 8163af6ab5fSopenharmony_ci 8173af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { 8183af6ab5fSopenharmony_ci ThrowSyntaxError("'}' expected"); 8193af6ab5fSopenharmony_ci } 8203af6ab5fSopenharmony_ci 8213af6ab5fSopenharmony_ci auto *mappedType = AllocNode<ir::TSMappedType>(typeParameter, typeAnnotation, readonly, optional); 8223af6ab5fSopenharmony_ci 8233af6ab5fSopenharmony_ci mappedType->SetRange({startLoc, Lexer()->GetToken().End()}); 8243af6ab5fSopenharmony_ci 8253af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '}' 8263af6ab5fSopenharmony_ci 8273af6ab5fSopenharmony_ci return mappedType; 8283af6ab5fSopenharmony_ci} 8293af6ab5fSopenharmony_ci 8303af6ab5fSopenharmony_ciir::TSTypePredicate *TSParser::ParseTypePredicate() 8313af6ab5fSopenharmony_ci{ 8323af6ab5fSopenharmony_ci auto pos = Lexer()->Save(); 8333af6ab5fSopenharmony_ci lexer::SourcePosition startPos = Lexer()->GetToken().Start(); 8343af6ab5fSopenharmony_ci bool isAsserts = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ASSERTS; 8353af6ab5fSopenharmony_ci if (isAsserts) { 8363af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'asserts' 8373af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) { 8383af6ab5fSopenharmony_ci isAsserts = false; 8393af6ab5fSopenharmony_ci Lexer()->Rewind(pos); 8403af6ab5fSopenharmony_ci } 8413af6ab5fSopenharmony_ci } 8423af6ab5fSopenharmony_ci 8433af6ab5fSopenharmony_ci ir::Expression *parameterName = nullptr; 8443af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { 8453af6ab5fSopenharmony_ci parameterName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 8463af6ab5fSopenharmony_ci } else { 8473af6ab5fSopenharmony_ci parameterName = AllocNode<ir::TSThisType>(); 8483af6ab5fSopenharmony_ci } 8493af6ab5fSopenharmony_ci 8503af6ab5fSopenharmony_ci parameterName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); 8513af6ab5fSopenharmony_ci 8523af6ab5fSopenharmony_ci Lexer()->NextToken(); 8533af6ab5fSopenharmony_ci 8543af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = nullptr; 8553af6ab5fSopenharmony_ci lexer::SourcePosition endPos; 8563af6ab5fSopenharmony_ci ir::TSTypePredicate *result = nullptr; 8573af6ab5fSopenharmony_ci 8583af6ab5fSopenharmony_ci if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) { 8593af6ab5fSopenharmony_ci endPos = parameterName->End(); 8603af6ab5fSopenharmony_ci result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 8613af6ab5fSopenharmony_ci result->SetRange({startPos, endPos}); 8623af6ab5fSopenharmony_ci return result; 8633af6ab5fSopenharmony_ci } 8643af6ab5fSopenharmony_ci 8653af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'is' 8663af6ab5fSopenharmony_ci 8673af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 8683af6ab5fSopenharmony_ci typeAnnotation = ParseTypeAnnotation(&options); 8693af6ab5fSopenharmony_ci endPos = typeAnnotation->End(); 8703af6ab5fSopenharmony_ci 8713af6ab5fSopenharmony_ci result = AllocNode<ir::TSTypePredicate>(parameterName, typeAnnotation, isAsserts); 8723af6ab5fSopenharmony_ci 8733af6ab5fSopenharmony_ci result->SetRange({startPos, endPos}); 8743af6ab5fSopenharmony_ci 8753af6ab5fSopenharmony_ci return result; 8763af6ab5fSopenharmony_ci} 8773af6ab5fSopenharmony_ci 8783af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotation) 8793af6ab5fSopenharmony_ci{ 8803af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 8813af6ab5fSopenharmony_ci return nullptr; 8823af6ab5fSopenharmony_ci } 8833af6ab5fSopenharmony_ci 8843af6ab5fSopenharmony_ci if (IsStartOfMappedType()) { 8853af6ab5fSopenharmony_ci return ParseMappedType(); 8863af6ab5fSopenharmony_ci } 8873af6ab5fSopenharmony_ci 8883af6ab5fSopenharmony_ci lexer::SourcePosition bodyStart = Lexer()->GetToken().Start(); 8893af6ab5fSopenharmony_ci auto members = ParseTypeLiteralOrInterface(); 8903af6ab5fSopenharmony_ci lexer::SourcePosition bodyEnd = Lexer()->GetToken().End(); 8913af6ab5fSopenharmony_ci Lexer()->NextToken(); 8923af6ab5fSopenharmony_ci 8933af6ab5fSopenharmony_ci auto *literalType = AllocNode<ir::TSTypeLiteral>(std::move(members)); 8943af6ab5fSopenharmony_ci auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType); 8953af6ab5fSopenharmony_ci literalType->SetVariable(typeVar); 8963af6ab5fSopenharmony_ci literalType->SetRange({bodyStart, bodyEnd}); 8973af6ab5fSopenharmony_ci return literalType; 8983af6ab5fSopenharmony_ci} 8993af6ab5fSopenharmony_ci 9003af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeReferenceOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate) 9013af6ab5fSopenharmony_ci{ 9023af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 9033af6ab5fSopenharmony_ci return nullptr; 9043af6ab5fSopenharmony_ci } 9053af6ab5fSopenharmony_ci 9063af6ab5fSopenharmony_ci if (canBeTsTypePredicate && IsStartOfTypePredicate()) { 9073af6ab5fSopenharmony_ci return ParseTypePredicate(); 9083af6ab5fSopenharmony_ci } 9093af6ab5fSopenharmony_ci 9103af6ab5fSopenharmony_ci return ParseTypeOperatorOrTypeReference(); 9113af6ab5fSopenharmony_ci} 9123af6ab5fSopenharmony_ci 9133af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseThisTypeOrTypePredicate(ir::TypeNode *typeAnnotation, bool canBeTsTypePredicate, 9143af6ab5fSopenharmony_ci bool throwError) 9153af6ab5fSopenharmony_ci{ 9163af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 9173af6ab5fSopenharmony_ci return nullptr; 9183af6ab5fSopenharmony_ci } 9193af6ab5fSopenharmony_ci 9203af6ab5fSopenharmony_ci if (canBeTsTypePredicate && IsStartOfTypePredicate()) { 9213af6ab5fSopenharmony_ci return ParseTypePredicate(); 9223af6ab5fSopenharmony_ci } 9233af6ab5fSopenharmony_ci 9243af6ab5fSopenharmony_ci return ParseThisType(throwError); 9253af6ab5fSopenharmony_ci} 9263af6ab5fSopenharmony_ci 9273af6ab5fSopenharmony_ciir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType) 9283af6ab5fSopenharmony_ci{ 9293af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); 9303af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 9313af6ab5fSopenharmony_ci 9323af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 9333af6ab5fSopenharmony_ci ThrowSyntaxError("']' expected"); 9343af6ab5fSopenharmony_ci } 9353af6ab5fSopenharmony_ci 9363af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 9373af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ']' 9383af6ab5fSopenharmony_ci 9393af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = elementType->Start(); 9403af6ab5fSopenharmony_ci auto *arrayType = AllocNode<ir::TSArrayType>(elementType); 9413af6ab5fSopenharmony_ci arrayType->SetRange({startLoc, endLoc}); 9423af6ab5fSopenharmony_ci 9433af6ab5fSopenharmony_ci return arrayType; 9443af6ab5fSopenharmony_ci} 9453af6ab5fSopenharmony_ci 9463af6ab5fSopenharmony_ciir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExtends) 9473af6ab5fSopenharmony_ci{ 9483af6ab5fSopenharmony_ci ArenaVector<ir::TypeNode *> types(Allocator()->Adapter()); 9493af6ab5fSopenharmony_ci lexer::SourcePosition startLoc; 9503af6ab5fSopenharmony_ci 9513af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 9523af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_UNION; 9533af6ab5fSopenharmony_ci 9543af6ab5fSopenharmony_ci if (restrictExtends) { 9553af6ab5fSopenharmony_ci options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 9563af6ab5fSopenharmony_ci } 9573af6ab5fSopenharmony_ci 9583af6ab5fSopenharmony_ci if (type != nullptr) { 9593af6ab5fSopenharmony_ci startLoc = type->Start(); 9603af6ab5fSopenharmony_ci types.push_back(type); 9613af6ab5fSopenharmony_ci } else { 9623af6ab5fSopenharmony_ci startLoc = Lexer()->GetToken().Start(); 9633af6ab5fSopenharmony_ci } 9643af6ab5fSopenharmony_ci 9653af6ab5fSopenharmony_ci while (true) { 9663af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_OR) { 9673af6ab5fSopenharmony_ci break; 9683af6ab5fSopenharmony_ci } 9693af6ab5fSopenharmony_ci 9703af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '|' 9713af6ab5fSopenharmony_ci 9723af6ab5fSopenharmony_ci types.push_back(ParseTypeAnnotation(&options)); 9733af6ab5fSopenharmony_ci } 9743af6ab5fSopenharmony_ci 9753af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = types.back()->End(); 9763af6ab5fSopenharmony_ci 9773af6ab5fSopenharmony_ci auto *unionType = AllocNode<ir::TSUnionType>(std::move(types)); 9783af6ab5fSopenharmony_ci auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType); 9793af6ab5fSopenharmony_ci unionType->SetVariable(typeVar); 9803af6ab5fSopenharmony_ci unionType->SetRange({startLoc, endLoc}); 9813af6ab5fSopenharmony_ci 9823af6ab5fSopenharmony_ci return unionType; 9833af6ab5fSopenharmony_ci} 9843af6ab5fSopenharmony_ci 9853af6ab5fSopenharmony_ciir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bool inUnion, bool restrictExtends) 9863af6ab5fSopenharmony_ci{ 9873af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> types(Allocator()->Adapter()); 9883af6ab5fSopenharmony_ci lexer::SourcePosition startLoc; 9893af6ab5fSopenharmony_ci 9903af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 9913af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IN_INTERSECTION; 9923af6ab5fSopenharmony_ci 9933af6ab5fSopenharmony_ci if (restrictExtends) { 9943af6ab5fSopenharmony_ci options |= TypeAnnotationParsingOptions::RESTRICT_EXTENDS; 9953af6ab5fSopenharmony_ci } 9963af6ab5fSopenharmony_ci 9973af6ab5fSopenharmony_ci if (inUnion) { 9983af6ab5fSopenharmony_ci options |= TypeAnnotationParsingOptions::IN_UNION; 9993af6ab5fSopenharmony_ci } 10003af6ab5fSopenharmony_ci 10013af6ab5fSopenharmony_ci if (type != nullptr) { 10023af6ab5fSopenharmony_ci startLoc = type->Start(); 10033af6ab5fSopenharmony_ci types.push_back(type); 10043af6ab5fSopenharmony_ci } else { 10053af6ab5fSopenharmony_ci startLoc = Lexer()->GetToken().Start(); 10063af6ab5fSopenharmony_ci } 10073af6ab5fSopenharmony_ci 10083af6ab5fSopenharmony_ci while (true) { 10093af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_BITWISE_AND) { 10103af6ab5fSopenharmony_ci break; 10113af6ab5fSopenharmony_ci } 10123af6ab5fSopenharmony_ci 10133af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '&' 10143af6ab5fSopenharmony_ci 10153af6ab5fSopenharmony_ci types.push_back(ParseTypeAnnotation(&options)); 10163af6ab5fSopenharmony_ci } 10173af6ab5fSopenharmony_ci 10183af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = types.back()->End(); 10193af6ab5fSopenharmony_ci 10203af6ab5fSopenharmony_ci auto *intersectionType = AllocNode<ir::TSIntersectionType>(std::move(types)); 10213af6ab5fSopenharmony_ci auto *typeVar = 10223af6ab5fSopenharmony_ci varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType); 10233af6ab5fSopenharmony_ci intersectionType->SetVariable(typeVar); 10243af6ab5fSopenharmony_ci intersectionType->SetRange({startLoc, endLoc}); 10253af6ab5fSopenharmony_ci 10263af6ab5fSopenharmony_ci return intersectionType; 10273af6ab5fSopenharmony_ci} 10283af6ab5fSopenharmony_ci 10293af6ab5fSopenharmony_ciclass TSParser::ParseBasicTypeHelper { 10303af6ab5fSopenharmony_ci friend ir::TypeNode *TSParser::ParseBasicType(); 10313af6ab5fSopenharmony_ci 10323af6ab5fSopenharmony_ciprivate: 10333af6ab5fSopenharmony_ci static ir::TypeNode *GetTypeAnnotationFromLiteral(TSParser *parser, lexer::Lexer *lexer) 10343af6ab5fSopenharmony_ci { 10353af6ab5fSopenharmony_ci switch (lexer->GetToken().KeywordType()) { 10363af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: { 10373af6ab5fSopenharmony_ci if ((lexer->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { 10383af6ab5fSopenharmony_ci auto *bigintNode = parser->AllocNode<ir::BigIntLiteral>(lexer->GetToken().BigInt()); 10393af6ab5fSopenharmony_ci bigintNode->SetRange(lexer->GetToken().Loc()); 10403af6ab5fSopenharmony_ci 10413af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSLiteralType>(bigintNode); 10423af6ab5fSopenharmony_ci } 10433af6ab5fSopenharmony_ci auto *numberNode = parser->AllocNode<ir::NumberLiteral>(lexer->GetToken().GetNumber()); 10443af6ab5fSopenharmony_ci numberNode->SetRange(lexer->GetToken().Loc()); 10453af6ab5fSopenharmony_ci 10463af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSLiteralType>(numberNode); 10473af6ab5fSopenharmony_ci } 10483af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: { 10493af6ab5fSopenharmony_ci auto *stringNode = parser->AllocNode<ir::StringLiteral>(lexer->GetToken().String()); 10503af6ab5fSopenharmony_ci stringNode->SetRange(lexer->GetToken().Loc()); 10513af6ab5fSopenharmony_ci 10523af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSLiteralType>(stringNode); 10533af6ab5fSopenharmony_ci } 10543af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_TRUE: { 10553af6ab5fSopenharmony_ci auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(true); 10563af6ab5fSopenharmony_ci booleanLiteral->SetRange(lexer->GetToken().Loc()); 10573af6ab5fSopenharmony_ci 10583af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSLiteralType>(booleanLiteral); 10593af6ab5fSopenharmony_ci } 10603af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_FALSE: { 10613af6ab5fSopenharmony_ci auto *booleanLiteral = parser->AllocNode<ir::BooleanLiteral>(false); 10623af6ab5fSopenharmony_ci booleanLiteral->SetRange(lexer->GetToken().Loc()); 10633af6ab5fSopenharmony_ci 10643af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSLiteralType>(booleanLiteral); 10653af6ab5fSopenharmony_ci } 10663af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NULL: { 10673af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSNullKeyword>(); 10683af6ab5fSopenharmony_ci } 10693af6ab5fSopenharmony_ci default: { 10703af6ab5fSopenharmony_ci return nullptr; 10713af6ab5fSopenharmony_ci } 10723af6ab5fSopenharmony_ci } 10733af6ab5fSopenharmony_ci } 10743af6ab5fSopenharmony_ci 10753af6ab5fSopenharmony_ci static ir::TypeNode *GetTypeAnnotation(TSParser *parser, lexer::Lexer *lexer) 10763af6ab5fSopenharmony_ci { 10773af6ab5fSopenharmony_ci switch (lexer->GetToken().KeywordType()) { 10783af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: 10793af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: 10803af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_TRUE: 10813af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_FALSE: 10823af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NULL: { 10833af6ab5fSopenharmony_ci return GetTypeAnnotationFromLiteral(parser, lexer); 10843af6ab5fSopenharmony_ci } 10853af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_ANY: { 10863af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSAnyKeyword>(); 10873af6ab5fSopenharmony_ci } 10883af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_BOOLEAN: { 10893af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSBooleanKeyword>(); 10903af6ab5fSopenharmony_ci } 10913af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NUMBER: { 10923af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSNumberKeyword>(); 10933af6ab5fSopenharmony_ci } 10943af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_STRING: { 10953af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSStringKeyword>(); 10963af6ab5fSopenharmony_ci } 10973af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_UNKNOWN: { 10983af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSUnknownKeyword>(); 10993af6ab5fSopenharmony_ci } 11003af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_VOID: { 11013af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSVoidKeyword>(); 11023af6ab5fSopenharmony_ci } 11033af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_UNDEFINED: { 11043af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSUndefinedKeyword>(); 11053af6ab5fSopenharmony_ci } 11063af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NEVER: { 11073af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSNeverKeyword>(); 11083af6ab5fSopenharmony_ci } 11093af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_OBJECT: { 11103af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSObjectKeyword>(); 11113af6ab5fSopenharmony_ci } 11123af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_BIGINT: { 11133af6ab5fSopenharmony_ci return parser->AllocNode<ir::TSBigintKeyword>(); 11143af6ab5fSopenharmony_ci } 11153af6ab5fSopenharmony_ci default: { 11163af6ab5fSopenharmony_ci parser->ThrowSyntaxError("Unexpected type"); 11173af6ab5fSopenharmony_ci } 11183af6ab5fSopenharmony_ci } 11193af6ab5fSopenharmony_ci } 11203af6ab5fSopenharmony_ci}; 11213af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseBasicType() 11223af6ab5fSopenharmony_ci{ 11233af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MINUS) { 11243af6ab5fSopenharmony_ci Lexer()->NextToken(); 11253af6ab5fSopenharmony_ci 11263af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_NUMBER) { 11273af6ab5fSopenharmony_ci ThrowSyntaxError("Type expected"); 11283af6ab5fSopenharmony_ci } 11293af6ab5fSopenharmony_ci } 11303af6ab5fSopenharmony_ci 11313af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = ParseBasicTypeHelper::GetTypeAnnotation(this, Lexer()); 11323af6ab5fSopenharmony_ci 11333af6ab5fSopenharmony_ci typeAnnotation->SetRange(Lexer()->GetToken().Loc()); 11343af6ab5fSopenharmony_ci 11353af6ab5fSopenharmony_ci Lexer()->NextToken(); 11363af6ab5fSopenharmony_ci return typeAnnotation; 11373af6ab5fSopenharmony_ci} 11383af6ab5fSopenharmony_ci 11393af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError) 11403af6ab5fSopenharmony_ci{ 11413af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 11423af6ab5fSopenharmony_ci return nullptr; 11433af6ab5fSopenharmony_ci } 11443af6ab5fSopenharmony_ci 11453af6ab5fSopenharmony_ci lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); 11463af6ab5fSopenharmony_ci 11473af6ab5fSopenharmony_ci bool abstractConstructor = false; 11483af6ab5fSopenharmony_ci 11493af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_ABSTRACT) { 11503af6ab5fSopenharmony_ci abstractConstructor = true; 11513af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'abstract' 11523af6ab5fSopenharmony_ci } 11533af6ab5fSopenharmony_ci 11543af6ab5fSopenharmony_ci bool isConstructionType = false; 11553af6ab5fSopenharmony_ci 11563af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_NEW) { 11573af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'new' 11583af6ab5fSopenharmony_ci isConstructionType = true; 11593af6ab5fSopenharmony_ci 11603af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 11613af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN) { 11623af6ab5fSopenharmony_ci ThrowSyntaxError("'(' expected"); 11633af6ab5fSopenharmony_ci } 11643af6ab5fSopenharmony_ci } 11653af6ab5fSopenharmony_ci 11663af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN || isConstructionType) { 11673af6ab5fSopenharmony_ci return ParseFunctionType(typeStart, isConstructionType, throwError, abstractConstructor); 11683af6ab5fSopenharmony_ci } 11693af6ab5fSopenharmony_ci 11703af6ab5fSopenharmony_ci const auto startPos = Lexer()->Save(); 11713af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 11723af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '(' 11733af6ab5fSopenharmony_ci 11743af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 11753af6ab5fSopenharmony_ci ir::TypeNode *type = ParseTypeAnnotation(&options); 11763af6ab5fSopenharmony_ci 11773af6ab5fSopenharmony_ci if (type == nullptr) { 11783af6ab5fSopenharmony_ci Lexer()->Rewind(startPos); 11793af6ab5fSopenharmony_ci return ParseFunctionType(typeStart, false, throwError); 11803af6ab5fSopenharmony_ci } 11813af6ab5fSopenharmony_ci 11823af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || 11833af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK || 11843af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 11853af6ab5fSopenharmony_ci Lexer()->Rewind(startPos); 11863af6ab5fSopenharmony_ci return ParseFunctionType(typeStart, false, throwError); 11873af6ab5fSopenharmony_ci } 11883af6ab5fSopenharmony_ci 11893af6ab5fSopenharmony_ci if (throwError && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 11903af6ab5fSopenharmony_ci ThrowSyntaxError("')' expected"); 11913af6ab5fSopenharmony_ci } 11923af6ab5fSopenharmony_ci 11933af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 11943af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ')' 11953af6ab5fSopenharmony_ci 11963af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW) { 11973af6ab5fSopenharmony_ci Lexer()->Rewind(startPos); 11983af6ab5fSopenharmony_ci 11993af6ab5fSopenharmony_ci return ParseFunctionType(typeStart, false, throwError); 12003af6ab5fSopenharmony_ci } 12013af6ab5fSopenharmony_ci 12023af6ab5fSopenharmony_ci auto *result = AllocNode<ir::TSParenthesizedType>(type); 12033af6ab5fSopenharmony_ci result->SetRange({typeStart, endLoc}); 12043af6ab5fSopenharmony_ci 12053af6ab5fSopenharmony_ci return result; 12063af6ab5fSopenharmony_ci} 12073af6ab5fSopenharmony_ci 12083af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseFunctionType(lexer::SourcePosition startLoc, bool isConstructionType, bool throwError, 12093af6ab5fSopenharmony_ci bool abstractConstructor) 12103af6ab5fSopenharmony_ci{ 12113af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 12123af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 12133af6ab5fSopenharmony_ci auto options = throwError ? TypeAnnotationParsingOptions::REPORT_ERROR : TypeAnnotationParsingOptions::NO_OPTS; 12143af6ab5fSopenharmony_ci typeParamDecl = ParseTypeParameterDeclaration(&options); 12153af6ab5fSopenharmony_ci 12163af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 12173af6ab5fSopenharmony_ci if (!throwError) { 12183af6ab5fSopenharmony_ci return nullptr; 12193af6ab5fSopenharmony_ci } 12203af6ab5fSopenharmony_ci 12213af6ab5fSopenharmony_ci ThrowSyntaxError("'(' expected"); 12223af6ab5fSopenharmony_ci } 12233af6ab5fSopenharmony_ci } 12243af6ab5fSopenharmony_ci 12253af6ab5fSopenharmony_ci auto params = ParseFunctionParams(); 12263af6ab5fSopenharmony_ci 12273af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_ARROW) { 12283af6ab5fSopenharmony_ci ThrowSyntaxError("'=>' expected"); 12293af6ab5fSopenharmony_ci } 12303af6ab5fSopenharmony_ci 12313af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '=>' 12323af6ab5fSopenharmony_ci 12333af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 12343af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 12353af6ab5fSopenharmony_ci ir::TypeNode *returnTypeAnnotation = ParseTypeAnnotation(&options); 12363af6ab5fSopenharmony_ci 12373af6ab5fSopenharmony_ci ir::TypeNode *funcType = nullptr; 12383af6ab5fSopenharmony_ci 12393af6ab5fSopenharmony_ci ir::FunctionSignature signature(typeParamDecl, std::move(params), returnTypeAnnotation); 12403af6ab5fSopenharmony_ci 12413af6ab5fSopenharmony_ci if (isConstructionType) { 12423af6ab5fSopenharmony_ci funcType = AllocNode<ir::TSConstructorType>(std::move(signature), abstractConstructor); 12433af6ab5fSopenharmony_ci } else { 12443af6ab5fSopenharmony_ci funcType = AllocNode<ir::TSFunctionType>(std::move(signature)); 12453af6ab5fSopenharmony_ci } 12463af6ab5fSopenharmony_ci 12473af6ab5fSopenharmony_ci funcType->SetRange({startLoc, returnTypeAnnotation->End()}); 12483af6ab5fSopenharmony_ci 12493af6ab5fSopenharmony_ci return funcType; 12503af6ab5fSopenharmony_ci} 12513af6ab5fSopenharmony_ci 12523af6ab5fSopenharmony_ciclass TSParser::ParseTypeAnnotationElementHelper { 12533af6ab5fSopenharmony_ci friend ir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, 12543af6ab5fSopenharmony_ci TypeAnnotationParsingOptions *options); 12553af6ab5fSopenharmony_ci 12563af6ab5fSopenharmony_ciprivate: 12573af6ab5fSopenharmony_ci static ir::TypeNode *ParseKeywordTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation, 12583af6ab5fSopenharmony_ci TypeAnnotationParsingOptions *options) 12593af6ab5fSopenharmony_ci { 12603af6ab5fSopenharmony_ci switch (lexer->GetToken().Type()) { 12613af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_NEW: { 12623af6ab5fSopenharmony_ci return parser->ParseParenthesizedOrFunctionType( 12633af6ab5fSopenharmony_ci typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 12643af6ab5fSopenharmony_ci } 12653af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_TYPEOF: { 12663af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 12673af6ab5fSopenharmony_ci break; 12683af6ab5fSopenharmony_ci } 12693af6ab5fSopenharmony_ci 12703af6ab5fSopenharmony_ci return parser->ParseTypeReferenceOrQuery(true); 12713af6ab5fSopenharmony_ci } 12723af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_IMPORT: { 12733af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 12743af6ab5fSopenharmony_ci break; 12753af6ab5fSopenharmony_ci } 12763af6ab5fSopenharmony_ci return parser->ParseImportType(lexer->GetToken().Start()); 12773af6ab5fSopenharmony_ci } 12783af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_CONST: { 12793af6ab5fSopenharmony_ci if (((*options) & TypeAnnotationParsingOptions::ALLOW_CONST) == 0) { 12803af6ab5fSopenharmony_ci break; 12813af6ab5fSopenharmony_ci } 12823af6ab5fSopenharmony_ci 12833af6ab5fSopenharmony_ci (*options) &= ~TypeAnnotationParsingOptions::ALLOW_CONST; 12843af6ab5fSopenharmony_ci return parser->ParseConstExpression(); 12853af6ab5fSopenharmony_ci } 12863af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_EXTENDS: { 12873af6ab5fSopenharmony_ci if (((*options) & 12883af6ab5fSopenharmony_ci (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) { 12893af6ab5fSopenharmony_ci break; 12903af6ab5fSopenharmony_ci } 12913af6ab5fSopenharmony_ci 12923af6ab5fSopenharmony_ci if (typeAnnotation == nullptr) { 12933af6ab5fSopenharmony_ci return parser->ParseIdentifierReference(); 12943af6ab5fSopenharmony_ci } 12953af6ab5fSopenharmony_ci 12963af6ab5fSopenharmony_ci return parser->ParseConditionalType(typeAnnotation, 12973af6ab5fSopenharmony_ci ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 12983af6ab5fSopenharmony_ci } 12993af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_THIS: { 13003af6ab5fSopenharmony_ci return parser->ParseThisTypeOrTypePredicate( 13013af6ab5fSopenharmony_ci typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0, 13023af6ab5fSopenharmony_ci ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 13033af6ab5fSopenharmony_ci } 13043af6ab5fSopenharmony_ci default: { 13053af6ab5fSopenharmony_ci break; 13063af6ab5fSopenharmony_ci } 13073af6ab5fSopenharmony_ci } 13083af6ab5fSopenharmony_ci return nullptr; 13093af6ab5fSopenharmony_ci } 13103af6ab5fSopenharmony_ci 13113af6ab5fSopenharmony_ci static ir::TypeNode *ParsePunctuatorTokens(TSParser *parser, lexer::Lexer *lexer, ir::TypeNode *typeAnnotation, 13123af6ab5fSopenharmony_ci TypeAnnotationParsingOptions *options) 13133af6ab5fSopenharmony_ci { 13143af6ab5fSopenharmony_ci switch (lexer->GetToken().Type()) { 13153af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { 13163af6ab5fSopenharmony_ci if (((*options) & 13173af6ab5fSopenharmony_ci (TypeAnnotationParsingOptions::IN_UNION | TypeAnnotationParsingOptions::IN_INTERSECTION)) != 0) { 13183af6ab5fSopenharmony_ci break; 13193af6ab5fSopenharmony_ci } 13203af6ab5fSopenharmony_ci 13213af6ab5fSopenharmony_ci return parser->ParseUnionType(typeAnnotation, 13223af6ab5fSopenharmony_ci ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 13233af6ab5fSopenharmony_ci } 13243af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { 13253af6ab5fSopenharmony_ci if (((*options) & TypeAnnotationParsingOptions::IN_INTERSECTION) != 0) { 13263af6ab5fSopenharmony_ci break; 13273af6ab5fSopenharmony_ci } 13283af6ab5fSopenharmony_ci 13293af6ab5fSopenharmony_ci return parser->ParseIntersectionType( 13303af6ab5fSopenharmony_ci typeAnnotation, ((*options) & TypeAnnotationParsingOptions::IN_UNION) != 0, 13313af6ab5fSopenharmony_ci ((*options) & TypeAnnotationParsingOptions::RESTRICT_EXTENDS) != 0); 13323af6ab5fSopenharmony_ci } 13333af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LESS_THAN: 13343af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { 13353af6ab5fSopenharmony_ci return parser->ParseParenthesizedOrFunctionType( 13363af6ab5fSopenharmony_ci typeAnnotation, ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 13373af6ab5fSopenharmony_ci } 13383af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 13393af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 13403af6ab5fSopenharmony_ci if (lexer->Lookahead() == lexer::LEX_CHAR_RIGHT_SQUARE) { 13413af6ab5fSopenharmony_ci return parser->ParseArrayType(typeAnnotation); 13423af6ab5fSopenharmony_ci } 13433af6ab5fSopenharmony_ci 13443af6ab5fSopenharmony_ci return parser->ParseIndexAccessType(typeAnnotation); 13453af6ab5fSopenharmony_ci } 13463af6ab5fSopenharmony_ci 13473af6ab5fSopenharmony_ci return parser->ParseTupleType(); 13483af6ab5fSopenharmony_ci } 13493af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { 13503af6ab5fSopenharmony_ci return parser->ParseTypeLiteralOrMappedType(typeAnnotation); 13513af6ab5fSopenharmony_ci } 13523af6ab5fSopenharmony_ci default: { 13533af6ab5fSopenharmony_ci break; 13543af6ab5fSopenharmony_ci } 13553af6ab5fSopenharmony_ci } 13563af6ab5fSopenharmony_ci 13573af6ab5fSopenharmony_ci return nullptr; 13583af6ab5fSopenharmony_ci } 13593af6ab5fSopenharmony_ci}; 13603af6ab5fSopenharmony_ci 13613af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseTypeAnnotationElement(ir::TypeNode *typeAnnotation, TypeAnnotationParsingOptions *options) 13623af6ab5fSopenharmony_ci{ 13633af6ab5fSopenharmony_ci switch (Lexer()->GetToken().Type()) { 13643af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_MINUS: 13653af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: 13663af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: 13673af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_FALSE: 13683af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_TRUE: 13693af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NULL: 13703af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_VOID: { 13713af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 13723af6ab5fSopenharmony_ci break; 13733af6ab5fSopenharmony_ci } 13743af6ab5fSopenharmony_ci 13753af6ab5fSopenharmony_ci return ParseBasicType(); 13763af6ab5fSopenharmony_ci } 13773af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 13783af6ab5fSopenharmony_ci if (IsStartOfAbstractConstructorType()) { 13793af6ab5fSopenharmony_ci return ParseParenthesizedOrFunctionType(typeAnnotation, 13803af6ab5fSopenharmony_ci ((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0); 13813af6ab5fSopenharmony_ci } 13823af6ab5fSopenharmony_ci 13833af6ab5fSopenharmony_ci return ParseTypeReferenceOrTypePredicate( 13843af6ab5fSopenharmony_ci typeAnnotation, ((*options) & TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE) != 0); 13853af6ab5fSopenharmony_ci } 13863af6ab5fSopenharmony_ci default: { 13873af6ab5fSopenharmony_ci ir::TypeNode *parsedValue = 13883af6ab5fSopenharmony_ci ParseTypeAnnotationElementHelper::ParseKeywordTokens(this, Lexer(), typeAnnotation, options); 13893af6ab5fSopenharmony_ci if (parsedValue != nullptr) { 13903af6ab5fSopenharmony_ci return parsedValue; 13913af6ab5fSopenharmony_ci } 13923af6ab5fSopenharmony_ci 13933af6ab5fSopenharmony_ci parsedValue = 13943af6ab5fSopenharmony_ci ParseTypeAnnotationElementHelper::ParsePunctuatorTokens(this, Lexer(), typeAnnotation, options); 13953af6ab5fSopenharmony_ci if (parsedValue != nullptr) { 13963af6ab5fSopenharmony_ci return parsedValue; 13973af6ab5fSopenharmony_ci } 13983af6ab5fSopenharmony_ci 13993af6ab5fSopenharmony_ci break; 14003af6ab5fSopenharmony_ci } 14013af6ab5fSopenharmony_ci } 14023af6ab5fSopenharmony_ci 14033af6ab5fSopenharmony_ci if (typeAnnotation == nullptr && (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0)) { 14043af6ab5fSopenharmony_ci ThrowSyntaxError("Type expected"); 14053af6ab5fSopenharmony_ci } 14063af6ab5fSopenharmony_ci 14073af6ab5fSopenharmony_ci return nullptr; 14083af6ab5fSopenharmony_ci} 14093af6ab5fSopenharmony_ci 14103af6ab5fSopenharmony_cibool TSParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression, 14113af6ab5fSopenharmony_ci const lexer::SourcePosition &startLoc, bool ignoreCallExpression) 14123af6ab5fSopenharmony_ci{ 14133af6ab5fSopenharmony_ci if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN || 14143af6ab5fSopenharmony_ci (!primaryExpr->IsIdentifier() && !primaryExpr->IsMemberExpression())) { 14153af6ab5fSopenharmony_ci return true; 14163af6ab5fSopenharmony_ci } 14173af6ab5fSopenharmony_ci 14183af6ab5fSopenharmony_ci const auto savedPos = Lexer()->Save(); 14193af6ab5fSopenharmony_ci 14203af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { 14213af6ab5fSopenharmony_ci Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); 14223af6ab5fSopenharmony_ci } 14233af6ab5fSopenharmony_ci 14243af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; 14253af6ab5fSopenharmony_ci ir::TSTypeParameterInstantiation *typeParams = ParseTypeParameterInstantiation(&options); 14263af6ab5fSopenharmony_ci 14273af6ab5fSopenharmony_ci if (typeParams == nullptr) { 14283af6ab5fSopenharmony_ci Lexer()->Rewind(savedPos); 14293af6ab5fSopenharmony_ci return true; 14303af6ab5fSopenharmony_ci } 14313af6ab5fSopenharmony_ci 14323af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::EOS) { 14333af6ab5fSopenharmony_ci ThrowSyntaxError("'(' or '`' expected"); 14343af6ab5fSopenharmony_ci } 14353af6ab5fSopenharmony_ci 14363af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 14373af6ab5fSopenharmony_ci if (!ignoreCallExpression) { 14383af6ab5fSopenharmony_ci *returnExpression = ParseCallExpression(*returnExpression, false); 14393af6ab5fSopenharmony_ci (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams); 14403af6ab5fSopenharmony_ci return false; 14413af6ab5fSopenharmony_ci } 14423af6ab5fSopenharmony_ci 14433af6ab5fSopenharmony_ci return true; 14443af6ab5fSopenharmony_ci } 14453af6ab5fSopenharmony_ci 14463af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) { 14473af6ab5fSopenharmony_ci ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); 14483af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = propertyNode->End(); 14493af6ab5fSopenharmony_ci 14503af6ab5fSopenharmony_ci *returnExpression = AllocNode<ir::TaggedTemplateExpression>(*returnExpression, propertyNode, typeParams); 14513af6ab5fSopenharmony_ci (*returnExpression)->SetRange({startLoc, endLoc}); 14523af6ab5fSopenharmony_ci return false; 14533af6ab5fSopenharmony_ci } 14543af6ab5fSopenharmony_ci 14553af6ab5fSopenharmony_ci Lexer()->Rewind(savedPos); 14563af6ab5fSopenharmony_ci return true; 14573af6ab5fSopenharmony_ci} 14583af6ab5fSopenharmony_ci 14593af6ab5fSopenharmony_cibool TSParser::IsNamedFunctionExpression() 14603af6ab5fSopenharmony_ci{ 14613af6ab5fSopenharmony_ci return Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && 14623af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN; 14633af6ab5fSopenharmony_ci} 14643af6ab5fSopenharmony_ci 14653af6ab5fSopenharmony_ciir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) 14663af6ab5fSopenharmony_ci{ 14673af6ab5fSopenharmony_ci auto *identNode = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 14683af6ab5fSopenharmony_ci identNode->SetReference(); 14693af6ab5fSopenharmony_ci identNode->SetRange(Lexer()->GetToken().Loc()); 14703af6ab5fSopenharmony_ci 14713af6ab5fSopenharmony_ci Lexer()->NextToken(); 14723af6ab5fSopenharmony_ci 14733af6ab5fSopenharmony_ci ParsePotentialOptionalFunctionParameter(identNode); 14743af6ab5fSopenharmony_ci 14753af6ab5fSopenharmony_ci return identNode; 14763af6ab5fSopenharmony_ci} 14773af6ab5fSopenharmony_ci 14783af6ab5fSopenharmony_ciir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature) 14793af6ab5fSopenharmony_ci{ 14803af6ab5fSopenharmony_ci lexer::SourcePosition memberStartLoc = Lexer()->GetToken().Start(); 14813af6ab5fSopenharmony_ci 14823af6ab5fSopenharmony_ci if (!isCallSignature) { 14833af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'new' keyword 14843af6ab5fSopenharmony_ci } 14853af6ab5fSopenharmony_ci 14863af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 14873af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 14883af6ab5fSopenharmony_ci auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 14893af6ab5fSopenharmony_ci typeParamDecl = ParseTypeParameterDeclaration(&options); 14903af6ab5fSopenharmony_ci 14913af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { 14923af6ab5fSopenharmony_ci ThrowSyntaxError("'(' expected"); 14933af6ab5fSopenharmony_ci } 14943af6ab5fSopenharmony_ci } 14953af6ab5fSopenharmony_ci 14963af6ab5fSopenharmony_ci FunctionParameterContext funcParamContext(&GetContext()); 14973af6ab5fSopenharmony_ci auto params = ParseFunctionParams(); 14983af6ab5fSopenharmony_ci 14993af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = nullptr; 15003af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 15013af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 15023af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 15033af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 15043af6ab5fSopenharmony_ci typeAnnotation = ParseTypeAnnotation(&options); 15053af6ab5fSopenharmony_ci } 15063af6ab5fSopenharmony_ci 15073af6ab5fSopenharmony_ci auto kind = isCallSignature ? ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE 15083af6ab5fSopenharmony_ci : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE; 15093af6ab5fSopenharmony_ci auto *signatureMember = AllocNode<ir::TSSignatureDeclaration>( 15103af6ab5fSopenharmony_ci kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation)); 15113af6ab5fSopenharmony_ci signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()}); 15123af6ab5fSopenharmony_ci 15133af6ab5fSopenharmony_ci return signatureMember; 15143af6ab5fSopenharmony_ci} 15153af6ab5fSopenharmony_ci 15163af6ab5fSopenharmony_cibool TSParser::IsPotentiallyIndexSignature() 15173af6ab5fSopenharmony_ci{ 15183af6ab5fSopenharmony_ci const auto savedPos = Lexer()->Save(); 15193af6ab5fSopenharmony_ci 15203af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 15213af6ab5fSopenharmony_ci 15223af6ab5fSopenharmony_ci bool isIndexSignature = 15233af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON; 15243af6ab5fSopenharmony_ci 15253af6ab5fSopenharmony_ci Lexer()->Rewind(savedPos); 15263af6ab5fSopenharmony_ci 15273af6ab5fSopenharmony_ci return isIndexSignature; 15283af6ab5fSopenharmony_ci} 15293af6ab5fSopenharmony_ci 15303af6ab5fSopenharmony_ci// NOLINTNEXTLINE(google-default-arguments) 15313af6ab5fSopenharmony_ciir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition &startLoc, bool isReadonly) 15323af6ab5fSopenharmony_ci{ 15333af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '[' 15343af6ab5fSopenharmony_ci 15353af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); 15363af6ab5fSopenharmony_ci auto *key = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 15373af6ab5fSopenharmony_ci key->SetRange(Lexer()->GetToken().Loc()); 15383af6ab5fSopenharmony_ci 15393af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat key 15403af6ab5fSopenharmony_ci 15413af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON); 15423af6ab5fSopenharmony_ci 15433af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 15443af6ab5fSopenharmony_ci 15453af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 15463af6ab5fSopenharmony_ci ir::TypeNode *keyType = ParseTypeAnnotation(&options); 15473af6ab5fSopenharmony_ci 15483af6ab5fSopenharmony_ci if (!keyType->IsTSNumberKeyword() && !keyType->IsTSStringKeyword()) { 15493af6ab5fSopenharmony_ci ThrowSyntaxError( 15503af6ab5fSopenharmony_ci "An index signature parameter type must be either " 15513af6ab5fSopenharmony_ci "'string' or 'number'"); 15523af6ab5fSopenharmony_ci } 15533af6ab5fSopenharmony_ci 15543af6ab5fSopenharmony_ci key->SetTsTypeAnnotation(keyType); 15553af6ab5fSopenharmony_ci 15563af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 15573af6ab5fSopenharmony_ci ThrowSyntaxError("']' expected."); 15583af6ab5fSopenharmony_ci } 15593af6ab5fSopenharmony_ci 15603af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ']' 15613af6ab5fSopenharmony_ci 15623af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 15633af6ab5fSopenharmony_ci ThrowSyntaxError("An index signature must have a type annotation."); 15643af6ab5fSopenharmony_ci } 15653af6ab5fSopenharmony_ci 15663af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 15673af6ab5fSopenharmony_ci 15683af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 15693af6ab5fSopenharmony_ci 15703af6ab5fSopenharmony_ci auto *indexSignature = AllocNode<ir::TSIndexSignature>(key, typeAnnotation, isReadonly); 15713af6ab5fSopenharmony_ci indexSignature->SetRange({startLoc, Lexer()->GetToken().End()}); 15723af6ab5fSopenharmony_ci return indexSignature; 15733af6ab5fSopenharmony_ci} 15743af6ab5fSopenharmony_ci 15753af6ab5fSopenharmony_cistd::tuple<ir::Expression *, bool> TSParser::ParseInterfacePropertyKey() 15763af6ab5fSopenharmony_ci{ 15773af6ab5fSopenharmony_ci ir::Expression *key = nullptr; 15783af6ab5fSopenharmony_ci bool isComputed = false; 15793af6ab5fSopenharmony_ci 15803af6ab5fSopenharmony_ci switch (Lexer()->GetToken().Type()) { 15813af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_IDENT: { 15823af6ab5fSopenharmony_ci const util::StringView &ident = Lexer()->GetToken().Ident(); 15833af6ab5fSopenharmony_ci key = AllocNode<ir::Identifier>(ident, Allocator()); 15843af6ab5fSopenharmony_ci key->SetRange(Lexer()->GetToken().Loc()); 15853af6ab5fSopenharmony_ci break; 15863af6ab5fSopenharmony_ci } 15873af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_STRING: { 15883af6ab5fSopenharmony_ci const util::StringView &string = Lexer()->GetToken().String(); 15893af6ab5fSopenharmony_ci key = AllocNode<ir::StringLiteral>(string); 15903af6ab5fSopenharmony_ci key->SetRange(Lexer()->GetToken().Loc()); 15913af6ab5fSopenharmony_ci break; 15923af6ab5fSopenharmony_ci } 15933af6ab5fSopenharmony_ci case lexer::TokenType::LITERAL_NUMBER: { 15943af6ab5fSopenharmony_ci if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { 15953af6ab5fSopenharmony_ci key = AllocNode<ir::BigIntLiteral>(Lexer()->GetToken().BigInt()); 15963af6ab5fSopenharmony_ci } else { 15973af6ab5fSopenharmony_ci key = AllocNode<ir::NumberLiteral>(Lexer()->GetToken().GetNumber()); 15983af6ab5fSopenharmony_ci } 15993af6ab5fSopenharmony_ci 16003af6ab5fSopenharmony_ci key->SetRange(Lexer()->GetToken().Loc()); 16013af6ab5fSopenharmony_ci break; 16023af6ab5fSopenharmony_ci } 16033af6ab5fSopenharmony_ci case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { 16043af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat left square bracket 16053af6ab5fSopenharmony_ci 16063af6ab5fSopenharmony_ci key = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 16073af6ab5fSopenharmony_ci isComputed = true; 16083af6ab5fSopenharmony_ci 16093af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 16103af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ']'"); 16113af6ab5fSopenharmony_ci } 16123af6ab5fSopenharmony_ci break; 16133af6ab5fSopenharmony_ci } 16143af6ab5fSopenharmony_ci default: { 16153af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token in property key"); 16163af6ab5fSopenharmony_ci } 16173af6ab5fSopenharmony_ci } 16183af6ab5fSopenharmony_ci 16193af6ab5fSopenharmony_ci Lexer()->NextToken(); 16203af6ab5fSopenharmony_ci return {key, isComputed}; 16213af6ab5fSopenharmony_ci} 16223af6ab5fSopenharmony_ci 16233af6ab5fSopenharmony_civoid TSParser::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, varbinder::VariableFlags flags) 16243af6ab5fSopenharmony_ci{ 16253af6ab5fSopenharmony_ci varbinder::Variable *propVar = nullptr; 16263af6ab5fSopenharmony_ci bool isMethod = (flags & varbinder::VariableFlags::METHOD) != 0; 16273af6ab5fSopenharmony_ci util::StringView propName = "__computed"; 16283af6ab5fSopenharmony_ci 16293af6ab5fSopenharmony_ci switch (key->Type()) { 16303af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 16313af6ab5fSopenharmony_ci propName = key->AsIdentifier()->Name(); 16323af6ab5fSopenharmony_ci break; 16333af6ab5fSopenharmony_ci } 16343af6ab5fSopenharmony_ci case ir::AstNodeType::NUMBER_LITERAL: { 16353af6ab5fSopenharmony_ci propName = key->AsNumberLiteral()->Str(); 16363af6ab5fSopenharmony_ci flags |= varbinder::VariableFlags::NUMERIC_NAME; 16373af6ab5fSopenharmony_ci break; 16383af6ab5fSopenharmony_ci } 16393af6ab5fSopenharmony_ci case ir::AstNodeType::STRING_LITERAL: { 16403af6ab5fSopenharmony_ci propName = key->AsStringLiteral()->Str(); 16413af6ab5fSopenharmony_ci break; 16423af6ab5fSopenharmony_ci } 16433af6ab5fSopenharmony_ci default: { 16443af6ab5fSopenharmony_ci flags |= varbinder::VariableFlags::COMPUTED; 16453af6ab5fSopenharmony_ci break; 16463af6ab5fSopenharmony_ci } 16473af6ab5fSopenharmony_ci } 16483af6ab5fSopenharmony_ci 16493af6ab5fSopenharmony_ci propVar = isMethod ? varbinder::Scope::CreateVar<varbinder::MethodDecl>(Allocator(), propName, flags, node) 16503af6ab5fSopenharmony_ci : varbinder::Scope::CreateVar<varbinder::PropertyDecl>(Allocator(), propName, flags, node); 16513af6ab5fSopenharmony_ci 16523af6ab5fSopenharmony_ci node->SetVariable(propVar); 16533af6ab5fSopenharmony_ci} 16543af6ab5fSopenharmony_ci 16553af6ab5fSopenharmony_ciir::AstNode *TSParser::ParsePropertyOrMethodSignature(const lexer::SourcePosition &startLoc, bool isReadonly) 16563af6ab5fSopenharmony_ci{ 16573af6ab5fSopenharmony_ci auto [key, isComputed] = ParseInterfacePropertyKey(); 16583af6ab5fSopenharmony_ci varbinder::VariableFlags flags = isReadonly ? varbinder::VariableFlags::READONLY : varbinder::VariableFlags::NONE; 16593af6ab5fSopenharmony_ci 16603af6ab5fSopenharmony_ci bool isOptional = false; 16613af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { 16623af6ab5fSopenharmony_ci isOptional = true; 16633af6ab5fSopenharmony_ci flags |= varbinder::VariableFlags::OPTIONAL; 16643af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat '?' 16653af6ab5fSopenharmony_ci } 16663af6ab5fSopenharmony_ci 16673af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 16683af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 16693af6ab5fSopenharmony_ci if (isReadonly) { 16703af6ab5fSopenharmony_ci ThrowSyntaxError("'readonly' modifier can only appear on a property declaration or index signature.", 16713af6ab5fSopenharmony_ci startLoc); 16723af6ab5fSopenharmony_ci } 16733af6ab5fSopenharmony_ci 16743af6ab5fSopenharmony_ci ir::TSTypeParameterDeclaration *typeParamDecl = nullptr; 16753af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 16763af6ab5fSopenharmony_ci auto options = TypeAnnotationParsingOptions::REPORT_ERROR; 16773af6ab5fSopenharmony_ci typeParamDecl = ParseTypeParameterDeclaration(&options); 16783af6ab5fSopenharmony_ci } 16793af6ab5fSopenharmony_ci 16803af6ab5fSopenharmony_ci ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, false); 16813af6ab5fSopenharmony_ci 16823af6ab5fSopenharmony_ci FunctionParameterContext funcParamContext(&GetContext()); 16833af6ab5fSopenharmony_ci auto params = ParseFunctionParams(); 16843af6ab5fSopenharmony_ci 16853af6ab5fSopenharmony_ci ir::TypeNode *returnType = nullptr; 16863af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 16873af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 16883af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 16893af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 16903af6ab5fSopenharmony_ci returnType = ParseTypeAnnotation(&options); 16913af6ab5fSopenharmony_ci } 16923af6ab5fSopenharmony_ci 16933af6ab5fSopenharmony_ci auto *methodSignature = AllocNode<ir::TSMethodSignature>( 16943af6ab5fSopenharmony_ci key, ir::FunctionSignature(typeParamDecl, std::move(params), returnType), isComputed, isOptional); 16953af6ab5fSopenharmony_ci CreateTSVariableForProperty(methodSignature, key, flags | varbinder::VariableFlags::METHOD); 16963af6ab5fSopenharmony_ci methodSignature->SetRange({startLoc, Lexer()->GetToken().End()}); 16973af6ab5fSopenharmony_ci return methodSignature; 16983af6ab5fSopenharmony_ci } 16993af6ab5fSopenharmony_ci 17003af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = nullptr; 17013af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 17023af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 17033af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 17043af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 17053af6ab5fSopenharmony_ci typeAnnotation = ParseTypeAnnotation(&options); 17063af6ab5fSopenharmony_ci } 17073af6ab5fSopenharmony_ci 17083af6ab5fSopenharmony_ci auto *propertySignature = 17093af6ab5fSopenharmony_ci AllocNode<ir::TSPropertySignature>(key, typeAnnotation, isComputed, isOptional, isReadonly); 17103af6ab5fSopenharmony_ci CreateTSVariableForProperty(propertySignature, key, flags | varbinder::VariableFlags::PROPERTY); 17113af6ab5fSopenharmony_ci propertySignature->SetRange({startLoc, Lexer()->GetToken().End()}); 17123af6ab5fSopenharmony_ci return propertySignature; 17133af6ab5fSopenharmony_ci} 17143af6ab5fSopenharmony_ci 17153af6ab5fSopenharmony_ciir::AstNode *TSParser::ParseTypeLiteralOrInterfaceMember() 17163af6ab5fSopenharmony_ci{ 17173af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { 17183af6ab5fSopenharmony_ci ThrowSyntaxError("Decorators are not allowed here"); 17193af6ab5fSopenharmony_ci } 17203af6ab5fSopenharmony_ci 17213af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 17223af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { 17233af6ab5fSopenharmony_ci return ParseSignatureMember(true); 17243af6ab5fSopenharmony_ci } 17253af6ab5fSopenharmony_ci 17263af6ab5fSopenharmony_ci char32_t nextCp = Lexer()->Lookahead(); 17273af6ab5fSopenharmony_ci if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NEW && 17283af6ab5fSopenharmony_ci (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN)) { 17293af6ab5fSopenharmony_ci return ParseSignatureMember(false); 17303af6ab5fSopenharmony_ci } 17313af6ab5fSopenharmony_ci 17323af6ab5fSopenharmony_ci lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); 17333af6ab5fSopenharmony_ci bool isReadonly = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_READONLY && 17343af6ab5fSopenharmony_ci nextCp != lexer::LEX_CHAR_LEFT_PAREN && nextCp != lexer::LEX_CHAR_COLON && 17353af6ab5fSopenharmony_ci nextCp != lexer::LEX_CHAR_COMMA; 17363af6ab5fSopenharmony_ci if (isReadonly) { 17373af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat 'readonly" 17383af6ab5fSopenharmony_ci } 17393af6ab5fSopenharmony_ci 17403af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && 17413af6ab5fSopenharmony_ci IsPotentiallyIndexSignature()) { 17423af6ab5fSopenharmony_ci return ParseIndexSignature(startLoc, isReadonly); 17433af6ab5fSopenharmony_ci } 17443af6ab5fSopenharmony_ci 17453af6ab5fSopenharmony_ci return ParsePropertyOrMethodSignature(startLoc, isReadonly); 17463af6ab5fSopenharmony_ci} 17473af6ab5fSopenharmony_ci 17483af6ab5fSopenharmony_civoid TSParser::ValidateFunctionParam(const ArenaVector<ir::Expression *> ¶ms, const ir::Expression *parameter, 17493af6ab5fSopenharmony_ci bool *seenOptional) 17503af6ab5fSopenharmony_ci{ 17513af6ab5fSopenharmony_ci if (!parameter->IsIdentifier()) { 17523af6ab5fSopenharmony_ci GetContext().Status() |= ParserStatus::HAS_COMPLEX_PARAM; 17533af6ab5fSopenharmony_ci if (!parameter->IsRestElement()) { 17543af6ab5fSopenharmony_ci return; 17553af6ab5fSopenharmony_ci } 17563af6ab5fSopenharmony_ci 17573af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 17583af6ab5fSopenharmony_ci ThrowSyntaxError("A rest parameter must be last in parameter list"); 17593af6ab5fSopenharmony_ci } 17603af6ab5fSopenharmony_ci return; 17613af6ab5fSopenharmony_ci } 17623af6ab5fSopenharmony_ci 17633af6ab5fSopenharmony_ci bool currentIsOptional = parameter->AsIdentifier()->IsOptional(); 17643af6ab5fSopenharmony_ci if (*seenOptional && !currentIsOptional) { 17653af6ab5fSopenharmony_ci ThrowSyntaxError("A required parameter cannot follow an optional parameter"); 17663af6ab5fSopenharmony_ci } 17673af6ab5fSopenharmony_ci 17683af6ab5fSopenharmony_ci *seenOptional |= currentIsOptional; 17693af6ab5fSopenharmony_ci const util::StringView ¶mName = parameter->AsIdentifier()->Name(); 17703af6ab5fSopenharmony_ci 17713af6ab5fSopenharmony_ci if (paramName.Is("this")) { 17723af6ab5fSopenharmony_ci if (!params.empty()) { 17733af6ab5fSopenharmony_ci ThrowSyntaxError("A 'this' parameter must be the first parameter"); 17743af6ab5fSopenharmony_ci } 17753af6ab5fSopenharmony_ci 17763af6ab5fSopenharmony_ci if ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0) { 17773af6ab5fSopenharmony_ci ThrowSyntaxError("A constructor cannot have a 'this' parameter"); 17783af6ab5fSopenharmony_ci } 17793af6ab5fSopenharmony_ci 17803af6ab5fSopenharmony_ci if ((GetContext().Status() & ParserStatus::ARROW_FUNCTION) != 0) { 17813af6ab5fSopenharmony_ci ThrowSyntaxError("An arrow function cannot have a 'this' parameter"); 17823af6ab5fSopenharmony_ci } 17833af6ab5fSopenharmony_ci 17843af6ab5fSopenharmony_ci if ((GetContext().Status() & ParserStatus::ACCESSOR_FUNCTION) != 0) { 17853af6ab5fSopenharmony_ci ThrowSyntaxError("'get' and 'set' accessors cannot declare 'this' parameters"); 17863af6ab5fSopenharmony_ci } 17873af6ab5fSopenharmony_ci } 17883af6ab5fSopenharmony_ci 17893af6ab5fSopenharmony_ci if (paramName.Is("constructor") && ((GetContext().Status() & ParserStatus::CONSTRUCTOR_FUNCTION) != 0)) { 17903af6ab5fSopenharmony_ci ThrowSyntaxError("'constructor' cannot be used as a parameter property name"); 17913af6ab5fSopenharmony_ci } 17923af6ab5fSopenharmony_ci} 17933af6ab5fSopenharmony_ci 17943af6ab5fSopenharmony_ciArenaVector<ir::Expression *> TSParser::ParseFunctionParams() 17953af6ab5fSopenharmony_ci{ 17963af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); 17973af6ab5fSopenharmony_ci Lexer()->NextToken(); 17983af6ab5fSopenharmony_ci 17993af6ab5fSopenharmony_ci ArenaVector<ir::Expression *> params(Allocator()->Adapter()); 18003af6ab5fSopenharmony_ci bool seenOptional = false; 18013af6ab5fSopenharmony_ci 18023af6ab5fSopenharmony_ci while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 18033af6ab5fSopenharmony_ci ArenaVector<ir::Decorator *> decorators(Allocator()->Adapter()); 18043af6ab5fSopenharmony_ci 18053af6ab5fSopenharmony_ci ParseDecorators(decorators); 18063af6ab5fSopenharmony_ci 18073af6ab5fSopenharmony_ci if (!decorators.empty() && ((GetContext().Status() & ParserStatus::IN_CLASS_BODY) == 0)) { 18083af6ab5fSopenharmony_ci ThrowSyntaxError("Decorators are not valid here", decorators.front()->Start()); 18093af6ab5fSopenharmony_ci } 18103af6ab5fSopenharmony_ci 18113af6ab5fSopenharmony_ci ir::Expression *parameter = ParseFunctionParameter(); 18123af6ab5fSopenharmony_ci ValidateFunctionParam(params, parameter, &seenOptional); 18133af6ab5fSopenharmony_ci 18143af6ab5fSopenharmony_ci if (!decorators.empty()) { 18153af6ab5fSopenharmony_ci parameter->AddDecorators(std::move(decorators)); 18163af6ab5fSopenharmony_ci } 18173af6ab5fSopenharmony_ci 18183af6ab5fSopenharmony_ci params.push_back(parameter); 18193af6ab5fSopenharmony_ci 18203af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && 18213af6ab5fSopenharmony_ci Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { 18223af6ab5fSopenharmony_ci ThrowSyntaxError(", expected"); 18233af6ab5fSopenharmony_ci } 18243af6ab5fSopenharmony_ci 18253af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 18263af6ab5fSopenharmony_ci Lexer()->NextToken(); 18273af6ab5fSopenharmony_ci } 18283af6ab5fSopenharmony_ci } 18293af6ab5fSopenharmony_ci 18303af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); 18313af6ab5fSopenharmony_ci Lexer()->NextToken(); 18323af6ab5fSopenharmony_ci 18333af6ab5fSopenharmony_ci return params; 18343af6ab5fSopenharmony_ci} 18353af6ab5fSopenharmony_ci 18363af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseClassKeyAnnotation() 18373af6ab5fSopenharmony_ci{ 18383af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 18393af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 18403af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 18413af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::BREAK_AT_NEW_LINE; 18423af6ab5fSopenharmony_ci return ParseTypeAnnotation(&options); 18433af6ab5fSopenharmony_ci } 18443af6ab5fSopenharmony_ci 18453af6ab5fSopenharmony_ci return nullptr; 18463af6ab5fSopenharmony_ci} 18473af6ab5fSopenharmony_ci 18483af6ab5fSopenharmony_civoid TSParser::ValidateClassMethodStart(ClassElementDescriptor *desc, ir::TypeNode *typeAnnotation) 18493af6ab5fSopenharmony_ci{ 18503af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && desc->isPrivateIdent) { 18513af6ab5fSopenharmony_ci ThrowSyntaxError("A method cannot be named with a private identifier"); 18523af6ab5fSopenharmony_ci } 18533af6ab5fSopenharmony_ci 18543af6ab5fSopenharmony_ci if (typeAnnotation == nullptr && (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || 18553af6ab5fSopenharmony_ci Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN)) { 18563af6ab5fSopenharmony_ci if (((desc->modifiers & (ir::ModifierFlags::DECLARE | ir::ModifierFlags::READONLY)) != 0)) { 18573af6ab5fSopenharmony_ci ThrowSyntaxError("Class method can not be declare nor readonly"); 18583af6ab5fSopenharmony_ci } 18593af6ab5fSopenharmony_ci desc->classMethod = true; 18603af6ab5fSopenharmony_ci } else { 18613af6ab5fSopenharmony_ci if (((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) || desc->isGenerator) { 18623af6ab5fSopenharmony_ci ThrowSyntaxError("Expected '('"); 18633af6ab5fSopenharmony_ci } 18643af6ab5fSopenharmony_ci desc->classField = true; 18653af6ab5fSopenharmony_ci 18663af6ab5fSopenharmony_ci if (desc->invalidComputedProperty) { 18673af6ab5fSopenharmony_ci ThrowSyntaxError( 18683af6ab5fSopenharmony_ci "Computed property name must refer to a symbol or " 18693af6ab5fSopenharmony_ci "literal expression whose value is " 18703af6ab5fSopenharmony_ci "number or string"); 18713af6ab5fSopenharmony_ci } 18723af6ab5fSopenharmony_ci } 18733af6ab5fSopenharmony_ci 18743af6ab5fSopenharmony_ci if ((desc->modifiers & ir::ModifierFlags::ASYNC) != 0) { 18753af6ab5fSopenharmony_ci desc->newStatus |= ParserStatus::ASYNC_FUNCTION; 18763af6ab5fSopenharmony_ci } 18773af6ab5fSopenharmony_ci 18783af6ab5fSopenharmony_ci if (desc->isGenerator) { 18793af6ab5fSopenharmony_ci desc->newStatus |= ParserStatus::GENERATOR_FUNCTION; 18803af6ab5fSopenharmony_ci } 18813af6ab5fSopenharmony_ci} 18823af6ab5fSopenharmony_ci 18833af6ab5fSopenharmony_ciir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, 18843af6ab5fSopenharmony_ci const ArenaVector<ir::AstNode *> &properties, ir::Expression *propName, 18853af6ab5fSopenharmony_ci lexer::SourcePosition *propEnd) 18863af6ab5fSopenharmony_ci{ 18873af6ab5fSopenharmony_ci if (desc->methodKind == ir::MethodDefinitionKind::SET || desc->methodKind == ir::MethodDefinitionKind::GET) { 18883af6ab5fSopenharmony_ci desc->newStatus |= ParserStatus::ACCESSOR_FUNCTION; 18893af6ab5fSopenharmony_ci } 18903af6ab5fSopenharmony_ci 18913af6ab5fSopenharmony_ci desc->newStatus |= ParserStatus::IN_METHOD_DEFINITION; 18923af6ab5fSopenharmony_ci 18933af6ab5fSopenharmony_ci if (InAmbientContext() && (desc->newStatus & ParserStatus::ASYNC_FUNCTION) != 0) { 18943af6ab5fSopenharmony_ci ThrowSyntaxError("'async' modifier cannot be used in an ambient context."); 18953af6ab5fSopenharmony_ci } 18963af6ab5fSopenharmony_ci 18973af6ab5fSopenharmony_ci if (InAmbientContext() && desc->isGenerator) { 18983af6ab5fSopenharmony_ci ThrowSyntaxError("Generators are not allowed in an ambient context."); 18993af6ab5fSopenharmony_ci } 19003af6ab5fSopenharmony_ci 19013af6ab5fSopenharmony_ci if (desc->methodKind != ir::MethodDefinitionKind::SET && 19023af6ab5fSopenharmony_ci ((desc->newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) == 0)) { 19033af6ab5fSopenharmony_ci desc->newStatus |= ParserStatus::NEED_RETURN_TYPE; 19043af6ab5fSopenharmony_ci } 19053af6ab5fSopenharmony_ci 19063af6ab5fSopenharmony_ci ir::ScriptFunction *func = ParseFunction(desc->newStatus); 19073af6ab5fSopenharmony_ci 19083af6ab5fSopenharmony_ci if (func->IsOverload() && !desc->decorators.empty()) { 19093af6ab5fSopenharmony_ci ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.", 19103af6ab5fSopenharmony_ci desc->decorators.front()->Start()); 19113af6ab5fSopenharmony_ci } 19123af6ab5fSopenharmony_ci 19133af6ab5fSopenharmony_ci auto *funcExpr = AllocNode<ir::FunctionExpression>(func); 19143af6ab5fSopenharmony_ci funcExpr->SetRange(func->Range()); 19153af6ab5fSopenharmony_ci 19163af6ab5fSopenharmony_ci if (desc->methodKind == ir::MethodDefinitionKind::SET) { 19173af6ab5fSopenharmony_ci ValidateClassSetter(desc, properties, propName, func); 19183af6ab5fSopenharmony_ci } else if (desc->methodKind == ir::MethodDefinitionKind::GET) { 19193af6ab5fSopenharmony_ci ValidateClassGetter(desc, properties, propName, func); 19203af6ab5fSopenharmony_ci } 19213af6ab5fSopenharmony_ci 19223af6ab5fSopenharmony_ci *propEnd = func->End(); 19233af6ab5fSopenharmony_ci func->AddFlag(ir::ScriptFunctionFlags::METHOD); 19243af6ab5fSopenharmony_ci auto *method = AllocNode<ir::MethodDefinition>(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), 19253af6ab5fSopenharmony_ci desc->isComputed); 19263af6ab5fSopenharmony_ci method->SetRange(funcExpr->Range()); 19273af6ab5fSopenharmony_ci 19283af6ab5fSopenharmony_ci return method; 19293af6ab5fSopenharmony_ci} 19303af6ab5fSopenharmony_ci 19313af6ab5fSopenharmony_civoid TSParser::ValidateClassSetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, 19323af6ab5fSopenharmony_ci ir::Expression *propName, ir::ScriptFunction *func) 19333af6ab5fSopenharmony_ci{ 19343af6ab5fSopenharmony_ci if (func->Params().size() != 1) { 19353af6ab5fSopenharmony_ci ThrowSyntaxError("Setter must have exactly one formal parameter"); 19363af6ab5fSopenharmony_ci } 19373af6ab5fSopenharmony_ci 19383af6ab5fSopenharmony_ci if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) { 19393af6ab5fSopenharmony_ci ir::ModifierFlags access = GetAccessability(desc->modifiers); 19403af6ab5fSopenharmony_ci CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::GET, access); 19413af6ab5fSopenharmony_ci } 19423af6ab5fSopenharmony_ci} 19433af6ab5fSopenharmony_ci 19443af6ab5fSopenharmony_civoid TSParser::ValidateClassGetter(ClassElementDescriptor *desc, const ArenaVector<ir::AstNode *> &properties, 19453af6ab5fSopenharmony_ci ir::Expression *propName, ir::ScriptFunction *func) 19463af6ab5fSopenharmony_ci{ 19473af6ab5fSopenharmony_ci if (!func->Params().empty()) { 19483af6ab5fSopenharmony_ci ThrowSyntaxError("Getter must not have formal parameters"); 19493af6ab5fSopenharmony_ci } 19503af6ab5fSopenharmony_ci 19513af6ab5fSopenharmony_ci if ((desc->modifiers & ir::ModifierFlags::STATIC) == 0) { 19523af6ab5fSopenharmony_ci ir::ModifierFlags access = GetAccessability(desc->modifiers); 19533af6ab5fSopenharmony_ci 19543af6ab5fSopenharmony_ci CheckAccessorPair(properties, propName, ir::MethodDefinitionKind::SET, access); 19553af6ab5fSopenharmony_ci } 19563af6ab5fSopenharmony_ci} 19573af6ab5fSopenharmony_ci 19583af6ab5fSopenharmony_civoid TSParser::ValidateIndexSignatureTypeAnnotation(ir::TypeNode *typeAnnotation) 19593af6ab5fSopenharmony_ci{ 19603af6ab5fSopenharmony_ci if (typeAnnotation == nullptr) { 19613af6ab5fSopenharmony_ci ThrowSyntaxError("An index signature must have a type annotation"); 19623af6ab5fSopenharmony_ci } 19633af6ab5fSopenharmony_ci} 19643af6ab5fSopenharmony_ci 19653af6ab5fSopenharmony_cibool TSParser::IsModifierKind(const lexer::Token &token) 19663af6ab5fSopenharmony_ci{ 19673af6ab5fSopenharmony_ci switch (token.KeywordType()) { 19683af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_PUBLIC: 19693af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_PRIVATE: 19703af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_PROTECTED: 19713af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_STATIC: 19723af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_ASYNC: 19733af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_ABSTRACT: 19743af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_DECLARE: 19753af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_READONLY: 19763af6ab5fSopenharmony_ci return true; 19773af6ab5fSopenharmony_ci default: 19783af6ab5fSopenharmony_ci break; 19793af6ab5fSopenharmony_ci } 19803af6ab5fSopenharmony_ci 19813af6ab5fSopenharmony_ci return false; 19823af6ab5fSopenharmony_ci} 19833af6ab5fSopenharmony_ci 19843af6ab5fSopenharmony_civoid TSParser::CheckIfTypeParameterNameIsReserved() 19853af6ab5fSopenharmony_ci{ 19863af6ab5fSopenharmony_ci if (Lexer()->GetToken().IsReservedTypeName()) { 19873af6ab5fSopenharmony_ci ThrowSyntaxError("Invalid type parameter name"); 19883af6ab5fSopenharmony_ci } 19893af6ab5fSopenharmony_ci} 19903af6ab5fSopenharmony_ci 19913af6ab5fSopenharmony_civoid TSParser::ThrowErrorIfStaticConstructor(ir::ModifierFlags flags) 19923af6ab5fSopenharmony_ci{ 19933af6ab5fSopenharmony_ci if ((flags & ir::ModifierFlags::STATIC) != 0) { 19943af6ab5fSopenharmony_ci ThrowSyntaxError("Static modifier can not appear on a constructor"); 19953af6ab5fSopenharmony_ci } 19963af6ab5fSopenharmony_ci} 19973af6ab5fSopenharmony_ci 19983af6ab5fSopenharmony_cistd::tuple<bool, bool, bool> TSParser::ParseComputedClassFieldOrIndexSignature(ir::Expression **propName) 19993af6ab5fSopenharmony_ci{ 20003af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat left square bracket 20013af6ab5fSopenharmony_ci 20023af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && 20033af6ab5fSopenharmony_ci Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) { 20043af6ab5fSopenharmony_ci auto id = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 20053af6ab5fSopenharmony_ci id->SetRange(Lexer()->GetToken().Loc()); 20063af6ab5fSopenharmony_ci 20073af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat param 20083af6ab5fSopenharmony_ci 20093af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { 20103af6ab5fSopenharmony_ci ThrowSyntaxError("':' expected"); 20113af6ab5fSopenharmony_ci } 20123af6ab5fSopenharmony_ci 20133af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 20143af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 20153af6ab5fSopenharmony_ci ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); 20163af6ab5fSopenharmony_ci 20173af6ab5fSopenharmony_ci if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { 20183af6ab5fSopenharmony_ci ThrowSyntaxError( 20193af6ab5fSopenharmony_ci "An index signature parameter type must be either " 20203af6ab5fSopenharmony_ci "'string' or 'number'"); 20213af6ab5fSopenharmony_ci } 20223af6ab5fSopenharmony_ci 20233af6ab5fSopenharmony_ci id->SetTsTypeAnnotation(typeAnnotation); 20243af6ab5fSopenharmony_ci 20253af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 20263af6ab5fSopenharmony_ci ThrowSyntaxError("']' expected"); 20273af6ab5fSopenharmony_ci } 20283af6ab5fSopenharmony_ci 20293af6ab5fSopenharmony_ci *propName = id; 20303af6ab5fSopenharmony_ci Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 20313af6ab5fSopenharmony_ci 20323af6ab5fSopenharmony_ci return {false, false, true}; 20333af6ab5fSopenharmony_ci } 20343af6ab5fSopenharmony_ci 20353af6ab5fSopenharmony_ci *propName = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); 20363af6ab5fSopenharmony_ci 20373af6ab5fSopenharmony_ci bool invalidComputedProperty = 20383af6ab5fSopenharmony_ci !(*propName)->IsNumberLiteral() && !(*propName)->IsStringLiteral() && 20393af6ab5fSopenharmony_ci !((*propName)->IsMemberExpression() && (*propName)->AsMemberExpression()->Object()->IsIdentifier() && 20403af6ab5fSopenharmony_ci (*propName)->AsMemberExpression()->Object()->AsIdentifier()->Name().Is("Symbol")); 20413af6ab5fSopenharmony_ci 20423af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { 20433af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected ']'"); 20443af6ab5fSopenharmony_ci } 20453af6ab5fSopenharmony_ci 20463af6ab5fSopenharmony_ci return {true, invalidComputedProperty, false}; 20473af6ab5fSopenharmony_ci} 20483af6ab5fSopenharmony_ci 20493af6ab5fSopenharmony_ciir::TypeNode *TSParser::ParseFunctionReturnType([[maybe_unused]] ParserStatus status) 20503af6ab5fSopenharmony_ci{ 20513af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 20523af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 20533af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = 20543af6ab5fSopenharmony_ci TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; 20553af6ab5fSopenharmony_ci return ParseTypeAnnotation(&options); 20563af6ab5fSopenharmony_ci } 20573af6ab5fSopenharmony_ci 20583af6ab5fSopenharmony_ci return nullptr; 20593af6ab5fSopenharmony_ci} 20603af6ab5fSopenharmony_ci 20613af6ab5fSopenharmony_civoid TSParser::ValidateFunctionOverloadParams(const ArenaVector<ir::Expression *> ¶ms) 20623af6ab5fSopenharmony_ci{ 20633af6ab5fSopenharmony_ci for (auto *it : params) { 20643af6ab5fSopenharmony_ci if (it->IsAssignmentPattern()) { 20653af6ab5fSopenharmony_ci ThrowSyntaxError( 20663af6ab5fSopenharmony_ci "A parameter initializer is only allowed in a function " 20673af6ab5fSopenharmony_ci "or constructor implementation.", 20683af6ab5fSopenharmony_ci it->Start()); 20693af6ab5fSopenharmony_ci } 20703af6ab5fSopenharmony_ci } 20713af6ab5fSopenharmony_ci} 20723af6ab5fSopenharmony_ci 20733af6ab5fSopenharmony_cistd::tuple<bool, ir::BlockStatement *, lexer::SourcePosition, bool> TSParser::ParseFunctionBody( 20743af6ab5fSopenharmony_ci const ArenaVector<ir::Expression *> ¶ms, ParserStatus newStatus, ParserStatus contextStatus) 20753af6ab5fSopenharmony_ci{ 20763af6ab5fSopenharmony_ci bool isDeclare = InAmbientContext(); 20773af6ab5fSopenharmony_ci bool isOverload = false; 20783af6ab5fSopenharmony_ci bool letDeclare = true; 20793af6ab5fSopenharmony_ci ir::BlockStatement *body = nullptr; 20803af6ab5fSopenharmony_ci lexer::SourcePosition endLoc = Lexer()->GetToken().End(); 20813af6ab5fSopenharmony_ci 20823af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { 20833af6ab5fSopenharmony_ci if ((newStatus & ParserStatus::FUNCTION_DECLARATION) != 0) { 20843af6ab5fSopenharmony_ci ValidateFunctionOverloadParams(params); 20853af6ab5fSopenharmony_ci } else if (!isDeclare && ((contextStatus & ParserStatus::IN_METHOD_DEFINITION) == 0)) { 20863af6ab5fSopenharmony_ci ThrowSyntaxError("Unexpected token, expected '{'"); 20873af6ab5fSopenharmony_ci } else { 20883af6ab5fSopenharmony_ci letDeclare = false; 20893af6ab5fSopenharmony_ci } 20903af6ab5fSopenharmony_ci 20913af6ab5fSopenharmony_ci isOverload = true; 20923af6ab5fSopenharmony_ci } else if (isDeclare) { 20933af6ab5fSopenharmony_ci ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); 20943af6ab5fSopenharmony_ci } else { 20953af6ab5fSopenharmony_ci body = ParseBlockStatement(); 20963af6ab5fSopenharmony_ci endLoc = body->End(); 20973af6ab5fSopenharmony_ci } 20983af6ab5fSopenharmony_ci 20993af6ab5fSopenharmony_ci return {letDeclare, body, endLoc, isOverload}; 21003af6ab5fSopenharmony_ci} 21013af6ab5fSopenharmony_ci 21023af6ab5fSopenharmony_ciir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector<ir::AstNode *> *specifiers) 21033af6ab5fSopenharmony_ci{ 21043af6ab5fSopenharmony_ci ir::Identifier *local = ParseNamedImport(Lexer()->GetToken()); 21053af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat local name 21063af6ab5fSopenharmony_ci 21073af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 21083af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat substitution 21093af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { 21103af6ab5fSopenharmony_ci ThrowSyntaxError("identifier expected"); 21113af6ab5fSopenharmony_ci } 21123af6ab5fSopenharmony_ci 21133af6ab5fSopenharmony_ci auto *importEqualsDecl = AllocNode<ir::TSImportEqualsDeclaration>(local, ParseModuleReference(), false); 21143af6ab5fSopenharmony_ci 21153af6ab5fSopenharmony_ci return importEqualsDecl; 21163af6ab5fSopenharmony_ci } 21173af6ab5fSopenharmony_ci 21183af6ab5fSopenharmony_ci auto *specifier = AllocNode<ir::ImportDefaultSpecifier>(local); 21193af6ab5fSopenharmony_ci specifier->SetRange(specifier->Local()->Range()); 21203af6ab5fSopenharmony_ci specifiers->push_back(specifier); 21213af6ab5fSopenharmony_ci 21223af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat specifier name 21233af6ab5fSopenharmony_ci 21243af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { 21253af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat comma 21263af6ab5fSopenharmony_ci } 21273af6ab5fSopenharmony_ci 21283af6ab5fSopenharmony_ci return nullptr; 21293af6ab5fSopenharmony_ci} 21303af6ab5fSopenharmony_ci 21313af6ab5fSopenharmony_civoid TSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param) 21323af6ab5fSopenharmony_ci{ 21333af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { 21343af6ab5fSopenharmony_ci Lexer()->NextToken(); // eat ':' 21353af6ab5fSopenharmony_ci 21363af6ab5fSopenharmony_ci TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; 21373af6ab5fSopenharmony_ci param->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); 21383af6ab5fSopenharmony_ci } 21393af6ab5fSopenharmony_ci 21403af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { 21413af6ab5fSopenharmony_ci ThrowSyntaxError("Catch clause variable cannot have an initializer"); 21423af6ab5fSopenharmony_ci } 21433af6ab5fSopenharmony_ci} 21443af6ab5fSopenharmony_ci 21453af6ab5fSopenharmony_civoid TSParser::ThrowPossibleOutOfBoundaryJumpError(bool allowBreak) 21463af6ab5fSopenharmony_ci{ 21473af6ab5fSopenharmony_ci if (((GetContext().Status() & ParserStatus::FUNCTION) != 0) && !allowBreak) { 21483af6ab5fSopenharmony_ci ThrowSyntaxError("Jump target cannot cross function boundary"); 21493af6ab5fSopenharmony_ci } 21503af6ab5fSopenharmony_ci} 21513af6ab5fSopenharmony_ci 21523af6ab5fSopenharmony_civoid TSParser::ThrowIllegalBreakError() 21533af6ab5fSopenharmony_ci{ 21543af6ab5fSopenharmony_ci ThrowSyntaxError("A 'break' statement can only be used within an enclosing iteration or switch statement"); 21553af6ab5fSopenharmony_ci} 21563af6ab5fSopenharmony_ci 21573af6ab5fSopenharmony_civoid TSParser::ThrowIllegalContinueError() 21583af6ab5fSopenharmony_ci{ 21593af6ab5fSopenharmony_ci ThrowSyntaxError("A 'continue' statement can only be used within an enclosing iteration statement"); 21603af6ab5fSopenharmony_ci} 21613af6ab5fSopenharmony_ci 21623af6ab5fSopenharmony_civoid TSParser::ThrowMultipleDefaultError() 21633af6ab5fSopenharmony_ci{ 21643af6ab5fSopenharmony_ci ThrowSyntaxError("A 'default' clause cannot appear more than once in a 'switch' statement"); 21653af6ab5fSopenharmony_ci} 21663af6ab5fSopenharmony_ci 21673af6ab5fSopenharmony_civoid TSParser::ThrowIllegalNewLineErrorAfterThrow() 21683af6ab5fSopenharmony_ci{ 21693af6ab5fSopenharmony_ci ThrowSyntaxError("Line break not permitted here"); 21703af6ab5fSopenharmony_ci} 21713af6ab5fSopenharmony_ci 21723af6ab5fSopenharmony_civoid TSParser::ThrowIfBodyEmptyError(ir::Statement *consequent) 21733af6ab5fSopenharmony_ci{ 21743af6ab5fSopenharmony_ci if (consequent->IsEmptyStatement()) { 21753af6ab5fSopenharmony_ci ThrowSyntaxError("The body of an if statement cannot be the empty statement"); 21763af6ab5fSopenharmony_ci } 21773af6ab5fSopenharmony_ci} 21783af6ab5fSopenharmony_ci 21793af6ab5fSopenharmony_ci} // namespace ark::es2panda::parser 2180