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
18 #include <gtest/gtest.h>
19 #include <cstddef>
20
21 #include "ir/astNode.h"
22 #include "lsp/include/internal_api.h"
23 #include "public/es2panda_lib.h"
24 #include "public/public.h"
25
26 using ark::es2panda::lsp::Initializer;
27
28 class LspGetReferenceLocationTests : public LSPAPITests {};
29
TEST_F(LspGetReferenceLocationTests,GetReferenceLocationAtPosition1)30 TEST_F(LspGetReferenceLocationTests, GetReferenceLocationAtPosition1)
31 {
32 using ark::es2panda::public_lib::Context;
33 std::vector<std::string> files = {"ref_loc_export1.ts", "ref_loc_export2.ts", "ref_loc_export3.ts",
34 "ref_loc_export4.ts", "<ref-file.ets>"};
35 std::vector<std::string> texts = {"function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);",
36 "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);",
37 "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);",
38 "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);",
39 "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"};
40 auto filePaths = CreateTempFile(files, texts);
41 std::vector<std::string> autoGenerateFolders = {"export1.ts", "export2.ts"};
42
43 ark::es2panda::lsp::RemoveFromFiles(files, autoGenerateFolders);
44 const size_t fileCount = 3;
45 ASSERT_EQ(files.size(), fileCount);
46 }
47
TEST_F(LspGetReferenceLocationTests,GetReferenceLocationAtPosition2)48 TEST_F(LspGetReferenceLocationTests, GetReferenceLocationAtPosition2)
49 {
50 using ark::es2panda::public_lib::Context;
51 std::vector<std::string> fileNames = {"firstFile.ets", "secondFile.ets", "thirdFile.ets"};
52 std::vector<std::string> fileContents = {
53 "export function abc(x: number): void {\n}\n\nexport function dummy(x: number): void {\n}\n"
54 "\nexport class Foo {\nname: string = \"unassigned\";\nx: number = 1;\ny: number = 2;\nz: number = 3;"
55 "\nconstructor(name: string, x: number, y: number, z: number) {\nthis.name = name;\nthis.x = x;\nthis.y = "
56 "y;\nthis.z = z;\n}\n};",
57 "import {dummy, abc} from \"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(1);\nabc(2);",
58 "import { dummy, abc } from "
59 "\"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(3);\nabc(4);\nabc(5);\n"};
60 auto filePaths = CreateTempFile(fileNames, fileContents);
61 ASSERT_TRUE(filePaths.size() == fileContents.size());
62 Initializer initializer = Initializer();
63 const int position = 17;
64 const int fileIndex = 0;
65 auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED);
66 auto node = ark::es2panda::lsp::GetTouchingToken(context, position, false);
67 auto tokenId = ark::es2panda::lsp::GetOwnerId(node);
68 auto tokenName = ark::es2panda::lsp::GetIdentifierName(node);
69 FileNodeInfo fileNameInfo(tokenName, tokenId);
70 auto list = ReferenceLocationList();
71 initializer.DestroyContext(context);
72 for (const std::string &file : filePaths) {
73 auto ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED);
74 ark::es2panda::lsp::GetReferenceLocationAtPositionImpl(fileNameInfo, ctx, &list);
75 initializer.DestroyContext(ctx);
76 }
77 const size_t file1Location = 0;
78 const size_t start1Index = 16;
79 const size_t file2Location = 2;
80 const size_t start2Index = 70;
81 ASSERT_EQ(list.referenceLocation.at(file1Location).uri, filePaths[0]);
82 ASSERT_EQ(list.referenceLocation.at(file1Location).start, start1Index);
83 ASSERT_EQ(list.referenceLocation.at(file2Location).uri, filePaths[1]);
84 ASSERT_EQ(list.referenceLocation.at(file2Location).start, start2Index);
85 }
86
TEST_F(LspGetReferenceLocationTests,GetReferenceLocationAtPosition3)87 TEST_F(LspGetReferenceLocationTests, GetReferenceLocationAtPosition3)
88 {
89 using ark::es2panda::public_lib::Context;
90 std::vector<std::string> fileNames = {"firstFile.ets", "secondFile.ets", "thirdFile.ets"};
91 std::vector<std::string> fileContents = {
92 "export function abc(x: number): void {\n}\n\nexport function dummy(x: number): void {\n}\n"
93 "\nexport class Foo {\nname: string = \"unassigned\";\nx: number = 1;\ny: number = 2;\nz: number = 3;"
94 "\nconstructor(name: string, x: number, y: number, z: number) {\nthis.name = name;\nthis.x = x;\nthis.y = "
95 "y;\nthis.z = z;\n}\n};",
96 "import {dummy, abc} from \"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(1);\nabc(2);",
97 "import { dummy, abc } from "
98 "\"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(3);\nabc(4);\nabc(5);\n"};
99 auto filePaths = CreateTempFile(fileNames, fileContents);
100 ASSERT_TRUE(filePaths.size() == fileContents.size());
101 Initializer initializer = Initializer();
102 const int position = 73;
103 const int fileIndex = 1;
104 auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED);
105 auto node = ark::es2panda::lsp::GetTouchingToken(context, position, false);
106 auto tokenId = ark::es2panda::lsp::GetOwnerId(node);
107 auto tokenName = ark::es2panda::lsp::GetIdentifierName(node);
108 FileNodeInfo fileNameInfo(tokenName, tokenId);
109 auto list = ReferenceLocationList();
110 initializer.DestroyContext(context);
111 for (const std::string &file : filePaths) {
112 auto ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED);
113 ark::es2panda::lsp::GetReferenceLocationAtPositionImpl(fileNameInfo, ctx, &list);
114
115 initializer.DestroyContext(ctx);
116 }
117 const size_t file1Location = 0;
118 const size_t start1Index = 16;
119 const size_t file2Location = 2;
120 const size_t start2Index = 70;
121 ASSERT_EQ(list.referenceLocation.at(file1Location).uri, filePaths[0]);
122 ASSERT_EQ(list.referenceLocation.at(file1Location).start, start1Index);
123 ASSERT_EQ(list.referenceLocation.at(file2Location).uri, filePaths[1]);
124 ASSERT_EQ(list.referenceLocation.at(file2Location).start, start2Index);
125 }
126
TEST_F(LspGetReferenceLocationTests,GetReferenceLocationAtPosition4)127 TEST_F(LspGetReferenceLocationTests, GetReferenceLocationAtPosition4)
128 {
129 using ark::es2panda::public_lib::Context;
130 std::vector<std::string> fileNames = {"firstFile.ets", "secondFile.ets", "thirdFile.ets"};
131 std::vector<std::string> fileContents = {
132 "export function abc(x: number): void {\n}\n\nexport function dummy(x: number): void {\n}\n"
133 "\nexport class Foo {\nname: string = \"unassigned\";\nx: number = 1;\ny: number = 2;\nz: number = 3;"
134 "\nconstructor(name: string, x: number, y: number, z: number) {\nthis.name = name;\nthis.x = x;\nthis.y = "
135 "y;\nthis.z = z;\n}\n};",
136 "import {dummy, abc} from \"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(1);\nabc(2);",
137 "import { dummy, abc } from "
138 "\"./firstFile.ets\";\n\ndummy(123);\ndummy(1992);\nabc(3);\nabc(4);\nabc(5);\n"};
139 auto filePaths = CreateTempFile(fileNames, fileContents);
140 ASSERT_TRUE(filePaths.size() == fileContents.size());
141 Initializer initializer = Initializer();
142 const int position = 58;
143 const int fileIndex = 0;
144 auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED);
145 auto node = ark::es2panda::lsp::GetTouchingToken(context, position, false);
146 auto tokenId = ark::es2panda::lsp::GetOwnerId(node);
147 auto tokenName = ark::es2panda::lsp::GetIdentifierName(node);
148 FileNodeInfo fileNameInfo(tokenName, tokenId);
149 auto list = ReferenceLocationList();
150 initializer.DestroyContext(context);
151 for (const std::string &file : filePaths) {
152 auto ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED);
153 ark::es2panda::lsp::GetReferenceLocationAtPositionImpl(fileNameInfo, ctx, &list);
154 initializer.DestroyContext(ctx);
155 }
156 const size_t file1Location = 0;
157 const size_t start1Index = 58;
158 const size_t file2Location = 1;
159 const size_t start2Index = 8;
160
161 ASSERT_EQ(list.referenceLocation.at(file1Location).uri, filePaths[0]);
162 ASSERT_EQ(list.referenceLocation.at(file1Location).start, start1Index);
163 ASSERT_EQ(list.referenceLocation.at(file2Location).uri, filePaths[1]);
164 ASSERT_EQ(list.referenceLocation.at(file2Location).start, start2Index);
165 }
166