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 "TestTU.h"
10 #include "TweakTesting.h"
11 #include "gmock/gmock-matchers.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14
15 namespace clang {
16 namespace clangd {
17 namespace {
18
19 TWEAK_TEST(RemoveUsingNamespace);
20
TEST_F(RemoveUsingNamespaceTest,All)21 TEST_F(RemoveUsingNamespaceTest, All) {
22 std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = {
23 {// Remove all occurrences of ns. Qualify only unqualified.
24 R"cpp(
25 namespace ns1 { struct vector {}; }
26 namespace ns2 { struct map {}; }
27 using namespace n^s1;
28 using namespace ns2;
29 using namespace ns1;
30 int main() {
31 ns1::vector v1;
32 vector v2;
33 map m1;
34 }
35 )cpp",
36 R"cpp(
37 namespace ns1 { struct vector {}; }
38 namespace ns2 { struct map {}; }
39
40 using namespace ns2;
41
42 int main() {
43 ns1::vector v1;
44 ns1::vector v2;
45 map m1;
46 }
47 )cpp"},
48 {// Ident to be qualified is a macro arg.
49 R"cpp(
50 #define DECLARE(x, y) x y
51 namespace ns { struct vector {}; }
52 using namespace n^s;
53 int main() {
54 DECLARE(ns::vector, v1);
55 DECLARE(vector, v2);
56 }
57 )cpp",
58 R"cpp(
59 #define DECLARE(x, y) x y
60 namespace ns { struct vector {}; }
61
62 int main() {
63 DECLARE(ns::vector, v1);
64 DECLARE(ns::vector, v2);
65 }
66 )cpp"},
67 {// Nested namespace: Fully qualify ident from inner ns.
68 R"cpp(
69 namespace aa { namespace bb { struct map {}; }}
70 using namespace aa::b^b;
71 int main() {
72 map m;
73 }
74 )cpp",
75 R"cpp(
76 namespace aa { namespace bb { struct map {}; }}
77
78 int main() {
79 aa::bb::map m;
80 }
81 )cpp"},
82 {// Nested namespace: Fully qualify ident from inner ns.
83 R"cpp(
84 namespace aa { namespace bb { struct map {}; }}
85 using namespace a^a;
86 int main() {
87 bb::map m;
88 }
89 )cpp",
90 R"cpp(
91 namespace aa { namespace bb { struct map {}; }}
92
93 int main() {
94 aa::bb::map m;
95 }
96 )cpp"},
97 {// Typedef.
98 R"cpp(
99 namespace aa { namespace bb { struct map {}; }}
100 using namespace a^a;
101 typedef bb::map map;
102 int main() { map M; }
103 )cpp",
104 R"cpp(
105 namespace aa { namespace bb { struct map {}; }}
106
107 typedef aa::bb::map map;
108 int main() { map M; }
109 )cpp"},
110 {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns.
111 R"cpp(
112 namespace aa { namespace bb { struct map {}; }}
113 using name[[space aa::b]]b;
114 using namespace aa;
115 int main() {
116 map m;
117 }
118 )cpp",
119 R"cpp(
120 namespace aa { namespace bb { struct map {}; }}
121
122 using namespace aa;
123 int main() {
124 aa::bb::map m;
125 }
126 )cpp"},
127 {// Does not qualify ident from inner namespace.
128 R"cpp(
129 namespace aa { namespace bb { struct map {}; }}
130 using namespace aa::bb;
131 using namespace a^a;
132 int main() {
133 map m;
134 }
135 )cpp",
136 R"cpp(
137 namespace aa { namespace bb { struct map {}; }}
138 using namespace aa::bb;
139
140 int main() {
141 map m;
142 }
143 )cpp"},
144 {// Available only for top level namespace decl.
145 R"cpp(
146 namespace aa {
147 namespace bb { struct map {}; }
148 using namespace b^b;
149 }
150 int main() { aa::map m; }
151 )cpp",
152 "unavailable"},
153 {// FIXME: Unavailable for namespaces containing using-namespace decl.
154 R"cpp(
155 namespace aa {
156 namespace bb { struct map {}; }
157 using namespace bb;
158 }
159 using namespace a^a;
160 int main() {
161 map m;
162 }
163 )cpp",
164 "unavailable"},
165 {R"cpp(
166 namespace a::b { struct Foo {}; }
167 using namespace a;
168 using namespace a::[[b]];
169 using namespace b;
170 int main() { Foo F;}
171 )cpp",
172 R"cpp(
173 namespace a::b { struct Foo {}; }
174 using namespace a;
175
176
177 int main() { a::b::Foo F;}
178 )cpp"},
179 {R"cpp(
180 namespace a::b { struct Foo {}; }
181 using namespace a;
182 using namespace a::b;
183 using namespace [[b]];
184 int main() { Foo F;}
185 )cpp",
186 R"cpp(
187 namespace a::b { struct Foo {}; }
188 using namespace a;
189
190
191 int main() { b::Foo F;}
192 )cpp"},
193 {// Enumerators.
194 R"cpp(
195 namespace tokens {
196 enum Token {
197 comma, identifier, numeric
198 };
199 }
200 using namespace tok^ens;
201 int main() {
202 auto x = comma;
203 }
204 )cpp",
205 R"cpp(
206 namespace tokens {
207 enum Token {
208 comma, identifier, numeric
209 };
210 }
211
212 int main() {
213 auto x = tokens::comma;
214 }
215 )cpp"},
216 {// inline namespaces.
217 R"cpp(
218 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
219 using namespace st^d;
220 int main() {
221 vector V;
222 }
223 )cpp",
224 R"cpp(
225 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}}
226
227 int main() {
228 std::vector V;
229 }
230 )cpp"}};
231 for (auto C : Cases)
232 EXPECT_EQ(C.second, apply(C.first)) << C.first;
233 }
234
235 } // namespace
236 } // namespace clangd
237 } // namespace clang
238