• 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 <gtest/gtest.h>
17 #include <cstddef>
18 #include <string>
19 #include "lsp_api_test.h"
20 #include "lsp/include/internal_api.h"
21 
22 using ark::es2panda::lsp::Initializer;
23 
24 class LspGetDefTests : public LSPAPITests {};
25 
TEST_F(LspGetDefTests,GetDefinitionAtPosition1)26 TEST_F(LspGetDefTests, GetDefinitionAtPosition1)
27 {
28     std::vector<std::string> files = {"getDefinitionAtPosition1.ets", "getDefinitionAtPosition2.ets"};
29     std::vector<std::string> texts = {R"(export function A(a:number, b:number): number {
30     return a + b;
31 })",
32                                       R"(import {A} from './getDefinitionAtPosition1';
33 A(1, 2);)"};
34     auto filePaths = CreateTempFile(files, texts);
35     size_t const expectedFileCount = 2;
36     ASSERT_EQ(filePaths.size(), expectedFileCount);
37 
38     LSPAPI const *lspApi = GetImpl();
39     size_t const offset = 46;
40     Initializer initializer = Initializer();
41     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
42     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
43     initializer.DestroyContext(ctx);
44     std::string expectedFileName = filePaths[0];
45     size_t const expectedStart = 16;
46     size_t const expectedLength = 1;
47     ASSERT_EQ(result.fileName, expectedFileName);
48     ASSERT_EQ(result.start, expectedStart);
49     ASSERT_EQ(result.length, expectedLength);
50 }
51 
TEST_F(LspGetDefTests,GetDefinitionAtPosition2)52 TEST_F(LspGetDefTests, GetDefinitionAtPosition2)
53 {
54     std::vector<std::string> files = {"getDefinitionAtPosition3.ets"};
55     std::vector<std::string> texts = {R"(
56     function A(a:number, b:number) {
57         return a + b;
58     }
59     A(1, 2);
60     function A(a:number) {
61         return a;
62     }
63     A(1);)"};
64     auto filePaths = CreateTempFile(files, texts);
65     int const expectedFileCount = 1;
66     ASSERT_EQ(filePaths.size(), expectedFileCount);
67 
68     LSPAPI const *lspApi = GetImpl();
69     size_t const offset = 70;
70     Initializer initializer = Initializer();
71     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
72     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
73     initializer.DestroyContext(ctx);
74     std::string expectedFileName = filePaths[0];
75     size_t const expectedStart = 14;
76     size_t const expectedLength = 1;
77     ASSERT_EQ(result.fileName, expectedFileName);
78     ASSERT_EQ(result.start, expectedStart);
79     ASSERT_EQ(result.length, expectedLength);
80 
81     size_t const offset1 = 134;
82     auto ctx1 = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
83     auto result1 = lspApi->getDefinitionAtPosition(ctx1, offset1);
84     initializer.DestroyContext(ctx1);
85     std::string expectedFileName1 = filePaths[0];
86     size_t const expectedStart1 = 92;
87     size_t const expectedLength1 = 1;
88     ASSERT_EQ(result1.fileName, expectedFileName1);
89     ASSERT_EQ(result1.start, expectedStart1);
90     ASSERT_EQ(result1.length, expectedLength1);
91 }
92 
TEST_F(LspGetDefTests,GetDefinitionAtPosition3)93 TEST_F(LspGetDefTests, GetDefinitionAtPosition3)
94 {
95     std::vector<std::string> files = {"getDefinitionAtPosition4.ets", "getDefinitionAtPosition5.ets"};
96     std::vector<std::string> texts = {R"(export function A(a:number, b:number): number {
97     return a + b;
98 })",
99                                       R"(import * as All from './getDefinitionAtPosition4';
100 All.A(1, 2);)"};
101     auto filePaths = CreateTempFile(files, texts);
102     size_t const expectedFileCount = 2;
103     ASSERT_EQ(filePaths.size(), expectedFileCount);
104 
105     LSPAPI const *lspApi = GetImpl();
106     size_t const offset = 55;
107     Initializer initializer = Initializer();
108     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
109     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
110     initializer.DestroyContext(ctx);
111     std::string expectedFileName = filePaths[0];
112     size_t const expectedStart = 16;
113     size_t const expectedLength = 1;
114     ASSERT_EQ(result.fileName, expectedFileName);
115     ASSERT_EQ(result.start, expectedStart);
116     ASSERT_EQ(result.length, expectedLength);
117 }
118 
TEST_F(LspGetDefTests,GetDefinitionAtPosition4)119 TEST_F(LspGetDefTests, GetDefinitionAtPosition4)
120 {
121     std::vector<std::string> files = {"getDefinitionAtPosition6.ets", "getDefinitionAtPosition7.ets"};
122     std::vector<std::string> texts = {R"(export class A {
123 Foo(a:number, b:number): number {
124     return a + b;
125 }})",
126                                       R"(import * as All from './getDefinitionAtPosition6';
127 let a = new All.A();
128 a.Foo(1, 2);)"};
129     auto filePaths = CreateTempFile(files, texts);
130     size_t const expectedFileCount = 2;
131     ASSERT_EQ(filePaths.size(), expectedFileCount);
132 
133     LSPAPI const *lspApi = GetImpl();
134     size_t const offset = 74;
135     Initializer initializer = Initializer();
136     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
137     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
138     initializer.DestroyContext(ctx);
139     std::string expectedFileName = filePaths[0];
140     size_t const expectedStart = 17;
141     size_t const expectedLength = 3;
142     ASSERT_EQ(result.fileName, expectedFileName);
143     ASSERT_EQ(result.start, expectedStart);
144     ASSERT_EQ(result.length, expectedLength);
145 }
146 
TEST_F(LspGetDefTests,GetDefinitionAtPosition5)147 TEST_F(LspGetDefTests, GetDefinitionAtPosition5)
148 {
149     std::vector<std::string> files = {"getDefinitionAtPosition8.ets", "getDefinitionAtPosition9.ets"};
150     std::vector<std::string> texts = {R"(export enum A {
151 a,
152 b})",
153                                       R"(import * as All from './getDefinitionAtPosition8';
154 All.A.a;)"};
155     auto filePaths = CreateTempFile(files, texts);
156     size_t const expectedFileCount = 2;
157     ASSERT_EQ(filePaths.size(), expectedFileCount);
158 
159     LSPAPI const *lspApi = GetImpl();
160     size_t const offset = 57;
161     Initializer initializer = Initializer();
162     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
163     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
164     initializer.DestroyContext(ctx);
165     std::string expectedFileName = filePaths[0];
166     size_t const expectedStart = 16;
167     size_t const expectedLength = 1;
168     ASSERT_EQ(result.fileName, expectedFileName);
169     ASSERT_EQ(result.start, expectedStart);
170     ASSERT_EQ(result.length, expectedLength);
171 }
172 
TEST_F(LspGetDefTests,GetDefinitionAtPosition6)173 TEST_F(LspGetDefTests, GetDefinitionAtPosition6)
174 {
175     std::vector<std::string> files = {"getDefinitionAtPosition10.ets", "getDefinitionAtPosition11.ets"};
176     std::vector<std::string> texts = {R"(export class A {
177 Foo(a:number, b:number): number {
178     return a + b;
179 }};
180 )",
181                                       R"(import {A} from './getDefinitionAtPosition10';
182 let a = new A();
183 a.Foo(1, 2);)"};
184     auto filePaths = CreateTempFile(files, texts);
185     size_t const expectedFileCount = 2;
186     ASSERT_EQ(filePaths.size(), expectedFileCount);
187 
188     LSPAPI const *lspApi = GetImpl();
189     size_t const offset = 66;
190     Initializer initializer = Initializer();
191     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
192     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
193     initializer.DestroyContext(ctx);
194     std::string expectedFileName = filePaths[0];
195     size_t const expectedStart = 17;
196     size_t const expectedLength = 3;
197     ASSERT_EQ(result.fileName, expectedFileName);
198     ASSERT_EQ(result.start, expectedStart);
199     ASSERT_EQ(result.length, expectedLength);
200 }
201 
TEST_F(LspGetDefTests,GetDefinitionAtPosition7)202 TEST_F(LspGetDefTests, GetDefinitionAtPosition7)
203 {
204     std::vector<std::string> files = {"getDefinitionAtPosition12.ets", "getDefinitionAtPosition13.ets"};
205     std::vector<std::string> texts = {R"(export let a = 1;)",
206                                       R"(import {a} from './getDefinitionAtPosition12';
207 let b = a;)"};
208     auto filePaths = CreateTempFile(files, texts);
209     size_t const expectedFileCount = 2;
210     ASSERT_EQ(filePaths.size(), expectedFileCount);
211 
212     LSPAPI const *lspApi = GetImpl();
213     size_t const offset = 55;
214     Initializer initializer = Initializer();
215     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
216     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
217     initializer.DestroyContext(ctx);
218     std::string expectedFileName = filePaths[0];
219     size_t const expectedStart = 11;
220     size_t const expectedLength = 1;
221     ASSERT_EQ(result.fileName, expectedFileName);
222     ASSERT_EQ(result.start, expectedStart);
223     ASSERT_EQ(result.length, expectedLength);
224 }
225 
TEST_F(LspGetDefTests,GetDefinitionAtPosition8)226 TEST_F(LspGetDefTests, GetDefinitionAtPosition8)
227 {
228     std::vector<std::string> files = {"getDefinitionAtPosition14.ets", "getDefinitionAtPosition15.ets"};
229     std::vector<std::string> texts = {R"(export interface I {})",
230                                       R"(import {I} from './getDefinitionAtPosition14';
231 import * as All from './getDefinitionAtPosition14';
232 class A implements All.I {};)"};
233     auto filePaths = CreateTempFile(files, texts);
234     size_t const expectedFileCount = 2;
235     ASSERT_EQ(filePaths.size(), expectedFileCount);
236 
237     LSPAPI const *lspApi = GetImpl();
238     size_t const offset = 8;
239     Initializer initializer = Initializer();
240     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
241     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
242     initializer.DestroyContext(ctx);
243     std::string expectedFileName = filePaths[0];
244     size_t const expectedStart = 17;
245     size_t const expectedLength = 1;
246     ASSERT_EQ(result.fileName, expectedFileName);
247     ASSERT_EQ(result.start, expectedStart);
248     ASSERT_EQ(result.length, expectedLength);
249 
250     size_t const offset1 = 122;
251     ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
252     result = lspApi->getDefinitionAtPosition(ctx, offset1);
253     initializer.DestroyContext(ctx);
254     ASSERT_EQ(result.fileName, expectedFileName);
255     ASSERT_EQ(result.start, expectedStart);
256     ASSERT_EQ(result.length, expectedLength);
257 }
258 
TEST_F(LspGetDefTests,GetDefinitionAtPosition9)259 TEST_F(LspGetDefTests, GetDefinitionAtPosition9)
260 {
261     std::vector<std::string> files = {"getDefinitionAtPosition16.ets", "getDefinitionAtPosition17.ets"};
262     std::vector<std::string> texts = {R"(export class Foo {
263 Foo(a:number, b:number): number {
264     return a + b;
265 }})",
266                                       R"(import * as All from './getDefinitionAtPosition16';
267 let a = new All.Foo();
268 a.Foo(1, 2);)"};
269     auto filePaths = CreateTempFile(files, texts);
270     size_t const expectedFileCount = 2;
271     ASSERT_EQ(filePaths.size(), expectedFileCount);
272 
273     LSPAPI const *lspApi = GetImpl();
274     size_t const offset = 68;
275     Initializer initializer = Initializer();
276     auto ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
277     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
278     initializer.DestroyContext(ctx);
279     std::string expectedFileName = filePaths[0];
280     size_t const expectedStart = 13;
281     size_t const expectedLength = 3;
282     ASSERT_EQ(result.fileName, expectedFileName);
283     ASSERT_EQ(result.start, expectedStart);
284     ASSERT_EQ(result.length, expectedLength);
285 
286     size_t const offset1 = 77;
287     ctx = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED);
288     auto result1 = lspApi->getDefinitionAtPosition(ctx, offset1);
289     initializer.DestroyContext(ctx);
290     std::string expectedFileName1 = filePaths[0];
291     size_t const expectedStart1 = 19;
292     size_t const expectedLength1 = 3;
293     ASSERT_EQ(result1.fileName, expectedFileName1);
294     ASSERT_EQ(result1.start, expectedStart1);
295     ASSERT_EQ(result1.length, expectedLength1);
296 }
297 
TEST_F(LspGetDefTests,GetDefinitionAtPositionForStdLibraryTaskPool)298 TEST_F(LspGetDefTests, GetDefinitionAtPositionForStdLibraryTaskPool)
299 {
300     std::vector<std::string> files = {"getDefinitionAtPositionForStdLibraryTaskPool.ets"};
301     std::vector<std::string> texts = {R"(const task = new taskpool.Task(()=>{});)"};
302     auto filePaths = CreateTempFile(files, texts);
303     size_t const expectedFileCount = 1;
304     ASSERT_EQ(filePaths.size(), expectedFileCount);
305 
306     LSPAPI const *lspApi = GetImpl();
307     size_t const offset = 21;
308     Initializer initializer = Initializer();
309     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
310     auto result = lspApi->getDefinitionAtPosition(ctx, offset);
311     initializer.DestroyContext(ctx);
312     std::string expectedFileName = "taskpool.ets";
313     size_t const expectedLength = 8;
314     ASSERT_TRUE(result.fileName.find(expectedFileName) != std::string::npos);
315     ASSERT_EQ(result.length, expectedLength);
316 }
317