• 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/internal_api.h"
17 #include "lsp/include/classifier.h"
18 #include "lsp_api_test.h"
19 #include "public/es2panda_lib.h"
20 
21 using ark::es2panda::lsp::Initializer;
22 
23 class LspDiagnosticsTests : public LSPAPITests {};
24 
TEST_F(LspDiagnosticsTests,GetSemanticDiagnostics1)25 TEST_F(LspDiagnosticsTests, GetSemanticDiagnostics1)
26 {
27     Initializer initializer = Initializer();
28     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
29                                                       R"(function add(a: number, b: number) {
30     return a + b;
31 }
32 let n = 333;
33 let res = add(n, n);)");
34     LSPAPI const *lspApi = GetImpl();
35     DiagnosticReferences result = lspApi->getSemanticDiagnostics(ctx);
36     initializer.DestroyContext(ctx);
37     ASSERT_EQ(result.diagnostic.size(), 0);
38 }
39 
TEST_F(LspDiagnosticsTests,GetSemanticDiagnostics2)40 TEST_F(LspDiagnosticsTests, GetSemanticDiagnostics2)
41 {
42     Initializer initializer = Initializer();
43     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
44                                                       R"(const a: number = "hello";
45 function add(a: number, b: number): number {
46     return a + b;
47 }
48 add("1", 2);)");
49     LSPAPI const *lspApi = GetImpl();
50     DiagnosticReferences result = lspApi->getSemanticDiagnostics(ctx);
51     initializer.DestroyContext(ctx);
52     auto const expectedErrorCount = 3;
53     ASSERT_EQ(result.diagnostic.size(), expectedErrorCount);
54     auto const thirdIndex = 2;
55     auto const expectedFirstStartLine = 1;
56     auto const expectedFirstStartCharacter = 19;
57     auto const expectedFirstEndLine = 1;
58     auto const expectedFirstEndCharacter = 26;
59     ASSERT_EQ(result.diagnostic[thirdIndex].range_.start.line_, expectedFirstStartLine);
60     ASSERT_EQ(result.diagnostic[thirdIndex].range_.start.character_, expectedFirstStartCharacter);
61     ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.line_, expectedFirstEndLine);
62     ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.character_, expectedFirstEndCharacter);
63     ASSERT_EQ(result.diagnostic[thirdIndex].severity_, DiagnosticSeverity::Error);
64     ASSERT_NE(std::get<int>(result.diagnostic[thirdIndex].code_), 0);
65     ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Type '"hello"' cannot be assigned to type 'double')");
66     ASSERT_EQ(result.diagnostic[thirdIndex].codeDescription_.href_, "test code description");
67     auto const expectedSecondStartLine = 5;
68     auto const expectedSecondStartCharacter = 5;
69     auto const expectedSecondEndLine = 5;
70     auto const expectedSecondEndCharacter = 8;
71     ASSERT_EQ(result.diagnostic[0].range_.start.line_, expectedSecondStartLine);
72     ASSERT_EQ(result.diagnostic[0].range_.start.character_, expectedSecondStartCharacter);
73     ASSERT_EQ(result.diagnostic[0].range_.end.line_, expectedSecondEndLine);
74     ASSERT_EQ(result.diagnostic[0].range_.end.character_, expectedSecondEndCharacter);
75     ASSERT_EQ(result.diagnostic[0].severity_, DiagnosticSeverity::Error);
76     ASSERT_NE(std::get<int>(result.diagnostic[0].code_), 0);
77     ASSERT_EQ(result.diagnostic[0].message_, R"(Type '"1"' is not compatible with type 'double' at index 1)");
78     ASSERT_EQ(result.diagnostic[0].codeDescription_.href_, "test code description");
79 }
80 
TEST_F(LspDiagnosticsTests,GetSyntacticDiagnostics1)81 TEST_F(LspDiagnosticsTests, GetSyntacticDiagnostics1)
82 {
83     Initializer initializer = Initializer();
84     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
85                                                       R"(function add(a: number, b: number) {
86     return a + b;
87 }
88 let n = 333;
89 let res = add(n, n);)");
90     LSPAPI const *lspApi = GetImpl();
91     auto result = lspApi->getSyntacticDiagnostics(ctx);
92     initializer.DestroyContext(ctx);
93     ASSERT_EQ(result.diagnostic.size(), 0);
94 }
95 
TEST_F(LspDiagnosticsTests,GetSyntacticDiagnostics2)96 TEST_F(LspDiagnosticsTests, GetSyntacticDiagnostics2)
97 {
98     Initializer initializer = Initializer();
99     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
100                                                       R"(functon add(a: number, b: number) {
101     return a + b;
102 }
103 let n = 333;
104 let res = add(n, n);)");
105     LSPAPI const *lspApi = GetImpl();
106     auto result = lspApi->getSyntacticDiagnostics(ctx);
107     initializer.DestroyContext(ctx);
108     auto const expectedErrorCount = 13;
109     ASSERT_EQ(result.diagnostic.size(), expectedErrorCount);
110     auto const expectedFirstStartLine = 1;
111     auto const expectedFirstStartCharacter = 9;
112     auto const expectedFirstEndLine = 1;
113     auto const expectedFirstEndCharacter = 12;
114     ASSERT_EQ(result.diagnostic[0].range_.start.line_, expectedFirstStartLine);
115     ASSERT_EQ(result.diagnostic[0].range_.start.character_, expectedFirstStartCharacter);
116     ASSERT_EQ(result.diagnostic[0].range_.end.line_, expectedFirstEndLine);
117     ASSERT_EQ(result.diagnostic[0].range_.end.character_, expectedFirstEndCharacter);
118     ASSERT_EQ(result.diagnostic[0].severity_, DiagnosticSeverity::Error);
119     ASSERT_NE(std::get<int>(result.diagnostic[0].code_), 0);
120     auto const expectedSecondStartLine = 1;
121     auto const expectedSecondStartCharacter = 14;
122     auto const expectedSecondEndLine = 1;
123     auto const expectedSecondEndCharacter = 15;
124     ASSERT_EQ(result.diagnostic[1].range_.start.line_, expectedSecondStartLine);
125     ASSERT_EQ(result.diagnostic[1].range_.start.character_, expectedSecondStartCharacter);
126     ASSERT_EQ(result.diagnostic[1].range_.end.line_, expectedSecondEndLine);
127     ASSERT_EQ(result.diagnostic[1].range_.end.character_, expectedSecondEndCharacter);
128     ASSERT_EQ(result.diagnostic[1].severity_, DiagnosticSeverity::Error);
129     ASSERT_NE(std::get<int>(result.diagnostic[1].code_), 0);
130     auto const thirdIndex = 2;
131     auto const expectedThirdStartLine = 1;
132     auto const expectedThirdStartCharacter = 14;
133     auto const expectedThirdEndLine = 1;
134     auto const expectedThirdEndCharacter = 15;
135     ASSERT_EQ(result.diagnostic[thirdIndex].range_.start.line_, expectedThirdStartLine);
136     ASSERT_EQ(result.diagnostic[thirdIndex].range_.start.character_, expectedThirdStartCharacter);
137     ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.line_, expectedThirdEndLine);
138     ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.character_, expectedThirdEndCharacter);
139     ASSERT_EQ(result.diagnostic[thirdIndex].severity_, DiagnosticSeverity::Error);
140     ASSERT_NE(std::get<int>(result.diagnostic[thirdIndex].code_), 0);
141     ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Unexpected token ':'.)");
142 }
143 
TEST_F(LspDiagnosticsTests,GetSyntacticDiagnostics3)144 TEST_F(LspDiagnosticsTests, GetSyntacticDiagnostics3)
145 {
146     Initializer initializer = Initializer();
147     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
148                                                       R"(functon add(a: number, b: number) {
149     return a + b;
150 }
151 let n = 333;
152 let res = add(n, n);)");
153     LSPAPI const *lspApi = GetImpl();
154     auto result = lspApi->getSyntacticDiagnostics(ctx);
155     initializer.DestroyContext(ctx);
156     auto const forthIndex = 5;
157     auto const expectedForthStartLine = 1;
158     auto const expectedForthStartCharacter = 22;
159     auto const expectedForthEndLine = 1;
160     auto const expectedForthEndCharacter = 23;
161     ASSERT_EQ(result.diagnostic[forthIndex].range_.start.line_, expectedForthStartLine);
162     ASSERT_EQ(result.diagnostic[forthIndex].range_.start.character_, expectedForthStartCharacter);
163     ASSERT_EQ(result.diagnostic[forthIndex].range_.end.line_, expectedForthEndLine);
164     ASSERT_EQ(result.diagnostic[forthIndex].range_.end.character_, expectedForthEndCharacter);
165     ASSERT_EQ(result.diagnostic[forthIndex].severity_, DiagnosticSeverity::Error);
166     ASSERT_NE(std::get<int>(result.diagnostic[forthIndex].code_), 0);
167     ASSERT_EQ(result.diagnostic[forthIndex].message_, R"(Unexpected token ','.)");
168     ASSERT_EQ(result.diagnostic[forthIndex].codeDescription_.href_, "test code description");
169     auto const fifthIndex = 8;
170     auto const expectedFifththStartLine = 1;
171     auto const expectedFifthStartCharacter = 27;
172     auto const expectedFifthEndLine = 1;
173     auto const expectedFifthEndCharacter = 33;
174     ASSERT_EQ(result.diagnostic[fifthIndex].range_.start.line_, expectedFifththStartLine);
175     ASSERT_EQ(result.diagnostic[fifthIndex].range_.start.character_, expectedFifthStartCharacter);
176     ASSERT_EQ(result.diagnostic[fifthIndex].range_.end.line_, expectedFifthEndLine);
177     ASSERT_EQ(result.diagnostic[fifthIndex].range_.end.character_, expectedFifthEndCharacter);
178     ASSERT_EQ(result.diagnostic[fifthIndex].severity_, DiagnosticSeverity::Error);
179     ASSERT_NE(std::get<int>(result.diagnostic[fifthIndex].code_), 0);
180     ASSERT_EQ(result.diagnostic[fifthIndex].message_, R"(Label must be followed by a loop statement.)");
181     ASSERT_EQ(result.diagnostic[fifthIndex].codeDescription_.href_, "test code description");
182 }
183 
TEST_F(LspDiagnosticsTests,GetSyntacticDiagnosticsForFile4)184 TEST_F(LspDiagnosticsTests, GetSyntacticDiagnosticsForFile4)
185 {
186     Initializer initializer = Initializer();
187     es2panda_Context *ctx = initializer.CreateContext("GetSemanticDiagnosticsNoError1.ets", ES2PANDA_STATE_CHECKED,
188                                                       R"(functon add(a: number, b: number) {
189     return a + b;
190 }
191 let n = 333;
192 let res = add(n, n);)");
193     LSPAPI const *lspApi = GetImpl();
194     auto result = lspApi->getSyntacticDiagnostics(ctx);
195     initializer.DestroyContext(ctx);
196     auto const sixthIndex = 9;
197     auto const expectedSixthStartLine = 1;
198     auto const expectedSixthStartCharacter = 33;
199     auto const expectedSixthEndLine = 1;
200     auto const expectedSixthEndCharacter = 34;
201     ASSERT_EQ(result.diagnostic[sixthIndex].range_.start.line_, expectedSixthStartLine);
202     ASSERT_EQ(result.diagnostic[sixthIndex].range_.start.character_, expectedSixthStartCharacter);
203     ASSERT_EQ(result.diagnostic[sixthIndex].range_.end.line_, expectedSixthEndLine);
204     ASSERT_EQ(result.diagnostic[sixthIndex].range_.end.character_, expectedSixthEndCharacter);
205     ASSERT_EQ(result.diagnostic[sixthIndex].severity_, DiagnosticSeverity::Error);
206     ASSERT_NE(std::get<int>(result.diagnostic[sixthIndex].code_), 0);
207     ASSERT_EQ(result.diagnostic[sixthIndex].message_, R"(Unexpected token ')'.)");
208     ASSERT_EQ(result.diagnostic[sixthIndex].codeDescription_.href_, "test code description");
209     auto const sevenIndex = 12;
210     auto const expectedSeventhStartLine = 2;
211     auto const expectedSeventhStartCharacter = 5;
212     auto const expectedSeventhEndLine = 2;
213     auto const expectedSeventhEndCharacter = 18;
214     ASSERT_EQ(result.diagnostic[sevenIndex].range_.start.line_, expectedSeventhStartLine);
215     ASSERT_EQ(result.diagnostic[sevenIndex].range_.start.character_, expectedSeventhStartCharacter);
216     ASSERT_EQ(result.diagnostic[sevenIndex].range_.end.line_, expectedSeventhEndLine);
217     ASSERT_EQ(result.diagnostic[sevenIndex].range_.end.character_, expectedSeventhEndCharacter);
218     ASSERT_EQ(result.diagnostic[sevenIndex].severity_, DiagnosticSeverity::Error);
219     ASSERT_NE(std::get<int>(result.diagnostic[sevenIndex].code_), 0);
220     ASSERT_EQ(result.diagnostic[sevenIndex].message_, R"(return keyword should be used in function body.)");
221     ASSERT_EQ(result.diagnostic[sevenIndex].codeDescription_.href_, "test code description");
222 }
223