• 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/quick_info.h"
17 #include "lsp_api_test.h"
18 #include "lsp/include/internal_api.h"
19 #include <gtest/gtest.h>
20 namespace {
21 using ark::es2panda::lsp::Initializer;
22 
23 class LspQuickInfoTests : public LSPAPITests {};
24 
TEST_F(LspQuickInfoTests,CreateDisplayForEnum)25 TEST_F(LspQuickInfoTests, CreateDisplayForEnum)
26 {
27     Initializer initializer = Initializer();
28     es2panda_Context *ctx =
29         initializer.CreateContext("enum-test.ets", ES2PANDA_STATE_CHECKED, "enum MyEnum { A, B, C }");
30     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
31     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
32     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
33     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
34         return node->Type() == ark::es2panda::ir::AstNodeType::CLASS_DEFINITION &&
35                node->AsClassDefinition()->Ident()->Name() == "MyEnum";
36     };
37     auto found = ast->FindChild(checkFunc);
38     auto enumDecl = found->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration();
39     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForEnum(enumDecl);
40     std::vector<SymbolDisplayPart> expected;
41     expected.emplace_back("enum", "keyword");
42     expected.emplace_back(" ", "space");
43     expected.emplace_back("MyEnum", "enumName");
44     ASSERT_EQ(expected, display);
45     initializer.DestroyContext(ctx);
46 }
47 
TEST_F(LspQuickInfoTests,CreateDisplayForClass1)48 TEST_F(LspQuickInfoTests, CreateDisplayForClass1)
49 {
50     Initializer initializer = Initializer();
51     es2panda_Context *ctx =
52         initializer.CreateContext("quick-info-test.ets", ES2PANDA_STATE_CHECKED,
53                                   "class Test {\n  private _a: number = 1;\n  public get a(): number {\n    "
54                                   "return this._a;\n  }\n  public static ccc:number = 1\n\n  constructor(a : "
55                                   "number) {\n  }\n}\n\nlet a = 1\nlet test: Test = new Test(a)\nlet t_a = test.a");
56     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
57     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
58     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
59     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
60         return node->Type() == ark::es2panda::ir::AstNodeType::CLASS_DECLARATION &&
61                node->AsClassDeclaration()->Definition()->InternalName() != "quick-info-test.ETSGLOBAL";
62     };
63     auto found = ast->FindChild(checkFunc);
64     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForClass(found);
65     std::vector<SymbolDisplayPart> expected;
66     auto keyword1 = SymbolDisplayPart("class", "keyword");
67     auto keyword2 = SymbolDisplayPart(" ", "space");
68     auto keyword3 = SymbolDisplayPart("Test", "className");
69     expected.push_back(keyword1);
70     expected.push_back(keyword2);
71     expected.push_back(keyword3);
72     ASSERT_EQ(expected, display);
73     initializer.DestroyContext(ctx);
74 }
75 
TEST_F(LspQuickInfoTests,CreateDisplayForUnionTypeAlias)76 TEST_F(LspQuickInfoTests, CreateDisplayForUnionTypeAlias)
77 {
78     Initializer initializer = Initializer();
79     es2panda_Context *ctx = initializer.CreateContext("union-type-alias-test.ets", ES2PANDA_STATE_CHECKED,
80                                                       "type TestUnion = string | number;");
81     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
82     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
83     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
84     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
85         return node->Type() == ark::es2panda::ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION;
86     };
87     auto found = ast->FindChild(checkFunc);
88     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForTypeAlias(found);
89     std::vector<SymbolDisplayPart> expected;
90     expected.emplace_back("type", "keyword");
91     expected.emplace_back(" ", "space");
92     expected.emplace_back("TestUnion", "className");
93     expected.emplace_back(" ", "space");
94     expected.emplace_back("=", "operator");
95     expected.emplace_back(" ", "space");
96     expected.emplace_back("string|number", "typeName");
97     ASSERT_EQ(expected, display);
98     initializer.DestroyContext(ctx);
99 }
100 
TEST_F(LspQuickInfoTests,CreateDisplayForTypeAlias)101 TEST_F(LspQuickInfoTests, CreateDisplayForTypeAlias)
102 {
103     Initializer initializer = Initializer();
104     es2panda_Context *ctx =
105         initializer.CreateContext("type-alias-test.ets", ES2PANDA_STATE_CHECKED, "type TestType = string;");
106     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
107     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
108     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
109     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
110         return node->Type() == ark::es2panda::ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION;
111     };
112     auto found = ast->FindChild(checkFunc);
113     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForTypeAlias(found);
114     std::vector<SymbolDisplayPart> expected;
115     expected.emplace_back("type", "keyword");
116     expected.emplace_back(" ", "space");
117     expected.emplace_back("TestType", "className");
118     expected.emplace_back(" ", "space");
119     expected.emplace_back("=", "operator");
120     expected.emplace_back(" ", "space");
121     expected.emplace_back("string", "typeName");
122     ASSERT_EQ(expected, display);
123     initializer.DestroyContext(ctx);
124 }
125 
TEST_F(LspQuickInfoTests,CreateDisplayForInterface)126 TEST_F(LspQuickInfoTests, CreateDisplayForInterface)
127 {
128     Initializer initializer = Initializer();
129     es2panda_Context *ctx = initializer.CreateContext(
130         "quick-info-test.ets", ES2PANDA_STATE_CHECKED,
131         "interface Inner { key : string; }\ninterface Outer { inner : Inner; keyValue : number; }");
132     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
133     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
134     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
135     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
136         return node->Type() == ark::es2panda::ir::AstNodeType::TS_INTERFACE_DECLARATION;
137     };
138     auto found = ast->FindChild(checkFunc);
139     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForInterface(found);
140     std::vector<SymbolDisplayPart> expected;
141     auto keyword1 = SymbolDisplayPart("interface", "keyword");
142     auto keyword2 = SymbolDisplayPart(" ", "space");
143     auto keyword3 = SymbolDisplayPart("Inner", "className");
144     expected.push_back(keyword1);
145     expected.push_back(keyword2);
146     expected.push_back(keyword3);
147     ASSERT_EQ(expected, display);
148     initializer.DestroyContext(ctx);
149 }
150 
TEST_F(LspQuickInfoTests,CreateDisplayForTypeAliasTypeParameter)151 TEST_F(LspQuickInfoTests, CreateDisplayForTypeAliasTypeParameter)
152 {
153     Initializer initializer = Initializer();
154     es2panda_Context *ctx =
155         initializer.CreateContext("type-alias-type-param-test.ets", ES2PANDA_STATE_CHECKED, "type list<T> = T[]");
156     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
157     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
158     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
159     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
160         return node->Type() == ark::es2panda::ir::AstNodeType::TS_TYPE_PARAMETER;
161     };
162     auto found = ast->FindChild(checkFunc);
163     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForTypeParameter(found);
164     std::vector<SymbolDisplayPart> expected;
165     expected.emplace_back("T", "typeParameter");
166     expected.emplace_back(" ", "space");
167     expected.emplace_back("in", "keyword");
168     expected.emplace_back(" ", "space");
169     expected.emplace_back("type", "keyword");
170     expected.emplace_back(" ", "space");
171     expected.emplace_back("list", "typeName");
172     expected.emplace_back("<", "punctuation");
173     expected.emplace_back("T", "typeParameter");
174     expected.emplace_back(">", "punctuation");
175     ASSERT_EQ(expected, display);
176     initializer.DestroyContext(ctx);
177 }
178 
TEST_F(LspQuickInfoTests,CreateDisplayForClassDeclarationTypeParameter)179 TEST_F(LspQuickInfoTests, CreateDisplayForClassDeclarationTypeParameter)
180 {
181     Initializer initializer = Initializer();
182     es2panda_Context *ctx = initializer.CreateContext("class-type-param-test.ets", ES2PANDA_STATE_CHECKED,
183                                                       "class Queue<T> { private items: T[] = []; }");
184     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
185     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
186     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
187     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
188         return node->Type() == ark::es2panda::ir::AstNodeType::TS_TYPE_PARAMETER;
189     };
190     auto found = ast->FindChild(checkFunc);
191     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForTypeParameter(found);
192     std::vector<SymbolDisplayPart> expected;
193     expected.emplace_back("T", "typeParameter");
194     expected.emplace_back(" ", "space");
195     expected.emplace_back("in", "keyword");
196     expected.emplace_back(" ", "space");
197     expected.emplace_back("Queue", "className");
198     expected.emplace_back("<", "punctuation");
199     expected.emplace_back("T", "typeParameter");
200     expected.emplace_back(">", "punctuation");
201     ASSERT_EQ(expected, display);
202     initializer.DestroyContext(ctx);
203 }
204 
TEST_F(LspQuickInfoTests,CreateDisplayForMethodDefinition)205 TEST_F(LspQuickInfoTests, CreateDisplayForMethodDefinition)
206 {
207     Initializer initializer = Initializer();
208     es2panda_Context *ctx = initializer.CreateContext("method-definition-test.ets", ES2PANDA_STATE_CHECKED,
209                                                       "function func(a: number): string { return 'function1'; }");
210     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
211     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
212     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
213     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
214         return node->Type() == ark::es2panda::ir::AstNodeType::METHOD_DEFINITION &&
215                node->AsMethodDefinition()->Id()->Name() != "main" &&
216                node->AsMethodDefinition()->Id()->Name() != "_$init$_";
217     };
218     auto found = ast->FindChild(checkFunc);
219     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForMethodDefinition(found, "");
220     std::vector<SymbolDisplayPart> expected;
221 
222     // Expected parts for the method definition
223     expected.emplace_back("function", "keyword");
224     expected.emplace_back(" ", "space");
225     expected.emplace_back("func", "functionName");
226     expected.emplace_back("(", "punctuation");
227     expected.emplace_back("a", "functionParameter");
228     expected.emplace_back(":", "punctuation");
229     expected.emplace_back(" ", "space");
230     expected.emplace_back("number", "typeParameter");
231     expected.emplace_back(")", "punctuation");
232     expected.emplace_back(":", "punctuation");
233     expected.emplace_back(" ", "space");
234     expected.emplace_back("string", "returnType");
235 
236     ASSERT_EQ(expected, display);
237     initializer.DestroyContext(ctx);
238 }
239 
TEST_F(LspQuickInfoTests,CreateDisplayForScriptFunctionTypeParameter)240 TEST_F(LspQuickInfoTests, CreateDisplayForScriptFunctionTypeParameter)
241 {
242     Initializer initializer = Initializer();
243     es2panda_Context *ctx = initializer.CreateContext("function-type-param-test.ets", ES2PANDA_STATE_CHECKED,
244                                                       "function identity<T, D>(arg: T): T { return arg }");
245     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
246     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
247     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
248     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
249         return node->Type() == ark::es2panda::ir::AstNodeType::TS_TYPE_PARAMETER;
250     };
251     auto found = ast->FindChild(checkFunc);
252     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForTypeParameter(found);
253     std::vector<SymbolDisplayPart> expected;
254     expected.emplace_back("T", "typeParameter");
255     expected.emplace_back(" ", "space");
256     expected.emplace_back("in", "keyword");
257     expected.emplace_back(" ", "space");
258     expected.emplace_back("identity", "functionName");
259     expected.emplace_back("<", "punctuation");
260     expected.emplace_back("T", "typeParameter");
261     expected.emplace_back(",", "punctuation");
262     expected.emplace_back(" ", "space");
263     expected.emplace_back("D", "typeParameter");
264     expected.emplace_back(">", "punctuation");
265     expected.emplace_back("(", "punctuation");
266     expected.emplace_back("arg", "functionParameter");
267     expected.emplace_back(":", "punctuation");
268     expected.emplace_back(" ", "space");
269     expected.emplace_back("T", "typeParameter");
270     expected.emplace_back(")", "punctuation");
271     expected.emplace_back(":", "punctuation");
272     expected.emplace_back(" ", "space");
273     expected.emplace_back("T", "returnType");
274     ASSERT_EQ(expected, display);
275     initializer.DestroyContext(ctx);
276 }
277 
TEST_F(LspQuickInfoTests,CreateDisplayForClassProperty1)278 TEST_F(LspQuickInfoTests, CreateDisplayForClassProperty1)
279 {
280     Initializer initializer = Initializer();
281     es2panda_Context *ctx =
282         initializer.CreateContext("class-property-test.ets", ES2PANDA_STATE_CHECKED,
283                                   "class MyClass {\n  public myProp: number = 0;\n}\n let obj = new MyClass();");
284     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
285     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
286     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
287     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
288         return node->Type() == ark::es2panda::ir::AstNodeType::CLASS_PROPERTY &&
289                node->AsClassProperty()->Key()->AsIdentifier()->Name() != "ETSGLOBAL";
290     };
291     auto found = ast->FindChild(checkFunc);
292     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForClassProperty(found, "const");
293     std::vector<SymbolDisplayPart> expected;
294 
295     expected.emplace_back("const", "keyword");
296     expected.emplace_back(" ", "space");
297     expected.emplace_back("obj", "property");
298     expected.emplace_back(":", "punctuation");
299     expected.emplace_back(" ", "space");
300     expected.emplace_back("MyClass", "typeName");
301 
302     ASSERT_EQ(expected, display);
303     initializer.DestroyContext(ctx);
304 }
305 
TEST_F(LspQuickInfoTests,CreateDisplayForClassProperty2)306 TEST_F(LspQuickInfoTests, CreateDisplayForClassProperty2)
307 {
308     Initializer initializer = Initializer();
309     es2panda_Context *ctx = initializer.CreateContext("class-property-test.ets", ES2PANDA_STATE_CHECKED,
310                                                       "class MyClass {\n  public myProp: number = 0;\n}");
311     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
312     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
313     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
314     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
315         return node->Type() == ark::es2panda::ir::AstNodeType::CLASS_PROPERTY &&
316                node->AsClassProperty()->Key()->AsIdentifier()->Name() != "ETSGLOBAL";
317     };
318     auto found = ast->FindChild(checkFunc);
319     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForClassProperty(found, "const");
320     std::vector<SymbolDisplayPart> expected;
321 
322     expected.emplace_back("MyClass", "className");
323     expected.emplace_back(".", "punctuation");
324     expected.emplace_back("myProp", "property");
325     expected.emplace_back(":", "punctuation");
326     expected.emplace_back(" ", "space");
327     expected.emplace_back("number", "typeName");
328 
329     ASSERT_EQ(expected, display);
330     initializer.DestroyContext(ctx);
331 }
332 
TEST_F(LspQuickInfoTests,CreateDisplayForParameterExpression)333 TEST_F(LspQuickInfoTests, CreateDisplayForParameterExpression)
334 {
335     Initializer initializer = Initializer();
336     es2panda_Context *ctx = initializer.CreateContext("parameter-expression-test.ets", ES2PANDA_STATE_CHECKED,
337                                                       "function func(param1: string, param2: number) {}");
338     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
339     auto context = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
340     auto ast = reinterpret_cast<ark::es2panda::ir::AstNode *>(context->parserProgram->Ast());
341     auto checkFunc = [](ark::es2panda::ir::AstNode *node) {
342         return node->Type() == ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION &&
343                node->AsETSParameterExpression()->Name() != "param2";
344     };
345     auto found = ast->FindChild(checkFunc);
346     std::vector<SymbolDisplayPart> display = ark::es2panda::lsp::CreateDisplayForETSParameterExpression(found);
347     std::vector<SymbolDisplayPart> expected;
348 
349     expected.emplace_back("param1", "functionParameter");
350     expected.emplace_back(":", "punctuation");
351     expected.emplace_back(" ", "space");
352     expected.emplace_back("string", "typeName");
353 
354     ASSERT_EQ(expected, display);
355     initializer.DestroyContext(ctx);
356 }
357 }  // namespace