• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cstddef>
17 #include <string>
18 #include <vector>
19 #include "lsp_api_test.h"
20 #include "lsp/include/internal_api.h"
21 #include "lsp/include/references.h"
22 #include "public/es2panda_lib.h"
23 
24 using ark::es2panda::lsp::Initializer;
25 
26 class LSPGetReferencesAtPositionTests : public LSPAPITests {
27 public:
28     LSPGetReferencesAtPositionTests() = default;
29     ~LSPGetReferencesAtPositionTests() override = default;
30 
31     NO_COPY_SEMANTIC(LSPGetReferencesAtPositionTests);
32     NO_MOVE_SEMANTIC(LSPGetReferencesAtPositionTests);
33 
MockGetReferencesAtPosition(char const * fileName,size_t position,const std::vector<std::string> & filePaths)34     References MockGetReferencesAtPosition(char const *fileName, size_t position,
35                                            const std::vector<std::string> &filePaths)
36     {
37         Initializer initializer = Initializer();
38         auto context = initializer.CreateContext(fileName, ES2PANDA_STATE_CHECKED);
39         auto astNode = ark::es2panda::lsp::GetTouchingToken(context, position, false);
40         auto declInfo = ark::es2panda::lsp::GetDeclInfoImpl(astNode);
41         initializer.DestroyContext(context);
42 
43         References result {};
44         for (auto const &file : filePaths) {
45             auto fileContext = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED);
46             auto refInfo = ark::es2panda::lsp::GetReferencesAtPositionImpl(fileContext, declInfo);
47             result.referenceInfos.insert(result.referenceInfos.end(), refInfo.referenceInfos.begin(),
48                                          refInfo.referenceInfos.end());
49             initializer.DestroyContext(fileContext);
50         }
51         auto comp = [](const ReferenceInfo &lhs, const ReferenceInfo &rhs) {
52             if (lhs.fileName != rhs.fileName) {
53                 return lhs.fileName < rhs.fileName;
54             }
55             if (lhs.start != rhs.start) {
56                 return lhs.start < rhs.start;
57             }
58             return lhs.length < rhs.length;
59         };
60         ark::es2panda::lsp::RemoveDuplicates(result.referenceInfos, comp);
61         return result;
62     }
63 };
64 
TEST_F(LSPGetReferencesAtPositionTests,GetReferencesAtPosition1)65 TEST_F(LSPGetReferencesAtPositionTests, GetReferencesAtPosition1)
66 {
67     std::vector<std::string> files = {"references1.ets"};
68     std::vector<std::string> texts = {R"(let a = 1;;)"};
69     auto filePaths = CreateTempFile(files, texts);
70     size_t const expectedFileCount = 1;
71     ASSERT_EQ(filePaths.size(), expectedFileCount);
72 
73     size_t const position = 4;
74     References result = MockGetReferencesAtPosition(filePaths[0].c_str(), position, filePaths);
75     // NOLINTBEGIN(readability-magic-numbers)
76     std::vector<ReferenceInfo> expectedResult {{filePaths[0], 4, 1}};
77     // NOLINTEND(readability-magic-numbers)
78     ASSERT_EQ(result.referenceInfos.size(), expectedResult.size());
79     for (size_t i = 0; i < expectedResult.size(); i++) {
80         ASSERT_EQ(result.referenceInfos[i].fileName, expectedResult[i].fileName);
81         ASSERT_EQ(result.referenceInfos[i].start, expectedResult[i].start);
82         ASSERT_EQ(result.referenceInfos[i].length, expectedResult[i].length);
83     }
84 }
85 
TEST_F(LSPGetReferencesAtPositionTests,GetReferencesAtPosition2)86 TEST_F(LSPGetReferencesAtPositionTests, GetReferencesAtPosition2)
87 {
88     std::vector<std::string> files = {"references2.ets", "references3.ets"};
89     std::vector<std::string> texts = {R"(export let a = 1;
90 let b = a;
91 function C() {
92     let c = a;
93 };
94 function D() {
95     let a = 1;
96 };)",
97                                       R"(import {a} from './references2';
98 console.log(a);)"};
99     auto filePaths = CreateTempFile(files, texts);
100     size_t const expectedFileCount = 2;
101     ASSERT_EQ(filePaths.size(), expectedFileCount);
102 
103     size_t const position = 26;
104     References result = MockGetReferencesAtPosition(filePaths[0].c_str(), position, filePaths);
105     // NOLINTBEGIN(readability-magic-numbers)
106     std::vector<ReferenceInfo> expectedResult {{filePaths[0], 11, 1},
107                                                {filePaths[0], 26, 1},
108                                                {filePaths[0], 56, 1},
109                                                {filePaths[1], 8, 1},
110                                                {filePaths[1], 45, 1}};
111     // NOLINTEND(readability-magic-numbers)
112     ASSERT_EQ(result.referenceInfos.size(), expectedResult.size());
113     for (size_t i = 0; i < expectedResult.size(); i++) {
114         ASSERT_EQ(result.referenceInfos[i].fileName, expectedResult[i].fileName);
115         ASSERT_EQ(result.referenceInfos[i].start, expectedResult[i].start);
116         ASSERT_EQ(result.referenceInfos[i].length, expectedResult[i].length);
117     }
118 }
119 
TEST_F(LSPGetReferencesAtPositionTests,GetReferencesAtPosition3)120 TEST_F(LSPGetReferencesAtPositionTests, GetReferencesAtPosition3)
121 {
122     std::vector<std::string> files = {"references4.ets", "references5.ets"};
123     std::vector<std::string> texts = {R"(export function A(){};)", R"(import {A} from './references4';
124 A();)"};
125     auto filePaths = CreateTempFile(files, texts);
126     size_t const expectedFileCount = 2;
127     ASSERT_EQ(filePaths.size(), expectedFileCount);
128 
129     size_t const position = 16;
130     References result = MockGetReferencesAtPosition(filePaths[0].c_str(), position, filePaths);
131     // NOLINTBEGIN(readability-magic-numbers)
132     std::vector<ReferenceInfo> expectedResult {{filePaths[0], 16, 1}, {filePaths[1], 8, 1}, {filePaths[1], 33, 1}};
133     // NOLINTEND(readability-magic-numbers)
134     ASSERT_EQ(result.referenceInfos.size(), expectedResult.size());
135     for (size_t i = 0; i < expectedResult.size(); i++) {
136         ASSERT_EQ(result.referenceInfos[i].fileName, expectedResult[i].fileName);
137         ASSERT_EQ(result.referenceInfos[i].start, expectedResult[i].start);
138         ASSERT_EQ(result.referenceInfos[i].length, expectedResult[i].length);
139     }
140 }
141