From a915a12527cb6ec77de92376b4cbfe3bef2803fd Mon Sep 17 00:00:00 2001 From: lijunru Date: Wed, 23 Jul 2025 16:10:01 +0800 Subject: [PATCH] Support go to the import file Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICOB1C Signed-off-by: lijunru --- ets2panda/bindings/test/cases.ts | 3 +- .../expected/getDefinitionAtPosition.json | 5 ++ ets2panda/lsp/include/internal_api.h | 1 + ets2panda/lsp/src/api.cpp | 4 ++ ets2panda/lsp/src/internal_api.cpp | 14 ++++ ets2panda/test/unit/lsp/CMakeLists.txt | 12 ++-- .../unit/lsp/get_import_file_path_test.cpp | 69 +++++++++++++++++++ 7 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/unit/lsp/get_import_file_path_test.cpp diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts index 6194db0a25..2174a4d07f 100644 --- a/ets2panda/bindings/test/cases.ts +++ b/ets2panda/bindings/test/cases.ts @@ -44,7 +44,8 @@ export const basicCases: TestCases = { '7': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets'), 664], '8': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.ets'), 617], '9': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.ets'), 677], - '11': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.ets'), 634] + '11': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.ets'), 634], + '12': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets'), 637] }, getSemanticDiagnostics: { expectedFilePath: resolveTestPath('test/expected/getSemanticDiagnostics.json'), diff --git a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json index 0463704db9..ad5c03a796 100644 --- a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json +++ b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json @@ -53,5 +53,10 @@ "fileName": "taskpool.ets", "start": 686, "length": 4 + }, + "12": { + "fileName": "getDefinitionAtPosition1.ets", + "start": 0, + "length": 0 } } diff --git a/ets2panda/lsp/include/internal_api.h b/ets2panda/lsp/include/internal_api.h index 4c0cbeee7b..e52b422cc8 100644 --- a/ets2panda/lsp/include/internal_api.h +++ b/ets2panda/lsp/include/internal_api.h @@ -140,6 +140,7 @@ ir::Identifier *GetIdentFromNewClassExprPart(const ir::Expression *value); varbinder::Decl *FindDeclInFunctionScope(varbinder::Scope *scope, const util::StringView &name); varbinder::Decl *FindDeclInGlobalScope(varbinder::Scope *scope, const util::StringView &name); varbinder::Decl *FindDeclInScopeWithFallback(varbinder::Scope *scope, const util::StringView &name); +std::string GetImportFilePath(es2panda_Context *context, size_t pos); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/api.cpp b/ets2panda/lsp/src/api.cpp index 129747640c..50a852b028 100644 --- a/ets2panda/lsp/src/api.cpp +++ b/ets2panda/lsp/src/api.cpp @@ -51,6 +51,10 @@ DefinitionInfo GetDefinitionAtPosition(es2panda_Context *context, size_t positio { auto ctx = reinterpret_cast(context); SetPhaseManager(ctx->phaseManager); + auto importFilePath = GetImportFilePath(context, position); + if (!importFilePath.empty()) { + return {importFilePath, 0, 0}; + } auto declInfo = GetDefinitionAtPositionImpl(context, position); DefinitionInfo result {}; if (declInfo.first == nullptr) { diff --git a/ets2panda/lsp/src/internal_api.cpp b/ets2panda/lsp/src/internal_api.cpp index 175d39818b..86b27c2036 100644 --- a/ets2panda/lsp/src/internal_api.cpp +++ b/ets2panda/lsp/src/internal_api.cpp @@ -632,6 +632,20 @@ std::pair GetDefinitionAtPositionImpl(es2panda_ return res; } +std::string GetImportFilePath(es2panda_Context *context, size_t pos) +{ + std::string res; + auto node = GetTouchingToken(context, pos, false); + if (node == nullptr) { + return res; + } + auto parent = node->Parent(); + if (parent != nullptr && parent->IsETSImportDeclaration() && parent->AsETSImportDeclaration()->Source() == node) { + res = std::string(parent->AsETSImportDeclaration()->ImportMetadata().resolvedSource); + } + return res; +} + ArenaVector RemoveRefDuplicates(const ArenaVector &nodes, ArenaAllocator *allocator) { auto hashFunc = [](const ir::AstNode *node) { diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index 2685091cae..e4481514f6 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -214,7 +214,7 @@ ets2panda_add_gtest(lsp_api_test_find_rename_locations CPP_SOURCES ets2panda_add_gtest(lsp_api_test_fix_expected_comma CPP_SOURCES fix_expected_comma_test.cpp - ) +) ets2panda_add_gtest(lsp_api_test_change_tracker CPP_SOURCES change_tracker_test.cpp @@ -280,10 +280,14 @@ ets2panda_add_gtest(lsp_api_test_forgotten_this_property_access CPP_SOURCES forgotten_this_property_access_test.cpp ) - ets2panda_add_gtest(lsp_api_test_remove_accidental_call_parentheses CPP_SOURCES +ets2panda_add_gtest(lsp_api_test_remove_accidental_call_parentheses CPP_SOURCES remove_accidental_call_parentheses_test.cpp - ) +) ets2panda_add_gtest(lsp_api_add_missing_new_operator CPP_SOURCES add_missing_new_operator_test.cpp -) \ No newline at end of file +) + +ets2panda_add_gtest(lsp_get_import_file_path_test CPP_SOURCES + get_import_file_path_test.cpp +) diff --git a/ets2panda/test/unit/lsp/get_import_file_path_test.cpp b/ets2panda/test/unit/lsp/get_import_file_path_test.cpp new file mode 100644 index 0000000000..006989b0aa --- /dev/null +++ b/ets2panda/test/unit/lsp/get_import_file_path_test.cpp @@ -0,0 +1,69 @@ +/** + * 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 +#include +#include +#include "lsp_api_test.h" +#include "lsp/include/internal_api.h" + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetImportFilePathTests : public LSPAPITests {}; + +TEST_F(LspGetImportFilePathTests, GetImportFilePath1) +{ + std::vector files = {"GetImportFilePath1.ets", "GetImportFilePath2.ets"}; + std::vector texts = {R"(export function A(a:number, b:number): number { + return a + b; +})", + R"(import {A} from './GetImportFilePath1';)"}; + auto filePaths = CreateTempFile(files, texts); + size_t const expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 22; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getDefinitionAtPosition(ctx, offset); + initializer.DestroyContext(ctx); + std::string expectedFileName = filePaths[0]; + size_t const expectedStart = 0; + size_t const expectedLength = 0; + ASSERT_EQ(result.fileName, expectedFileName); + ASSERT_EQ(result.start, expectedStart); + ASSERT_EQ(result.length, expectedLength); +} + +TEST_F(LspGetImportFilePathTests, GetImportFilePath2) +{ + LSPAPI const *lspApi = GetImpl(); + // Test invalid position to avoid segment fault + size_t const offset = 24; + Initializer initializer = Initializer(); + auto ctx = + initializer.CreateContext("invalidPositionTest.ets", ES2PANDA_STATE_CHECKED, "let invalidPositionTest = 0;"); + auto result = lspApi->getDefinitionAtPosition(ctx, offset); + initializer.DestroyContext(ctx); + std::string expectedFileName; + size_t const expectedStart = 0; + size_t const expectedLength = 0; + ASSERT_EQ(result.fileName, expectedFileName); + ASSERT_EQ(result.start, expectedStart); + ASSERT_EQ(result.length, expectedLength); +} +} // namespace \ No newline at end of file -- Gitee