• 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 "lsp_api_test.h"
17 #include "lsp/include/internal_api.h"
18 
19 using ark::es2panda::lsp::Initializer;
20 
21 class LspDocumentHighlights : public LSPAPITests {};
22 
TEST_F(LspDocumentHighlights,getDocumentHighlights1)23 TEST_F(LspDocumentHighlights, getDocumentHighlights1)
24 {
25     std::vector<std::string> files = {"getDocumentHighlights1.ets"};
26     std::vector<std::string> texts = {R"delimiter(
27 let aaa = 123;
28 let bbb = aaa + 111;
29 let ccc = bbb + aaa + 234;
30 )delimiter"};
31     auto filePaths = CreateTempFile(files, texts);
32     int const expectedFileCount = 1;
33     ASSERT_EQ(filePaths.size(), expectedFileCount);
34 
35     LSPAPI const *lspApi = GetImpl();
36     auto const pos = 6;
37     Initializer initializer = Initializer();
38     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
39     auto result = lspApi->getDocumentHighlights(ctx, pos);
40     initializer.DestroyContext(ctx);
41     auto const expectedHighlightCount = 3;
42     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
43     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
44     auto const firstHighlightStart = 5;
45     auto const secondHighlightStart = 26;
46     auto const thirdHighlightStart = 53;
47     auto const expectedLength = 3;
48     auto const secondIndex = 2;
49     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
50     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
51     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start, thirdHighlightStart);
52     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
53     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
54     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, expectedLength);
55     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
56     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
57     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
58 }
59 
TEST_F(LspDocumentHighlights,getDocumentHighlights2)60 TEST_F(LspDocumentHighlights, getDocumentHighlights2)
61 {
62     std::vector<std::string> files = {"getDocumentHighlights2.ets"};
63     std::vector<std::string> texts = {R"delimiter(
64 let aaa = 123;
65 let bbb = aaa + 111;
66 let ccc = bbb + aaa + 234;
67 function f1(aaa: number) {
68     return aaa + bbb;})delimiter"};
69     auto filePaths = CreateTempFile(files, texts);
70     int const expectedFileCount = 1;
71     ASSERT_EQ(filePaths.size(), expectedFileCount);
72     LSPAPI const *lspApi = GetImpl();
73     auto const firstPos = 109;
74     Initializer initializer = Initializer();
75     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
76     auto firstResult = lspApi->getDocumentHighlights(ctx, firstPos);
77     auto const firstExpectedHighlightCount = 3;
78     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_.size(), firstExpectedHighlightCount);
79     ASSERT_EQ(firstResult.documentHighlights_[0].fileName_, filePaths[0]);
80     auto const firstFirstHighlightStart = 20;
81     auto const firstSecondHighlightStart = 47;
82     auto const firstThirdHighlightStart = 108;
83     auto const firstExpectedLength = 3;
84     auto const secondIndex = 2;
85     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstFirstHighlightStart);
86     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[1].textSpan_.start, firstSecondHighlightStart);
87     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start,
88               firstThirdHighlightStart);
89     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[0].textSpan_.length, firstExpectedLength);
90     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[1].textSpan_.length, firstExpectedLength);
91     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, firstExpectedLength);
92     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
93     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
94     ASSERT_EQ(firstResult.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
95     auto const secondPos = 77;
96     auto secondResult = lspApi->getDocumentHighlights(ctx, secondPos);
97     initializer.DestroyContext(ctx);
98     auto const secondExpectedHighlightCount = 2;
99     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_.size(), secondExpectedHighlightCount);
100     ASSERT_EQ(secondResult.documentHighlights_[0].fileName_, filePaths[0]);
101     auto const secondFirstHighlightStart = 76;
102     auto const secondSecondHighlightStart = 102;
103     auto const secondExpectedLength = 3;
104     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[0].textSpan_.start, secondFirstHighlightStart);
105     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondSecondHighlightStart);
106     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[0].textSpan_.length, secondExpectedLength);
107     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[1].textSpan_.length, secondExpectedLength);
108     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
109     ASSERT_EQ(secondResult.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
110 }
111 
TEST_F(LspDocumentHighlights,getDocumentHighlights3)112 TEST_F(LspDocumentHighlights, getDocumentHighlights3)
113 {
114     std::vector<std::string> files = {"getDocumentHighlights3.ets"};
115     std::vector<std::string> texts = {R"delimiter(
116 class Foo {
117     aaa: number = 0;
118 }
119 
120 let foo1 = new Foo();
121 foo1.aaa = 222
122 
123 function f2() {
124     let foo2 = new Foo();
125     return foo2.aaa + foo1.aaa;
126 }
127 )delimiter"};
128     auto filePaths = CreateTempFile(files, texts);
129     int const expectedFileCount = 1;
130     ASSERT_EQ(filePaths.size(), expectedFileCount);
131 
132     LSPAPI const *lspApi = GetImpl();
133     auto const pos = 8;
134     Initializer initializer = Initializer();
135     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
136     auto result = lspApi->getDocumentHighlights(ctx, pos);
137     initializer.DestroyContext(ctx);
138     auto const expectedHighlightCount = 3;
139     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
140     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
141     auto const firstHighlightStart = 7;
142     auto const secondHighlightStart = 52;
143     auto const thirdHighlightStart = 110;
144     auto const expectedLength = 3;
145     auto const secondIndex = 2;
146     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
147     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
148     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start, thirdHighlightStart);
149     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
150     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
151     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, expectedLength);
152     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
153     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
154     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
155 }
156 
TEST_F(LspDocumentHighlights,getDocumentHighlights4)157 TEST_F(LspDocumentHighlights, getDocumentHighlights4)
158 {
159     std::vector<std::string> files = {"getDocumentHighlights3.ets"};
160     std::vector<std::string> texts = {R"delimiter(
161 class Foo {
162     aaa: number = 0;
163 }
164 
165 let foo1 = new Foo();
166 foo1.aaa = 222
167 
168 function f2() {
169     let foo2 = new Foo();
170     return foo2.aaa + foo1.aaa;
171 }
172 )delimiter"};
173     auto filePaths = CreateTempFile(files, texts);
174     int const expectedFileCount = 1;
175     ASSERT_EQ(filePaths.size(), expectedFileCount);
176 
177     LSPAPI const *lspApi = GetImpl();
178     auto const pos = 18;
179     Initializer initializer = Initializer();
180     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
181     auto result = lspApi->getDocumentHighlights(ctx, pos);
182     initializer.DestroyContext(ctx);
183     auto const expectedHighlightCount = 4;
184     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
185     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
186     auto const firstHighlightStart = 17;
187     auto const secondHighlightStart = 64;
188     auto const thirdHighlightStart = 133;
189     auto const fourthHighlightStart = 144;
190     auto const expectedLength = 3;
191     auto const secondIndex = 2;
192     auto const thirdIndex = 3;
193     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
194     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
195     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start, thirdHighlightStart);
196     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[thirdIndex].textSpan_.start, fourthHighlightStart);
197     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
198     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
199     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, expectedLength);
200     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[thirdIndex].textSpan_.length, expectedLength);
201     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
202     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
203     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
204     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[thirdIndex].kind_, HighlightSpanKind::REFERENCE);
205 }
206 
TEST_F(LspDocumentHighlights,getDocumentHighlights5)207 TEST_F(LspDocumentHighlights, getDocumentHighlights5)
208 {
209     std::vector<std::string> files = {"getDocumentHighlights5.ets"};
210     std::vector<std::string> texts = {R"delimiter(
211 function add(x: number, y: number) {
212     return x + y;
213 }
214 
215 function five() {
216     return add(2, 3);
217 }
218 
219 class Bar {
220     six: number = add(2, 4);
221 }
222 )delimiter"};
223     auto filePaths = CreateTempFile(files, texts);
224     int const expectedFileCount = 1;
225     ASSERT_EQ(filePaths.size(), expectedFileCount);
226 
227     LSPAPI const *lspApi = GetImpl();
228     auto const pos = 11;
229     Initializer initializer = Initializer();
230     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
231     auto result = lspApi->getDocumentHighlights(ctx, pos);
232     initializer.DestroyContext(ctx);
233     auto const expectedHighlightCount = 3;
234     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
235     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
236     auto const firstHighlightStart = 10;
237     auto const secondHighlightStart = 88;
238     auto const thirdHighlightStart = 132;
239     auto const expectedLength = 3;
240     auto const secondIndex = 2;
241     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
242     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
243     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start, thirdHighlightStart);
244     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
245     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
246     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, expectedLength);
247     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
248     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
249     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
250 }
251 
TEST_F(LspDocumentHighlights,getDocumentHighlights6)252 TEST_F(LspDocumentHighlights, getDocumentHighlights6)
253 {
254     std::vector<std::string> files = {"getDocumentHighlights6.ets"};
255     std::vector<std::string> texts = {R"delimiter(
256 class ListNode<T> {
257     value: T;
258     next: ListNode<T> | null = null;
259 
260     constructor(value: T) {
261         this.value = value;
262     }
263 }
264 )delimiter"};
265     auto filePaths = CreateTempFile(files, texts);
266     int const expectedFileCount = 1;
267     ASSERT_EQ(filePaths.size(), expectedFileCount);
268 
269     LSPAPI const *lspApi = GetImpl();
270     auto const pos = 49;
271     Initializer initializer = Initializer();
272     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
273     auto result = lspApi->getDocumentHighlights(ctx, pos);
274     initializer.DestroyContext(ctx);
275     auto const expectedHighlightCount = 2;
276     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
277     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
278     auto const firstHighlightStart = 7;
279     auto const secondHighlightStart = 45;
280     auto const expectedLength = 8;
281     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
282     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
283     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
284     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
285     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
286     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
287 }
288 
TEST_F(LspDocumentHighlights,getDocumentHighlights7)289 TEST_F(LspDocumentHighlights, getDocumentHighlights7)
290 {
291     std::vector<std::string> files = {"getDocumentHighlights7.ets"};
292     std::vector<std::string> texts = {R"delimiter(
293 function fib(n: number) {
294     if (n === 0) {
295         return 0;
296     }
297     if (n === 1) {
298         return 1;
299     }
300     return fib(n - 1) + fib(n - 2);
301 }
302 )delimiter"};
303     auto filePaths = CreateTempFile(files, texts);
304     int const expectedFileCount = 1;
305     ASSERT_EQ(filePaths.size(), expectedFileCount);
306 
307     LSPAPI const *lspApi = GetImpl();
308     auto const pos = 125;
309     Initializer initializer = Initializer();
310     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
311     auto result = lspApi->getDocumentHighlights(ctx, pos);
312     initializer.DestroyContext(ctx);
313     auto const expectedHighlightCount = 3;
314     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_.size(), expectedHighlightCount);
315     ASSERT_EQ(result.documentHighlights_[0].fileName_, filePaths[0]);
316     auto const firstHighlightStart = 10;
317     auto const secondHighlightStart = 124;
318     auto const thirdHighlightStart = 137;
319     auto const expectedLength = 3;
320     auto const secondIndex = 2;
321     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.start, firstHighlightStart);
322     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.start, secondHighlightStart);
323     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.start, thirdHighlightStart);
324     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].textSpan_.length, expectedLength);
325     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].textSpan_.length, expectedLength);
326     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].textSpan_.length, expectedLength);
327     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[0].kind_, HighlightSpanKind::WRITTEN_REFERENCE);
328     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[1].kind_, HighlightSpanKind::REFERENCE);
329     ASSERT_EQ(result.documentHighlights_[0].highlightSpans_[secondIndex].kind_, HighlightSpanKind::REFERENCE);
330 }
331