• 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/include/script_element_kind.h"
17 #include "lsp_api_test.h"
18 #include "lsp/include/internal_api.h"
19 #include <gtest/gtest.h>
20 
21 using ark::es2panda::lsp::CompletionEntryKind;
22 using ark::es2panda::lsp::Initializer;
23 
24 namespace {
25 
26 class LspScriptElementKindTests : public LSPAPITests {};
27 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_1)28 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_1)
29 {
30     LSPAPI const *lspApi = GetImpl();
31     ASSERT_TRUE(lspApi != nullptr);
32 
33     Initializer initializer = Initializer();
34     es2panda_Context *context = initializer.CreateContext(
35         "script_element_kind_1.ets", ES2PANDA_STATE_CHECKED,
36         "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = "
37         "\"foo\";\n");
38 
39     ASSERT_EQ(ContextState(context), ES2PANDA_STATE_CHECKED);
40     size_t const numberLiteralOffset = 31;  // 31: position of '3' in '1234'
41     size_t const stringLiteralOffset = 96;  // 96: position of first 'o' in 'foo'
42 
43     auto result = lspApi->getAliasScriptElementKind(context, numberLiteralOffset);
44     ASSERT_EQ(result, CompletionEntryKind::TEXT);  // Literal is VALUE
45     result = lspApi->getAliasScriptElementKind(context, stringLiteralOffset);
46     ASSERT_EQ(result, CompletionEntryKind::TEXT);
47     initializer.DestroyContext(context);
48 }
49 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_2)50 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_2)
51 {
52     LSPAPI const *lspApi = GetImpl();
53     Initializer initializer = Initializer();
54     es2panda_Context *context =
55         initializer.CreateContext("script_element_kind_2.ets", ES2PANDA_STATE_CHECKED,
56                                   "    \nfunction f() {\n    let a = 123;\n}\nconst s = \"hello\";\n");
57 
58     size_t const startOfFile = 0;            // 0: position of start of file, first space
59     size_t const firstleftCurlyBrance = 18;  // 18:position of left curly brance after f()
60     size_t const numberLiteralOffset = 33;   // 33: position of '2' in '123'
61     size_t const stringLiteralOffset = 50;   // 50: position of 'h' in 'hello'
62 
63     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, startOfFile), CompletionEntryKind::TEXT);
64     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, firstleftCurlyBrance), CompletionEntryKind::TEXT);
65     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, numberLiteralOffset), CompletionEntryKind::TEXT);
66     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, stringLiteralOffset), CompletionEntryKind::TEXT);
67 
68     initializer.DestroyContext(context);
69 }
70 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_3)71 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_3)
72 {
73     LSPAPI const *lspApi = GetImpl();
74     Initializer initializer = Initializer();
75 
76     const char *statement = R"(let empty: null = null;
77 let notAssigned: undefined = undefined;)";
78     es2panda_Context *context =
79         initializer.CreateContext("script_element_kind_3.ets", ES2PANDA_STATE_CHECKED, statement);
80 
81     size_t const nullLiteral = 19;       // 19:position of the second null.
82     size_t const etsNullType = 25;       // 25: position of the second let.
83     size_t const undefinedLiteral = 54;  // 54: position of the second undefined.
84 
85     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, nullLiteral), CompletionEntryKind::TEXT);
86     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, etsNullType), CompletionEntryKind::TEXT);
87     ASSERT_EQ(lspApi->getAliasScriptElementKind(context, undefinedLiteral), CompletionEntryKind::TEXT);
88 
89     initializer.DestroyContext(context);
90 }
91 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_4)92 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_4)
93 {
94     LSPAPI const *lspApi = GetImpl();
95     ASSERT_TRUE(lspApi != nullptr);
96     const std::string text = R"(class Person {
97  private body_ : string = '1';
98 }
99 
100 type alias/*1*/ = Person;)";
101 
102     auto pos = text.find("/*1*/");
103     ASSERT_NE(pos, std::string::npos);
104     Initializer initializer = Initializer();
105     auto context = initializer.CreateContext("aliasScriptElementKind_4.ets", ES2PANDA_STATE_CHECKED, text.c_str());
106 
107     auto result = lspApi->getAliasScriptElementKind(context, pos);
108     EXPECT_EQ(result, CompletionEntryKind::CLASS);
109     initializer.DestroyContext(context);
110 }
111 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_5)112 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_5)
113 {
114     LSPAPI const *lspApi = GetImpl();
115     ASSERT_TRUE(lspApi != nullptr);
116     const std::string text = R"(
117 interface MockInterface {
118   parameter1: number;
119   parameter2: string;
120   parameter3: boolean;
121 }
122 
123 type alias/*1*/ = MockInterface;)";
124 
125     auto pos = text.find("/*1*/");
126     ASSERT_NE(pos, std::string::npos);
127     Initializer initializer = Initializer();
128     auto context = initializer.CreateContext("aliasScriptElementKind_5.ets", ES2PANDA_STATE_CHECKED, text.c_str());
129 
130     auto result = lspApi->getAliasScriptElementKind(context, pos);
131     EXPECT_EQ(result, CompletionEntryKind::INTERFACE);
132     initializer.DestroyContext(context);
133 }
134 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_6)135 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_6)
136 {
137     LSPAPI const *lspApi = GetImpl();
138     ASSERT_TRUE(lspApi != nullptr);
139     const std::string text = R"(
140 @Entry
141 @Component
142 struct Index {
143   @State message: string = 'Hello World';
144 
145   build() {
146     RelativeContainer() {
147       Text(this.message)
148         .id('HelloWorld')
149         .fontSize($r('app.float.page_text_font_size'))
150         .fontWeight(FontWeight.Bold)
151         .alignRules({
152           center: { anchor: '__container__', align: VerticalAlign.Center },
153           middle: { anchor: '__container__', align: HorizontalAlign.Center }
154         })
155         .onClick(() => {
156           this.message = 'Welcome';
157         })
158     }
159     .height('100%')
160     .width('100%')
161   }
162 }
163 
164 type alias/*1*/ = Index;)";
165 
166     auto pos = text.find("/*1*/");
167     ASSERT_NE(pos, std::string::npos);
168     Initializer initializer = Initializer();
169     auto context = initializer.CreateContext("aliasScriptElementKind_6.ets", ES2PANDA_STATE_CHECKED, text.c_str());
170 
171     auto result = lspApi->getAliasScriptElementKind(context, pos);
172     EXPECT_EQ(result, CompletionEntryKind::CLASS);
173     initializer.DestroyContext(context);
174 }
175 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_7)176 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_7)
177 {
178     LSPAPI const *lspApi = GetImpl();
179     ASSERT_TRUE(lspApi != nullptr);
180     const std::string text = R"(type alias/*1*/ = '2';)";
181 
182     auto pos = text.find("/*1*/");
183     ASSERT_NE(pos, std::string::npos);
184     Initializer initializer = Initializer();
185     auto context = initializer.CreateContext("aliasScriptElementKind_7.ets", ES2PANDA_STATE_CHECKED, text.c_str());
186 
187     auto result = lspApi->getAliasScriptElementKind(context, pos);
188     EXPECT_EQ(result, CompletionEntryKind::VALUE);
189     initializer.DestroyContext(context);
190 }
191 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_8)192 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_8)
193 {
194     LSPAPI const *lspApi = GetImpl();
195     ASSERT_TRUE(lspApi != nullptr);
196     const std::string text = R"(type alias/*1*/ = undefinedType11;)";
197 
198     auto pos = text.find("/*1*/");
199     ASSERT_NE(pos, std::string::npos);
200     Initializer initializer = Initializer();
201     auto context = initializer.CreateContext("aliasScriptElementKind_8.ets", ES2PANDA_STATE_CHECKED, text.c_str());
202     auto result = lspApi->getAliasScriptElementKind(context, pos);
203     EXPECT_EQ(result, CompletionEntryKind::ALIAS_TYPE);
204     initializer.DestroyContext(context);
205 }
206 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_9)207 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_9)
208 {
209     LSPAPI const *lspApi = GetImpl();
210     ASSERT_TRUE(lspApi != nullptr);
211     const std::string text = R"(type TestUnion/*1*/ = string | number;)";
212 
213     auto pos = text.find("/*1*/");
214     ASSERT_NE(pos, std::string::npos);
215     Initializer initializer = Initializer();
216     auto context = initializer.CreateContext("aliasScriptElementKind_9.ets", ES2PANDA_STATE_CHECKED, text.c_str());
217     auto result = lspApi->getAliasScriptElementKind(context, pos);
218     EXPECT_EQ(result, CompletionEntryKind::TYPE_PARAMETER);
219     initializer.DestroyContext(context);
220 }
221 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_10)222 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_10)
223 {
224     LSPAPI const *lspApi = GetImpl();
225     ASSERT_TRUE(lspApi != nullptr);
226     const std::string text = R"(type Callback/*1*/ = (result: string) => void;)";
227 
228     auto pos = text.find("/*1*/");
229     ASSERT_NE(pos, std::string::npos);
230     Initializer initializer = Initializer();
231     auto context = initializer.CreateContext("aliasScriptElementKind_10.ets", ES2PANDA_STATE_CHECKED, text.c_str());
232     auto result = lspApi->getAliasScriptElementKind(context, pos);
233     EXPECT_EQ(result, CompletionEntryKind::FUNCTION);
234     initializer.DestroyContext(context);
235 }
236 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_11)237 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_11)
238 {
239     LSPAPI const *lspApi = GetImpl();
240     ASSERT_TRUE(lspApi != nullptr);
241     const std::string text = R"(type Callback/*1*/ = () => {};)";
242 
243     auto pos = text.find("/*1*/");
244     ASSERT_NE(pos, std::string::npos);
245     Initializer initializer = Initializer();
246     auto context = initializer.CreateContext("aliasScriptElementKind_11.ets", ES2PANDA_STATE_CHECKED, text.c_str());
247     auto result = lspApi->getAliasScriptElementKind(context, pos);
248     EXPECT_EQ(result, CompletionEntryKind::FUNCTION);
249     initializer.DestroyContext(context);
250 }
251 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_12)252 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_12)
253 {
254     LSPAPI const *lspApi = GetImpl();
255     ASSERT_TRUE(lspApi != nullptr);
256     const std::string text = R"(class Person {
257  private body_ : string = '1';
258  private body_ : string = 'ad';
259 }
260 type alias/*1*/ = Person;)";
261 
262     auto pos = text.find("/*1*/");
263     ASSERT_NE(pos, std::string::npos);
264     Initializer initializer = Initializer();
265     auto context = initializer.CreateContext("aliasScriptElementKind_12.ets", ES2PANDA_STATE_CHECKED, text.c_str());
266     auto result = lspApi->getAliasScriptElementKind(context, pos);
267     EXPECT_EQ(result, CompletionEntryKind::CLASS);
268     initializer.DestroyContext(context);
269 }
270 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_13)271 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_13)
272 {
273     LSPAPI const *lspApi = GetImpl();
274     ASSERT_TRUE(lspApi != nullptr);
275 
276     const std::string text = R"(type TestA<T>/*1*/ = Array<TestA<T>>;)";
277 
278     auto pos = text.find("/*1*/");
279     ASSERT_NE(pos, std::string::npos);
280     Initializer initializer = Initializer();
281     auto context = initializer.CreateContext("aliasScriptElementKind_13.ets", ES2PANDA_STATE_CHECKED, text.c_str());
282     auto result = lspApi->getAliasScriptElementKind(context, pos);
283     EXPECT_EQ(result, CompletionEntryKind::CLASS);
284     initializer.DestroyContext(context);
285 }
286 
TEST_F(LspScriptElementKindTests,GetAliasScriptElementKind_14)287 TEST_F(LspScriptElementKindTests, GetAliasScriptElementKind_14)
288 {
289     LSPAPI const *lspApi = GetImpl();
290     ASSERT_TRUE(lspApi != nullptr);
291 
292     const std::string text = R"(type TestB<T>/*1*/ = string | Array<TestB<T>>;)";
293 
294     auto pos = text.find("/*1*/");
295     ASSERT_NE(pos, std::string::npos);
296     Initializer initializer = Initializer();
297     auto context = initializer.CreateContext("aliasScriptElementKind_14.ets", ES2PANDA_STATE_CHECKED, text.c_str());
298     auto result = lspApi->getAliasScriptElementKind(context, pos);
299     EXPECT_EQ(result, CompletionEntryKind::TYPE_PARAMETER);
300     initializer.DestroyContext(context);
301 }
302 
303 }  // namespace
304