1//===-- RemoveUsingNamespaceTest.cpp ----------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "TweakTesting.h"
10#include "gmock/gmock-matchers.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
13
14namespace clang {
15namespace clangd {
16namespace {
17
18TWEAK_TEST(RemoveUsingNamespace);
19
20TEST_F(RemoveUsingNamespaceTest, All) {
21 std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
22 {// Remove all occurrences of ns. Qualify only unqualified.
23 R"cpp(
24 namespace ns1 { struct vector {}; }
25 namespace ns2 { struct map {}; }
26 using namespace n^s1;
27 using namespace ns2;
28 using namespace ns1;
29 int main() {
30 ns1::vector v1;
31 vector v2;
32 map m1;
33 }
34 )cpp",
35 R"cpp(
36 namespace ns1 { struct vector {}; }
37 namespace ns2 { struct map {}; }
38
39 using namespace ns2;
40
41 int main() {
42 ns1::vector v1;
43 ns1::vector v2;
44 map m1;
45 }
46 )cpp"},
47 {// Ident to be qualified is a macro arg.
48 R"cpp(
49 #define DECLARE(x, y) x y
50 namespace ns { struct vector {}; }
51 using namespace n^s;
52 int main() {
53 DECLARE(ns::vector, v1);
54 DECLARE(vector, v2);
55 }
56 )cpp",
57 R"cpp(
58 #define DECLARE(x, y) x y
59 namespace ns { struct vector {}; }
60
61 int main() {
62 DECLARE(ns::vector, v1);
63 DECLARE(ns::vector, v2);
64 }
65 )cpp"},
66 {// Nested namespace: Fully qualify ident from inner ns.
67 R"cpp(
68 namespace aa { namespace bb { struct map {}; }}
69 using namespace aa::b^b;
70 int main() {
71 map m;
72 }
73 )cpp",
74 R"cpp(
75 namespace aa { namespace bb { struct map {}; }}
76
77 int main() {
78 aa::bb::map m;
79 }
80 )cpp"},
81 {// Nested namespace: Fully qualify ident from inner ns.
82 R"cpp(
83 namespace aa { namespace bb { struct map {}; }}
84 using namespace a^a;
85 int main() {
86 bb::map m;
87 }
88 )cpp",
89 R"cpp(
90 namespace aa { namespace bb { struct map {}; }}
91
92 int main() {
93 aa::bb::map m;
94 }
95 )cpp"},
96 {// Typedef.
97 R"cpp(
98 namespace aa { namespace bb { struct map {}; }}
99 using namespace a^a;
100 typedef bb::map map;
101 int main() { map M; }
102 )cpp",
103 R"cpp(
104 namespace aa { namespace bb { struct map {}; }}
105
106 typedef aa::bb::map map;
107 int main() { map M; }
108 )cpp"},
109 {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
110 R"cpp(
111 namespace aa { namespace bb { struct map {}; }}
112 using name[[space aa::b]]b;
113 using namespace aa;
114 int main() {
115 map m;
116 }
117 )cpp",
118 R"cpp(
119 namespace aa { namespace bb { struct map {}; }}
120
121 using namespace aa;
122 int main() {
123 aa::bb::map m;
124 }
125 )cpp"},
126 {// Does not qualify ident from inner namespace.
127 R"cpp(
128 namespace aa { namespace bb { struct map {}; }}
129 using namespace aa::bb;
130 using namespace a^a;
131 int main() {
132 map m;
133 }
134 )cpp",
135 R"cpp(
136 namespace aa { namespace bb { struct map {}; }}
137 using namespace aa::bb;
138
139 int main() {
140 map m;
141 }
142 )cpp"},
143 {// Available only for top level namespace decl.
144 R"cpp(
145 namespace aa {
146 namespace bb { struct map {}; }
147 using namespace b^b;
148 }
149 int main() { aa::map m; }
150 )cpp",
151 "unavailable"},
152 {// FIXME: Unavailable for namespaces containing using-namespace decl.
153 R"cpp(
154 namespace aa {
155 namespace bb { struct map {}; }
156 using namespace bb;
157 }
158 using namespace a^a;
159 int main() {
160 map m;
161 }
162 )cpp",
163 "unavailable"},
164 {R"cpp(
165 namespace a::b { struct Foo {}; }
166 using namespace a;
167 using namespace a::[[b]];
168 using namespace b;
169 int main() { Foo F;}
170 )cpp",
171 R"cpp(
172 namespace a::b { struct Foo {}; }
173 using namespace a;
174
175
176 int main() { a::b::Foo F;}
177 )cpp"},
178 {R"cpp(
179 namespace a::b { struct Foo {}; }
180 using namespace a;
181 using namespace a::b;
182 using namespace [[b]];
183 int main() { Foo F;}
184 )cpp",
185 R"cpp(
186 namespace a::b { struct Foo {}; }
187 using namespace a;
188
189
190 int main() { b::Foo F;}
191 )cpp"},
192 {// Enumerators.
193 R"cpp(
194 namespace tokens {
195 enum Token {
196 comma, identifier, numeric
197 };
198 }
199 using namespace tok^ens;
200 int main() {
201 auto x = comma;
202 }
203 )cpp",
204 R"cpp(
205 namespace tokens {
206 enum Token {
207 comma, identifier, numeric
208 };
209 }
210
211 int main() {
212 auto x = tokens::comma;
213 }
214 )cpp"},
215 {// inline namespaces.
216 R"cpp(
217 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
218 using namespace st^d;
219 int main() {
220 vector V;
221 }
222 )cpp",
223 R"cpp(
224 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
225
226 int main() {
227 std::vector V;
228 }
229 )cpp"},
230 {// Does not qualify operators declared in a non-class context
231 R"cpp(
232 namespace ns {
233 struct Foo {};
234 void operator+(const Foo &, int) {}
235 }
236 using namespace n^s;
237 int main() {
238 Foo foo;
239 foo + 10;
240 }
241 )cpp",
242 R"cpp(
243 namespace ns {
244 struct Foo {};
245 void operator+(const Foo &, int) {}
246 }
247
248 int main() {
249 ns::Foo foo;
250 foo + 10;
251 }
252 )cpp"},
253 {// Does not qualify user-defined literals
254 R"cpp(
255 namespace ns {
256 long double operator "" _w(long double);
257 }
258 using namespace n^s;
259 int main() { 1.5_w; }
260 )cpp",
261 R"cpp(
262 namespace ns {
263 long double operator "" _w(long double);
264 }
265
266 int main() { 1.5_w; }
267 )cpp"},
268 {
269 R"cpp(
270 namespace a { inline namespace b { void foobar(); } }
271 using namespace a::[[b]];
272 int main() { foobar(); }
273 )cpp",
274 R"cpp(
275 namespace a { inline namespace b { void foobar(); } }
276
277 int main() { a::b::foobar(); }
278 )cpp"}};
279 for (auto C : Cases)
280 EXPECT_EQ(C.second, apply(C.first)) << C.first;
281}
282
283} // namespace
284} // namespace clangd
285} // namespace clang
286

source code of clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp