From c0afff54a478cff2f7319779e1d03029d0bc3ac4 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Tue, 9 Sep 2025 15:43:15 +0800 Subject: [PATCH] =?UTF-8?q?etsImport=20And=20qualifited=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yp9522 --- ets2panda/lsp/include/node_matchers.h | 3 + ets2panda/lsp/src/node_matchers.cpp | 42 ++++++++- ets2panda/test/unit/lsp/CMakeLists.txt | 4 + .../test/unit/lsp/get_node_import_test.cpp | 16 +++- .../unit/lsp/get_node_ts_qualified_test.cpp | 90 +++++++++++++++++++ 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100755 ets2panda/test/unit/lsp/get_node_ts_qualified_test.cpp diff --git a/ets2panda/lsp/include/node_matchers.h b/ets2panda/lsp/include/node_matchers.h index 6fdadbebb2..ca378fba8b 100644 --- a/ets2panda/lsp/include/node_matchers.h +++ b/ets2panda/lsp/include/node_matchers.h @@ -70,6 +70,9 @@ bool MatchSwitchStatement(ir::AstNode *childNode, const NodeInfo *info); bool MatchEtsParameterExpression(ir::AstNode *childNode, const NodeInfo *info); bool MatchTsNonNullExpression(ir::AstNode *childNode, const NodeInfo *info); bool MatchFunctionDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchETSImportDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSQualifiedName(ir::AstNode *childNode, const NodeInfo *info); + void HandleIdentifier(ir::AstNode *node, std::vector &result); void HandleMemberExpression(ir::AstNode *node, std::vector &result); void HandleSpeadeElement(ir::AstNode *node, std::vector &result); diff --git a/ets2panda/lsp/src/node_matchers.cpp b/ets2panda/lsp/src/node_matchers.cpp index 33ce4f1c86..47b0e7d531 100644 --- a/ets2panda/lsp/src/node_matchers.cpp +++ b/ets2panda/lsp/src/node_matchers.cpp @@ -517,6 +517,22 @@ bool MatchFunctionDeclaration(ir::AstNode *childNode, const NodeInfo *info) return std::string(childNode->AsFunctionDeclaration()->Function()->Id()->Name()) == info->name; } +bool MatchETSImportDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSImportDeclaration()) { + return false; + } + return std::string(childNode->AsETSImportDeclaration()->Source()->ToString()) == info->name; +} + +bool MatchTSQualifiedName(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsTSQualifiedName()) { + return false; + } + return std::string(childNode->AsTSQualifiedName()->Right()->ToString()) == info->name; +} + ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info) { if (node == nullptr) { @@ -678,6 +694,11 @@ static std::unordered_map GetFunctionAndVariable [](ir::AstNode *node, const NodeInfo *) { return node->IsScriptFunction() ? node->AsScriptFunction()->Id() : node; }}, + {ir::AstNodeType::FUNCTION_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsFunctionDeclaration() + ? node->AsFunctionDeclaration()->Function()->Id() : node; + }}, {ir::AstNodeType::VARIABLE_DECLARATOR, [](ir::AstNode *node, const NodeInfo *) { return node->IsVariableDeclarator() ? node->AsVariableDeclarator()->Id()->AsIdentifier() : node; @@ -728,6 +749,21 @@ static std::unordered_map GetAnnotationAndImport // clang-format on } +static std::unordered_map GetEtsImportAndTsQualifiedExtractors() +{ + // clang-format off + return {{ir::AstNodeType::ETS_IMPORT_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsETSImportDeclaration() ? node->AsETSImportDeclaration()->Source() : node; + }}, + {ir::AstNodeType::TS_QUALIFIED_NAME, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSQualifiedName() ? node->AsTSQualifiedName()->Right() : node; + }} + }; + // clang-format on +} + const std::unordered_map &GetNodeExtractors() { static std::unordered_map nodeExtractors; @@ -741,6 +777,7 @@ const std::unordered_map &GetNodeExtractors() auto typeRefExtractors = GetTypeReferenceExtractors(); auto funcVarExtractors = GetFunctionAndVariableExtractors(); auto annotationImportExtractors = GetAnnotationAndImportExtractors(); + auto importandqualifiedExtractors = GetEtsImportAndTsQualifiedExtractors(); nodeExtractors.insert(classExtractors.begin(), classExtractors.end()); nodeExtractors.insert(enumExtractors.begin(), enumExtractors.end()); @@ -749,6 +786,7 @@ const std::unordered_map &GetNodeExtractors() nodeExtractors.insert(typeRefExtractors.begin(), typeRefExtractors.end()); nodeExtractors.insert(funcVarExtractors.begin(), funcVarExtractors.end()); nodeExtractors.insert(annotationImportExtractors.begin(), annotationImportExtractors.end()); + nodeExtractors.insert(importandqualifiedExtractors.begin(), importandqualifiedExtractors.end()); initialized = true; } @@ -796,7 +834,9 @@ const std::unordered_map &GetNodeMatchers() {ir::AstNodeType::ETS_PARAMETER_EXPRESSION, MatchEtsParameterExpression}, {ir::AstNodeType::SWITCH_STATEMENT, MatchSwitchStatement}, {ir::AstNodeType::TS_NON_NULL_EXPRESSION, MatchTsNonNullExpression}, - {ir::AstNodeType::FUNCTION_DECLARATION, MatchFunctionDeclaration}}; + {ir::AstNodeType::FUNCTION_DECLARATION, MatchFunctionDeclaration}, + {ir::AstNodeType::ETS_IMPORT_DECLARATION, MatchETSImportDeclaration}, + {ir::AstNodeType::TS_QUALIFIED_NAME, MatchTSQualifiedName}}; return NODE_MATCHERS; } diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index 0efe307553..dfd17f7eba 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -525,4 +525,8 @@ ets2panda_add_gtest(lsp_api_get_node_info_class_property_import_test CPP_SOURCES ets2panda_add_gtest(lsp_api_get_rename_locations_from_node_test CPP_SOURCES get_rename_locations_from_node_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_ts_qualified_test CPP_SOURCES + get_node_ts_qualified_test.cpp ) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_import_test.cpp b/ets2panda/test/unit/lsp/get_node_import_test.cpp index 7d918cd385..3189712eea 100644 --- a/ets2panda/test/unit/lsp/get_node_import_test.cpp +++ b/ets2panda/test/unit/lsp/get_node_import_test.cpp @@ -46,7 +46,7 @@ export function add(a: number, b: number): number { } static void GenerateContexts(Initializer &initializer) { - contexts_ = initializer.CreateContext("GetNodeImportTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + contexts_ = initializer.CreateContext("GetNodeImportTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); } // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) static inline es2panda_Context *contexts_ = nullptr; @@ -97,4 +97,18 @@ TEST_F(LspGetNodeImportTests, GetImportNamespaceSpecifier) ASSERT_NE(extractedText.find(moduleName), std::string::npos); } +TEST_F(LspGetNodeImportTests, GetETSImportDeclarations) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "std/math"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_IMPORT_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + } // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_ts_qualified_test.cpp b/ets2panda/test/unit/lsp/get_node_ts_qualified_test.cpp new file mode 100755 index 0000000000..6d48c17819 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_ts_qualified_test.cpp @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTsQualifiedTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"(export namespace HTTP { + export namespace Status { + export let Code = 200; + } +} +interface Response { + status: HTTP.Status.Code; +})"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeTsQualifiedTest.ts", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeTsQualifiedTests, GetNodeTsQualifiedTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Code"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_QUALIFIED_NAME}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTsQualifiedTests, GetNodeTsQualifiedTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Status"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_QUALIFIED_NAME}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file -- Gitee