• 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 <cstdio>
19 
20 #include "lsp_api_test.h"
21 #include "public/es2panda_lib.h"
22 #include "lsp/include/services/utilities.h"
23 #include "lsp/include/internal_api.h"
24 #include "lsp/include/api.h"
25 
26 using ark::es2panda::lsp::Initializer;
27 
28 class LspGILAPTests : public LSPAPITests {};
29 
TEST_F(LspGILAPTests,GILAPIsInitializer_Test)30 TEST_F(LspGILAPTests, GILAPIsInitializer_Test)
31 {
32     Initializer initializer = Initializer();
33     const char *code = "class C {n: number = 0;constructor() {this.n = 12;};foo():this{return this}}";
34     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
35     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
36 
37     size_t const offset = 20;
38     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
39     ASSERT_NE(result, nullptr);
40     EXPECT_TRUE(ark::es2panda::lsp::IsInitializer(result));
41 
42     initializer.DestroyContext(ctx);
43 }
44 
TEST_F(LspGILAPTests,GILAPIsInitializer_Test1)45 TEST_F(LspGILAPTests, GILAPIsInitializer_Test1)
46 {
47     Initializer initializer = Initializer();
48     const char *code = "class C {n: number=0;foo():this{return this}};let a: C = new C();";
49     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
50     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
51 
52     size_t const offset = 10;
53     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
54     ASSERT_NE(result, nullptr);
55     EXPECT_TRUE(ark::es2panda::lsp::IsInitializer(result));
56 
57     initializer.DestroyContext(ctx);
58 }
59 
TEST_F(LspGILAPTests,GILAPIsReturnNode_Test)60 TEST_F(LspGILAPTests, GILAPIsReturnNode_Test)
61 {
62     Initializer initializer = Initializer();
63     const char *code = "function A(a:number, b:number):boolean{ return true;}";
64     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
65     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
66 
67     size_t const offset = 48;
68     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
69     ASSERT_NE(result, nullptr);
70     EXPECT_TRUE(ark::es2panda::lsp::IsReturnNode(result));
71 
72     initializer.DestroyContext(ctx);
73 }
74 
TEST_F(LspGILAPTests,GILAPIsThisNode_Test)75 TEST_F(LspGILAPTests, GILAPIsThisNode_Test)
76 {
77     Initializer initializer = Initializer();
78     const char *code = "class C {n: number = 0;foo():this{return this}}";
79     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
80     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
81 
82     size_t const offset = 30;
83     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
84     ASSERT_NE(result, nullptr);
85     EXPECT_TRUE(ark::es2panda::lsp::IsThis(result));
86 
87     initializer.DestroyContext(ctx);
88 }
89 
TEST_F(LspGILAPTests,GILAPIsThisNode_Test1)90 TEST_F(LspGILAPTests, GILAPIsThisNode_Test1)
91 {
92     Initializer initializer = Initializer();
93     const char *code = "class C {n: number = 0;foo():this{return this}}";
94     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
95     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
96 
97     size_t const offset = 42;
98     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
99     ASSERT_NE(result, nullptr);
100     EXPECT_TRUE(ark::es2panda::lsp::IsThis(result));
101 
102     initializer.DestroyContext(ctx);
103 }
104 
TEST_F(LspGILAPTests,GILAPIsValidImplementation_Test)105 TEST_F(LspGILAPTests, GILAPIsValidImplementation_Test)
106 {
107     Initializer initializer = Initializer();
108     const char *code = "function A(){ 1+2; }";
109     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
110     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
111 
112     size_t const offset = 15;
113     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
114     ASSERT_NE(result, nullptr);
115     EXPECT_TRUE(ark::es2panda::lsp::IsValidImplementation(result));
116 
117     initializer.DestroyContext(ctx);
118 }
119 
TEST_F(LspGILAPTests,GILAPIsAsTypeNode_Test)120 TEST_F(LspGILAPTests, GILAPIsAsTypeNode_Test)
121 {
122     Initializer initializer = Initializer();
123     const char *code =
124         "class Shape {}class Circle extends Shape {x: number = 5}class Square extends Shape {y: string = 'a'}function "
125         "createShape(): Shape {return new Circle()}let c2 = createShape() as Circle";
126     es2panda_Context *ctx = initializer.CreateContext("dummy-node.ets", ES2PANDA_STATE_CHECKED, code);
127     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
128 
129     size_t const offset = 159;
130     auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false);
131     ASSERT_NE(result, nullptr);
132     ASSERT_TRUE(ark::es2panda::lsp::IsAsTypeNode(result));
133 
134     initializer.DestroyContext(ctx);
135 }
136 
TEST_F(LspGILAPTests,GILAPGetImplementationAtPosition_Test)137 TEST_F(LspGILAPTests, GILAPGetImplementationAtPosition_Test)
138 {
139     Initializer initializer = Initializer();
140     static std::string source = R"(
141     function Ali(a:number, b:number) {
142         return a + b;
143     }
144     Ali(1, 2);
145     function Ali(a:number) {
146         return a;
147     }
148     Ali(1);
149     )";
150     es2panda_Context *ctx =
151         initializer.CreateContext("implementation-at-position.ets", ES2PANDA_STATE_CHECKED, source.data());
152     ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED);
153 
154     const int callOffset = 72;
155 
156     auto result = GetImpl()->getImplementationLocationAtPosition(ctx, callOffset);
157 
158     initializer.DestroyContext(ctx);
159     ASSERT_FALSE(result.empty());
160 
161     const int sL = 1;
162     const int eL = 3;
163 
164     const int sI = 5;
165     const int eI = 67;
166 
167     ASSERT_EQ(result[0].range_.start.line_, sL);
168     ASSERT_EQ(result[0].range_.start.character_, sI);
169 
170     ASSERT_EQ(result[0].range_.end.line_, eL);
171     ASSERT_EQ(result[0].range_.end.character_, eI);
172 
173     ASSERT_EQ(result[0].uri_.compare("implementation-at-position.ets"), 0);
174 }
175