13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 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 "ETSparser.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "lexer/lexer.h" 193af6ab5fSopenharmony_ci#include "ir/typeNode.h" 203af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 213af6ab5fSopenharmony_ci#include "ir/expressions/blockExpression.h" 223af6ab5fSopenharmony_ci#include "ir/expressions/sequenceExpression.h" 233af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h" 243af6ab5fSopenharmony_ci#include "ir/statements/expressionStatement.h" 253af6ab5fSopenharmony_ci#include "ir/base/methodDefinition.h" 263af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceBody.h" 273af6ab5fSopenharmony_ci#include "parser/parserStatusContext.h" 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_cinamespace ark::es2panda::parser { 303af6ab5fSopenharmony_ci//================================================================================================// 313af6ab5fSopenharmony_ci// Methods to create AST node(s) from the specified string (part of valid ETS-code!) 323af6ab5fSopenharmony_ci//================================================================================================// 333af6ab5fSopenharmony_ci 343af6ab5fSopenharmony_ci// NOLINTBEGIN(modernize-avoid-c-arrays) 353af6ab5fSopenharmony_ciinline constexpr char const FORMAT_SIGNATURE = '@'; 363af6ab5fSopenharmony_ciinline constexpr char const TYPE_FORMAT_NODE = 'T'; 373af6ab5fSopenharmony_ciinline constexpr char const GENERAL_FORMAT_NODE = 'N'; 383af6ab5fSopenharmony_ciinline constexpr char const IDENTIFIER_FORMAT_NODE = 'I'; 393af6ab5fSopenharmony_ci 403af6ab5fSopenharmony_cistatic constexpr char const INVALID_NUMBER_NODE[] = "Invalid node number in format expression."; 413af6ab5fSopenharmony_cistatic constexpr char const INVALID_FORMAT_NODE[] = "Invalid node type in format expression."; 423af6ab5fSopenharmony_cistatic constexpr char const INSERT_NODE_ABSENT[] = "There is no any node to insert at the placeholder position."; 433af6ab5fSopenharmony_cistatic constexpr char const INVALID_INSERT_NODE[] = 443af6ab5fSopenharmony_ci "Inserting node type differs from that required by format specification."; 453af6ab5fSopenharmony_cistatic constexpr char const INVALID_CLASS_FIELD[] = "Cannot parse class field definition property."; 463af6ab5fSopenharmony_cistatic constexpr char const INVALID_CLASS_METHOD[] = "Cannot parse class method definition property."; 473af6ab5fSopenharmony_ci// NOLINTEND(modernize-avoid-c-arrays) 483af6ab5fSopenharmony_ci 493af6ab5fSopenharmony_ciParserImpl::NodeFormatType ETSParser::GetFormatPlaceholderType() const 503af6ab5fSopenharmony_ci{ 513af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_FORMAT); 523af6ab5fSopenharmony_ci Lexer()->NextToken(); 533af6ab5fSopenharmony_ci 543af6ab5fSopenharmony_ci bool isArray = false; 553af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { 563af6ab5fSopenharmony_ci isArray = true; 573af6ab5fSopenharmony_ci Lexer()->NextToken(); 583af6ab5fSopenharmony_ci } 593af6ab5fSopenharmony_ci 603af6ab5fSopenharmony_ci ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); 613af6ab5fSopenharmony_ci char const *const identData = Lexer()->GetToken().Ident().Bytes(); 623af6ab5fSopenharmony_ci 633af6ab5fSopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic, cert-err34-c) 643af6ab5fSopenharmony_ci auto identNumber = std::atoi(identData + 1U); 653af6ab5fSopenharmony_ci if (identNumber <= 0) { 663af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_NUMBER_NODE, Lexer()->GetToken().Start()); 673af6ab5fSopenharmony_ci } 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_ci return {isArray, *identData, 703af6ab5fSopenharmony_ci static_cast<decltype(std::get<2>(std::declval<ParserImpl::NodeFormatType>()))>(identNumber - 1)}; 713af6ab5fSopenharmony_ci} 723af6ab5fSopenharmony_ci 733af6ab5fSopenharmony_ciir::Expression *ETSParser::ParseExpressionFormatPlaceholder() 743af6ab5fSopenharmony_ci{ 753af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 763af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 773af6ab5fSopenharmony_ci } 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 803af6ab5fSopenharmony_ci if (std::get<0>(nodeFormat)) { 813af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 823af6ab5fSopenharmony_ci } 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci if (auto const placeholderType = std::get<1>(nodeFormat); placeholderType == TYPE_FORMAT_NODE) { 853af6ab5fSopenharmony_ci return ParseTypeFormatPlaceholder(std::make_optional(std::move(nodeFormat))); 863af6ab5fSopenharmony_ci } else if (placeholderType == IDENTIFIER_FORMAT_NODE) { // NOLINT(readability-else-after-return) 873af6ab5fSopenharmony_ci return ParseIdentifierFormatPlaceholder(std::make_optional(std::move(nodeFormat))); 883af6ab5fSopenharmony_ci } else if (placeholderType != EXPRESSION_FORMAT_NODE) { // NOLINT(readability-else-after-return) 893af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 903af6ab5fSopenharmony_ci } 913af6ab5fSopenharmony_ci 923af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 933af6ab5fSopenharmony_ci auto *const insertingNode = 943af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 953af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsExpression()) { 963af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 973af6ab5fSopenharmony_ci } 983af6ab5fSopenharmony_ci 993af6ab5fSopenharmony_ci auto *const insertExpression = insertingNode->AsExpression(); 1003af6ab5fSopenharmony_ci Lexer()->NextToken(); 1013af6ab5fSopenharmony_ci return insertExpression; 1023af6ab5fSopenharmony_ci} 1033af6ab5fSopenharmony_ci 1043af6ab5fSopenharmony_ciir::TypeNode *ETSParser::ParseTypeFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat) 1053af6ab5fSopenharmony_ci{ 1063af6ab5fSopenharmony_ci if (!nodeFormat.has_value()) { 1073af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 1083af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 1093af6ab5fSopenharmony_ci } 1103af6ab5fSopenharmony_ci 1113af6ab5fSopenharmony_ci nodeFormat = GetFormatPlaceholderType(); 1123af6ab5fSopenharmony_ci if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != TYPE_FORMAT_NODE) { 1133af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 1143af6ab5fSopenharmony_ci } 1153af6ab5fSopenharmony_ci } 1163af6ab5fSopenharmony_ci 1173af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(*nodeFormat); 1183af6ab5fSopenharmony_ci auto *const insertingNode = 1193af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 1203af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsTypeNode()) { 1213af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 1223af6ab5fSopenharmony_ci } 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci auto *const insertType = insertingNode->AsExpression()->AsTypeNode(); 1253af6ab5fSopenharmony_ci Lexer()->NextToken(); 1263af6ab5fSopenharmony_ci return insertType; 1273af6ab5fSopenharmony_ci} 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ciir::Identifier *ETSParser::ParseIdentifierFormatPlaceholder(std::optional<ParserImpl::NodeFormatType> nodeFormat) const 1303af6ab5fSopenharmony_ci{ 1313af6ab5fSopenharmony_ci if (!nodeFormat.has_value()) { 1323af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 1333af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 1343af6ab5fSopenharmony_ci } 1353af6ab5fSopenharmony_ci 1363af6ab5fSopenharmony_ci nodeFormat = GetFormatPlaceholderType(); 1373af6ab5fSopenharmony_ci if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != IDENTIFIER_FORMAT_NODE) { 1383af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 1393af6ab5fSopenharmony_ci } 1403af6ab5fSopenharmony_ci } 1413af6ab5fSopenharmony_ci 1423af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(*nodeFormat); 1433af6ab5fSopenharmony_ci auto *const insertingNode = 1443af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 1453af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsExpression() || !insertingNode->AsExpression()->IsIdentifier()) { 1463af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 1473af6ab5fSopenharmony_ci } 1483af6ab5fSopenharmony_ci 1493af6ab5fSopenharmony_ci auto *const insertIdentifier = insertingNode->AsExpression()->AsIdentifier(); 1503af6ab5fSopenharmony_ci Lexer()->NextToken(); 1513af6ab5fSopenharmony_ci return insertIdentifier; 1523af6ab5fSopenharmony_ci} 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ciir::Statement *ETSParser::ParseStatementFormatPlaceholder() const 1553af6ab5fSopenharmony_ci{ 1563af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 1573af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 1583af6ab5fSopenharmony_ci } 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 1613af6ab5fSopenharmony_ci if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) { 1623af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 1633af6ab5fSopenharmony_ci } 1643af6ab5fSopenharmony_ci 1653af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 1663af6ab5fSopenharmony_ci auto *const insertingNode = 1673af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 1683af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsStatement()) { 1693af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 1703af6ab5fSopenharmony_ci } 1713af6ab5fSopenharmony_ci 1723af6ab5fSopenharmony_ci Lexer()->NextToken(); 1733af6ab5fSopenharmony_ci return insertingNode->AsStatement(); 1743af6ab5fSopenharmony_ci} 1753af6ab5fSopenharmony_ci 1763af6ab5fSopenharmony_ciir::AstNode *ETSParser::ParseTypeParametersFormatPlaceholder() const 1773af6ab5fSopenharmony_ci{ 1783af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 1793af6ab5fSopenharmony_ci if (std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) { 1803af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 1813af6ab5fSopenharmony_ci } 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 1843af6ab5fSopenharmony_ci if (placeholderNumber >= insertingNodes_.size()) { 1853af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 1863af6ab5fSopenharmony_ci } 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci auto *const insertingNode = insertingNodes_[placeholderNumber]; 1893af6ab5fSopenharmony_ci if (insertingNode != nullptr && !insertingNode->IsTSTypeParameterDeclaration() && 1903af6ab5fSopenharmony_ci !insertingNode->IsTSTypeParameterInstantiation()) { 1913af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 1923af6ab5fSopenharmony_ci } 1933af6ab5fSopenharmony_ci 1943af6ab5fSopenharmony_ci Lexer()->NextToken(); 1953af6ab5fSopenharmony_ci return insertingNode; 1963af6ab5fSopenharmony_ci} 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ciArenaVector<ir::AstNode *> &ETSParser::ParseAstNodesArrayFormatPlaceholder() const 1993af6ab5fSopenharmony_ci{ 2003af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 2013af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 2023af6ab5fSopenharmony_ci } 2033af6ab5fSopenharmony_ci 2043af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 2053af6ab5fSopenharmony_ci if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != GENERAL_FORMAT_NODE) { 2063af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 2073af6ab5fSopenharmony_ci } 2083af6ab5fSopenharmony_ci 2093af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 2103af6ab5fSopenharmony_ci auto *const insertingNode = 2113af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 2123af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsTSInterfaceBody()) { 2133af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 2143af6ab5fSopenharmony_ci } 2153af6ab5fSopenharmony_ci 2163af6ab5fSopenharmony_ci Lexer()->NextToken(); 2173af6ab5fSopenharmony_ci return insertingNode->AsTSInterfaceBody()->Body(); 2183af6ab5fSopenharmony_ci} 2193af6ab5fSopenharmony_ci 2203af6ab5fSopenharmony_ciArenaVector<ir::Statement *> &ETSParser::ParseStatementsArrayFormatPlaceholder() const 2213af6ab5fSopenharmony_ci{ 2223af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 2233af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 2243af6ab5fSopenharmony_ci } 2253af6ab5fSopenharmony_ci 2263af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 2273af6ab5fSopenharmony_ci if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != STATEMENT_FORMAT_NODE) { 2283af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 2293af6ab5fSopenharmony_ci } 2303af6ab5fSopenharmony_ci 2313af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 2323af6ab5fSopenharmony_ci auto *const insertingNode = 2333af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 2343af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsBlockExpression()) { 2353af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 2363af6ab5fSopenharmony_ci } 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ci Lexer()->NextToken(); 2393af6ab5fSopenharmony_ci return insertingNode->AsBlockExpression()->Statements(); 2403af6ab5fSopenharmony_ci} 2413af6ab5fSopenharmony_ci 2423af6ab5fSopenharmony_ciArenaVector<ir::Expression *> &ETSParser::ParseExpressionsArrayFormatPlaceholder() const 2433af6ab5fSopenharmony_ci{ 2443af6ab5fSopenharmony_ci if (insertingNodes_.empty()) { 2453af6ab5fSopenharmony_ci ThrowSyntaxError(INSERT_NODE_ABSENT, Lexer()->GetToken().Start()); 2463af6ab5fSopenharmony_ci } 2473af6ab5fSopenharmony_ci 2483af6ab5fSopenharmony_ci ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); 2493af6ab5fSopenharmony_ci if (!std::get<0>(nodeFormat) || std::get<1>(nodeFormat) != EXPRESSION_FORMAT_NODE) { 2503af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_FORMAT_NODE, Lexer()->GetToken().Start()); 2513af6ab5fSopenharmony_ci } 2523af6ab5fSopenharmony_ci 2533af6ab5fSopenharmony_ci auto const placeholderNumber = std::get<2>(nodeFormat); 2543af6ab5fSopenharmony_ci auto *const insertingNode = 2553af6ab5fSopenharmony_ci placeholderNumber < insertingNodes_.size() ? insertingNodes_[placeholderNumber] : nullptr; 2563af6ab5fSopenharmony_ci if (insertingNode == nullptr || !insertingNode->IsSequenceExpression()) { 2573af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_INSERT_NODE, Lexer()->GetToken().Start()); 2583af6ab5fSopenharmony_ci } 2593af6ab5fSopenharmony_ci 2603af6ab5fSopenharmony_ci Lexer()->NextToken(); 2613af6ab5fSopenharmony_ci return insertingNode->AsSequenceExpression()->Sequence(); 2623af6ab5fSopenharmony_ci} 2633af6ab5fSopenharmony_ci 2643af6ab5fSopenharmony_ciir::Statement *ETSParser::CreateStatement(std::string_view const sourceCode) 2653af6ab5fSopenharmony_ci{ 2663af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 2673af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 2683af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 2693af6ab5fSopenharmony_ci 2703af6ab5fSopenharmony_ci lexer::SourcePosition const startLoc = lexer->GetToken().Start(); 2713af6ab5fSopenharmony_ci lexer->NextToken(); 2723af6ab5fSopenharmony_ci 2733af6ab5fSopenharmony_ci auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); 2743af6ab5fSopenharmony_ci auto const statementNumber = statements.size(); 2753af6ab5fSopenharmony_ci if (statementNumber == 0U) { 2763af6ab5fSopenharmony_ci return nullptr; 2773af6ab5fSopenharmony_ci } 2783af6ab5fSopenharmony_ci 2793af6ab5fSopenharmony_ci if (statementNumber == 1U) { 2803af6ab5fSopenharmony_ci return statements[0U]; 2813af6ab5fSopenharmony_ci } 2823af6ab5fSopenharmony_ci 2833af6ab5fSopenharmony_ci auto *const blockStmt = AllocNode<ir::BlockStatement>(Allocator(), std::move(statements)); 2843af6ab5fSopenharmony_ci blockStmt->SetRange({startLoc, lexer->GetToken().End()}); 2853af6ab5fSopenharmony_ci 2863af6ab5fSopenharmony_ci for (auto *statement : blockStmt->Statements()) { 2873af6ab5fSopenharmony_ci statement->SetParent(blockStmt); 2883af6ab5fSopenharmony_ci } 2893af6ab5fSopenharmony_ci 2903af6ab5fSopenharmony_ci return blockStmt; 2913af6ab5fSopenharmony_ci} 2923af6ab5fSopenharmony_ci 2933af6ab5fSopenharmony_ciir::Statement *ETSParser::CreateFormattedStatement(std::string_view const sourceCode, 2943af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 2953af6ab5fSopenharmony_ci{ 2963af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 2973af6ab5fSopenharmony_ci auto const statement = CreateStatement(sourceCode); 2983af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 2993af6ab5fSopenharmony_ci return statement; 3003af6ab5fSopenharmony_ci} 3013af6ab5fSopenharmony_ci 3023af6ab5fSopenharmony_ciArenaVector<ir::Statement *> ETSParser::CreateStatements(std::string_view const sourceCode) 3033af6ab5fSopenharmony_ci{ 3043af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 3053af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 3063af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 3073af6ab5fSopenharmony_ci 3083af6ab5fSopenharmony_ci lexer->NextToken(); 3093af6ab5fSopenharmony_ci return ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); 3103af6ab5fSopenharmony_ci} 3113af6ab5fSopenharmony_ci 3123af6ab5fSopenharmony_ciArenaVector<ir::Statement *> ETSParser::CreateFormattedStatements(std::string_view const sourceCode, 3133af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 3143af6ab5fSopenharmony_ci{ 3153af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3163af6ab5fSopenharmony_ci auto statements = CreateStatements(sourceCode); 3173af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3183af6ab5fSopenharmony_ci return statements; 3193af6ab5fSopenharmony_ci} 3203af6ab5fSopenharmony_ci 3213af6ab5fSopenharmony_ci// NOTE: this method returns only a single (the first) class filed definition. 3223af6ab5fSopenharmony_ci// It seems that it is possible to have several of them be parsed at a time but nobody knows how... 3233af6ab5fSopenharmony_ciir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sourceCode, 3243af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 3253af6ab5fSopenharmony_ci{ 3263af6ab5fSopenharmony_ci static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()}; 3273af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3283af6ab5fSopenharmony_ci 3293af6ab5fSopenharmony_ci auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); 3303af6ab5fSopenharmony_ci if (!property->IsTSInterfaceBody() || property->AsTSInterfaceBody()->Body().empty()) { 3313af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_CLASS_FIELD); 3323af6ab5fSopenharmony_ci } 3333af6ab5fSopenharmony_ci 3343af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3353af6ab5fSopenharmony_ci return property->AsTSInterfaceBody()->Body().front(); 3363af6ab5fSopenharmony_ci} 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ciir::AstNode *ETSParser::CreateFormattedClassMethodDefinition(std::string_view sourceCode, 3393af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 3403af6ab5fSopenharmony_ci{ 3413af6ab5fSopenharmony_ci static ArenaVector<ir::AstNode *> const DUMMY_ARRAY {Allocator()->Adapter()}; 3423af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3433af6ab5fSopenharmony_ci 3443af6ab5fSopenharmony_ci auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); 3453af6ab5fSopenharmony_ci if (!property->IsMethodDefinition()) { 3463af6ab5fSopenharmony_ci ThrowSyntaxError(INVALID_CLASS_METHOD); 3473af6ab5fSopenharmony_ci } 3483af6ab5fSopenharmony_ci 3493af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3503af6ab5fSopenharmony_ci return property; 3513af6ab5fSopenharmony_ci} 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ciir::AstNode *ETSParser::CreateFormattedClassElement(std::string_view sourceCode, 3543af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes, 3553af6ab5fSopenharmony_ci const ArenaVector<ir::AstNode *> &properties, 3563af6ab5fSopenharmony_ci ir::ClassDefinitionModifiers modifiers) 3573af6ab5fSopenharmony_ci{ 3583af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3593af6ab5fSopenharmony_ci auto *const classElement = CreateClassElement(sourceCode, properties, modifiers); 3603af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3613af6ab5fSopenharmony_ci return classElement; 3623af6ab5fSopenharmony_ci} 3633af6ab5fSopenharmony_ci 3643af6ab5fSopenharmony_ci// NOTE: the method has limited functionality - it returns 'ir::TSInterfaceBody' placeholder for the field 3653af6ab5fSopenharmony_ci// declaration(s) (properties themselves are in ->Body() member) and does not perform any check of the node returned. 3663af6ab5fSopenharmony_ci// Also the node isn't placed in the providing properties container. 3673af6ab5fSopenharmony_ciir::AstNode *ETSParser::CreateClassElement(std::string_view sourceCode, const ArenaVector<ir::AstNode *> &properties, 3683af6ab5fSopenharmony_ci ir::ClassDefinitionModifiers modifiers) 3693af6ab5fSopenharmony_ci{ 3703af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 3713af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 3723af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 3733af6ab5fSopenharmony_ci 3743af6ab5fSopenharmony_ci auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext()); 3753af6ab5fSopenharmony_ci SavedClassPrivateContext classContext(this); 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci lexer->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); 3783af6ab5fSopenharmony_ci 3793af6ab5fSopenharmony_ci return ParseClassElement(properties, modifiers, ir::ModifierFlags::NONE); 3803af6ab5fSopenharmony_ci} 3813af6ab5fSopenharmony_ci 3823af6ab5fSopenharmony_ciir::ClassDeclaration *ETSParser::CreateFormattedClassDeclaration(std::string_view sourceCode, 3833af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes, 3843af6ab5fSopenharmony_ci bool const allowStatic) 3853af6ab5fSopenharmony_ci{ 3863af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3873af6ab5fSopenharmony_ci auto *const classDeclaration = CreateClassDeclaration(sourceCode, allowStatic); 3883af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 3893af6ab5fSopenharmony_ci return classDeclaration; 3903af6ab5fSopenharmony_ci} 3913af6ab5fSopenharmony_ci 3923af6ab5fSopenharmony_ciir::ClassDeclaration *ETSParser::CreateClassDeclaration(std::string_view sourceCode, bool allowStatic) 3933af6ab5fSopenharmony_ci{ 3943af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 3953af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 3963af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_ci auto savedCtx = SavedStatusContext<ParserStatus::IN_CLASS_BODY>(&GetContext()); 3993af6ab5fSopenharmony_ci 4003af6ab5fSopenharmony_ci auto modifiers = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL; 4013af6ab5fSopenharmony_ci ir::ModifierFlags flags = ir::ModifierFlags::NONE; 4023af6ab5fSopenharmony_ci 4033af6ab5fSopenharmony_ci lexer->NextToken(); 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci switch (auto tokenType = Lexer()->GetToken().Type(); tokenType) { 4063af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_STATIC: { 4073af6ab5fSopenharmony_ci if (!allowStatic) { 4083af6ab5fSopenharmony_ci ThrowUnexpectedToken(Lexer()->GetToken().Type()); 4093af6ab5fSopenharmony_ci } 4103af6ab5fSopenharmony_ci [[fallthrough]]; 4113af6ab5fSopenharmony_ci } 4123af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_ABSTRACT: 4133af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_FINAL: { 4143af6ab5fSopenharmony_ci flags = ParseClassModifiers(); 4153af6ab5fSopenharmony_ci if (allowStatic && (flags & ir::ModifierFlags::STATIC) == 0U) { 4163af6ab5fSopenharmony_ci modifiers |= ir::ClassDefinitionModifiers::INNER; 4173af6ab5fSopenharmony_ci } 4183af6ab5fSopenharmony_ci 4193af6ab5fSopenharmony_ci if (auto const tokType = Lexer()->GetToken().Type(); tokType != lexer::TokenType::KEYW_CLASS) { 4203af6ab5fSopenharmony_ci ThrowUnexpectedToken(tokType); 4213af6ab5fSopenharmony_ci } 4223af6ab5fSopenharmony_ci [[fallthrough]]; 4233af6ab5fSopenharmony_ci } 4243af6ab5fSopenharmony_ci case lexer::TokenType::KEYW_CLASS: { 4253af6ab5fSopenharmony_ci return ParseClassDeclaration(modifiers); 4263af6ab5fSopenharmony_ci } 4273af6ab5fSopenharmony_ci default: { 4283af6ab5fSopenharmony_ci ThrowUnexpectedToken(tokenType); 4293af6ab5fSopenharmony_ci } 4303af6ab5fSopenharmony_ci } 4313af6ab5fSopenharmony_ci} 4323af6ab5fSopenharmony_ci 4333af6ab5fSopenharmony_ciir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags modifiers, 4343af6ab5fSopenharmony_ci std::string_view const sourceCode) 4353af6ab5fSopenharmony_ci{ 4363af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 4373af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 4383af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 4393af6ab5fSopenharmony_ci 4403af6ab5fSopenharmony_ci auto const startLoc = Lexer()->GetToken().Start(); 4413af6ab5fSopenharmony_ci Lexer()->NextToken(); 4423af6ab5fSopenharmony_ci 4433af6ab5fSopenharmony_ci if (IsClassMethodModifier(Lexer()->GetToken().Type())) { 4443af6ab5fSopenharmony_ci modifiers |= ParseClassMethodModifiers(false); 4453af6ab5fSopenharmony_ci } 4463af6ab5fSopenharmony_ci 4473af6ab5fSopenharmony_ci if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_CONSTRUCTOR) { 4483af6ab5fSopenharmony_ci ThrowSyntaxError({"Unexpected token. 'Constructor' keyword is expected."}); 4493af6ab5fSopenharmony_ci } 4503af6ab5fSopenharmony_ci 4513af6ab5fSopenharmony_ci if ((modifiers & ir::ModifierFlags::ASYNC) != 0) { 4523af6ab5fSopenharmony_ci ThrowSyntaxError({"Constructor should not be async."}); 4533af6ab5fSopenharmony_ci } 4543af6ab5fSopenharmony_ci 4553af6ab5fSopenharmony_ci auto *memberName = AllocNode<ir::Identifier>(Lexer()->GetToken().Ident(), Allocator()); 4563af6ab5fSopenharmony_ci modifiers |= ir::ModifierFlags::CONSTRUCTOR; 4573af6ab5fSopenharmony_ci Lexer()->NextToken(); 4583af6ab5fSopenharmony_ci 4593af6ab5fSopenharmony_ci auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers); 4603af6ab5fSopenharmony_ci methodDefinition->SetStart(startLoc); 4613af6ab5fSopenharmony_ci 4623af6ab5fSopenharmony_ci return methodDefinition; 4633af6ab5fSopenharmony_ci} 4643af6ab5fSopenharmony_ci 4653af6ab5fSopenharmony_ciir::Expression *ETSParser::CreateExpression(std::string_view const sourceCode, ExpressionParseFlags const flags) 4663af6ab5fSopenharmony_ci{ 4673af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 4683af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 4693af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 4703af6ab5fSopenharmony_ci 4713af6ab5fSopenharmony_ci lexer::SourcePosition const startLoc = lexer->GetToken().Start(); 4723af6ab5fSopenharmony_ci lexer->NextToken(); 4733af6ab5fSopenharmony_ci 4743af6ab5fSopenharmony_ci ir::Expression *returnExpression = ParseExpression(flags); 4753af6ab5fSopenharmony_ci returnExpression->SetRange({startLoc, lexer->GetToken().End()}); 4763af6ab5fSopenharmony_ci 4773af6ab5fSopenharmony_ci return returnExpression; 4783af6ab5fSopenharmony_ci} 4793af6ab5fSopenharmony_ci 4803af6ab5fSopenharmony_ciir::Expression *ETSParser::CreateFormattedExpression(std::string_view const sourceCode, 4813af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 4823af6ab5fSopenharmony_ci{ 4833af6ab5fSopenharmony_ci ir::Expression *returnExpression; 4843af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 4853af6ab5fSopenharmony_ci 4863af6ab5fSopenharmony_ci if (auto statements = CreateStatements(sourceCode); 4873af6ab5fSopenharmony_ci statements.size() == 1U && statements.back()->IsExpressionStatement()) { 4883af6ab5fSopenharmony_ci returnExpression = statements.back()->AsExpressionStatement()->GetExpression(); 4893af6ab5fSopenharmony_ci } else { 4903af6ab5fSopenharmony_ci returnExpression = AllocNode<ir::BlockExpression>(std::move(statements)); 4913af6ab5fSopenharmony_ci } 4923af6ab5fSopenharmony_ci 4933af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 4943af6ab5fSopenharmony_ci return returnExpression; 4953af6ab5fSopenharmony_ci} 4963af6ab5fSopenharmony_ci 4973af6ab5fSopenharmony_ciir::Statement *ETSParser::CreateTopLevelStatement(std::string_view const sourceCode) 4983af6ab5fSopenharmony_ci{ 4993af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 5003af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 5013af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 5023af6ab5fSopenharmony_ci 5033af6ab5fSopenharmony_ci lexer->NextToken(); 5043af6ab5fSopenharmony_ci 5053af6ab5fSopenharmony_ci return ParseTopLevelStatement(); 5063af6ab5fSopenharmony_ci} 5073af6ab5fSopenharmony_ci 5083af6ab5fSopenharmony_ciir::Statement *ETSParser::CreateFormattedTopLevelStatement(std::string_view const sourceCode, 5093af6ab5fSopenharmony_ci std::vector<ir::AstNode *> &insertingNodes) 5103af6ab5fSopenharmony_ci{ 5113af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 5123af6ab5fSopenharmony_ci auto const statement = CreateTopLevelStatement(sourceCode); 5133af6ab5fSopenharmony_ci insertingNodes_.swap(insertingNodes); 5143af6ab5fSopenharmony_ci return statement; 5153af6ab5fSopenharmony_ci} 5163af6ab5fSopenharmony_ci 5173af6ab5fSopenharmony_ciir::TypeNode *ETSParser::CreateTypeAnnotation(TypeAnnotationParsingOptions *options, std::string_view const sourceCode) 5183af6ab5fSopenharmony_ci{ 5193af6ab5fSopenharmony_ci util::UString source {sourceCode, Allocator()}; 5203af6ab5fSopenharmony_ci auto const isp = InnerSourceParser(this); 5213af6ab5fSopenharmony_ci auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); 5223af6ab5fSopenharmony_ci 5233af6ab5fSopenharmony_ci lexer->NextToken(); 5243af6ab5fSopenharmony_ci return ParseTypeAnnotation(options); 5253af6ab5fSopenharmony_ci} 5263af6ab5fSopenharmony_ci} // namespace ark::es2panda::parser 527