blob: 726e9dce455152e746e473aac485741f6314df14 [file] [log] [blame]
Eric Liu495b2112016-09-19 17:40:32 +00001//===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ChangeNamespace.h"
11#include "unittests/Tooling/RewriterTestContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/Basic/FileManager.h"
14#include "clang/Basic/FileSystemOptions.h"
15#include "clang/Basic/VirtualFileSystem.h"
16#include "clang/Format/Format.h"
17#include "clang/Frontend/CompilerInstance.h"
18#include "clang/Frontend/PCHContainerOperations.h"
19#include "clang/Tooling/Refactoring.h"
20#include "clang/Tooling/Tooling.h"
21#include "llvm/ADT/IntrusiveRefCntPtr.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/MemoryBuffer.h"
24#include "gtest/gtest.h"
25#include <memory>
26#include <string>
27#include <vector>
28
29namespace clang {
30namespace change_namespace {
31namespace {
32
33class ChangeNamespaceTest : public ::testing::Test {
34public:
35 std::string runChangeNamespaceOnCode(llvm::StringRef Code) {
36 clang::RewriterTestContext Context;
37 clang::FileID ID = Context.createInMemoryFile(FileName, Code);
38
39 std::map<std::string, tooling::Replacements> FileToReplacements;
40 change_namespace::ChangeNamespaceTool NamespaceTool(
41 OldNamespace, NewNamespace, FilePattern, &FileToReplacements);
42 ast_matchers::MatchFinder Finder;
43 NamespaceTool.registerMatchers(&Finder);
44 std::unique_ptr<tooling::FrontendActionFactory> Factory =
45 tooling::newFrontendActionFactory(&Finder);
Eric Liuff51f012016-11-16 16:54:53 +000046 if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, {"-std=c++11"},
47 FileName))
48 return "";
Eric Liu495b2112016-09-19 17:40:32 +000049 formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite);
50 return format(Context.getRewrittenText(ID));
51 }
52
53 std::string format(llvm::StringRef Code) {
54 tooling::Replacements Replaces = format::reformat(
55 format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())});
56 auto ChangedCode = tooling::applyAllReplacements(Code, Replaces);
57 EXPECT_TRUE(static_cast<bool>(ChangedCode));
58 if (!ChangedCode) {
59 llvm::errs() << llvm::toString(ChangedCode.takeError());
60 return "";
61 }
62 return *ChangedCode;
63 }
64
65protected:
66 std::string FileName = "input.cc";
67 std::string OldNamespace = "na::nb";
68 std::string NewNamespace = "x::y";
69 std::string FilePattern = "input.cc";
70};
71
72TEST_F(ChangeNamespaceTest, NoMatchingNamespace) {
73 std::string Code = "namespace na {\n"
74 "namespace nx {\n"
75 "class A {};\n"
76 "} // namespace nx\n"
77 "} // namespace na\n";
78 std::string Expected = "namespace na {\n"
79 "namespace nx {\n"
80 "class A {};\n"
81 "} // namespace nx\n"
82 "} // namespace na\n";
83 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
84}
85
86TEST_F(ChangeNamespaceTest, SimpleMoveWithoutTypeRefs) {
87 std::string Code = "namespace na {\n"
88 "namespace nb {\n"
89 "class A {};\n"
90 "} // namespace nb\n"
91 "} // namespace na\n";
92 std::string Expected = "\n\n"
93 "namespace x {\n"
94 "namespace y {\n"
95 "class A {};\n"
96 "} // namespace y\n"
97 "} // namespace x\n";
98 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
99}
100
Eric Liu6aa94162016-11-10 18:29:01 +0000101TEST_F(ChangeNamespaceTest, NewNsNestedInOldNs) {
102 NewNamespace = "na::nb::nc";
103 std::string Code = "namespace na {\n"
104 "namespace nb {\n"
105 "class A {};\n"
106 "} // namespace nb\n"
107 "} // namespace na\n";
108 std::string Expected = "namespace na {\n"
109 "namespace nb {\n"
110 "namespace nc {\n"
111 "class A {};\n"
112 "} // namespace nc\n"
113 "\n"
114 "} // namespace nb\n"
115 "} // namespace na\n";
116 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
117}
118
119TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithRefs) {
120 NewNamespace = "na::nb::nc";
121 std::string Code = "namespace na {\n"
122 "class A {};\n"
123 "namespace nb {\n"
124 "class B {};\n"
125 "class C {};\n"
126 "void f() { A a; B b; }\n"
127 "} // namespace nb\n"
128 "} // namespace na\n";
129 std::string Expected = "namespace na {\n"
130 "class A {};\n"
131 "namespace nb {\n"
132 "namespace nc {\n"
133 "class B {};\n"
134 "class C {};\n"
135 "void f() { A a; B b; }\n"
136 "} // namespace nc\n"
137 "\n"
138 "} // namespace nb\n"
139 "} // namespace na\n";
140 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
141}
142
Eric Liu495b2112016-09-19 17:40:32 +0000143TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) {
144 NewNamespace = "na::nc";
145 std::string Code = "namespace na {\n"
146 "namespace nb {\n"
147 "class A {};\n"
148 "} // namespace nb\n"
149 "} // namespace na\n";
150 std::string Expected = "namespace na {\n"
151 "\n"
152 "namespace nc {\n"
153 "class A {};\n"
154 "} // namespace nc\n"
155 "} // namespace na\n";
156 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
157}
158
Eric Liu447164d2016-10-05 15:52:39 +0000159TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) {
160 NewNamespace = "na::nc";
161 std::string Code = "namespace na {\n"
162 "class A {};\n"
163 "namespace nb {\n"
164 "class X { A a; };\n"
165 "} // namespace nb\n"
166 "} // namespace na\n";
167 std::string Expected = "namespace na {\n"
168 "class A {};\n"
169 "\n"
170 "namespace nc {\n"
171 "class X { A a; };\n"
172 "} // namespace nc\n"
173 "} // namespace na\n";
174 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
175}
176
Eric Liu97f87ad2016-12-07 20:08:02 +0000177TEST_F(ChangeNamespaceTest, MoveIntoExistingNamespaceAndShortenRefs) {
178 std::string Code = "namespace x {\n"
179 "namespace z {\n"
180 "class Z {};\n"
181 "} // namespace z\n"
182 "namespace y {\n"
183 "class T {};\n"
184 "} // namespace y\n"
185 "} // namespace x\n"
186 "namespace na {\n"
187 "class A{};\n"
188 "namespace nb {\n"
189 "class X { A a; x::z::Z zz; x::y::T t; };\n"
190 "} // namespace nb\n"
191 "} // namespace na\n";
192 std::string Expected = "namespace x {\n"
193 "namespace z {\n"
194 "class Z {};\n"
195 "} // namespace z\n"
196 "namespace y {\n"
197 "class T {};\n"
198 "} // namespace y\n"
199 "} // namespace x\n"
200 "namespace na {\n"
201 "class A {};\n\n"
202 "} // namespace na\n"
203 "namespace x {\n"
204 "namespace y {\n"
205 "class X { ::na::A a; z::Z zz; T t; };\n"
206 "} // namespace y\n"
207 "} // namespace x\n";
208 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
209}
210
Eric Liu495b2112016-09-19 17:40:32 +0000211TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
212 NewNamespace = "na::x::y";
213 std::string Code = "namespace na {\n"
214 "class A {};\n"
215 "namespace nb {\n"
216 "class B {};\n"
217 "} // namespace nb\n"
218 "} // namespace na\n";
219 std::string Expected = "namespace na {\n"
220 "class A {};\n"
221 "\n"
222 "namespace x {\n"
223 "namespace y {\n"
224 "class B {};\n"
225 "} // namespace y\n"
226 "} // namespace x\n"
227 "} // namespace na\n";
228 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
229}
230
231TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) {
232 std::string Code = "namespace na {\n"
233 "class C_A {};\n"
234 "namespace nc {\n"
235 "class C_C {};"
236 "} // namespace nc\n"
237 "namespace nb {\n"
238 "class C_X {\n"
239 "public:\n"
240 " C_A a;\n"
241 " nc::C_C c;\n"
242 "};\n"
243 "class C_Y {\n"
244 " C_X x;\n"
245 "};\n"
246 "} // namespace nb\n"
247 "} // namespace na\n";
248 std::string Expected = "namespace na {\n"
249 "class C_A {};\n"
250 "namespace nc {\n"
251 "class C_C {};"
252 "} // namespace nc\n"
253 "\n"
254 "} // namespace na\n"
255 "namespace x {\n"
256 "namespace y {\n"
257 "class C_X {\n"
258 "public:\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000259 " ::na::C_A a;\n"
260 " ::na::nc::C_C c;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000261 "};\n"
262 "class C_Y {\n"
263 " C_X x;\n"
264 "};\n"
265 "} // namespace y\n"
266 "} // namespace x\n";
267 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
268}
269
Eric Liu8393cb02016-10-31 08:28:29 +0000270TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) {
271 std::string Code = "namespace na {\n"
272 "class A {};\n"
273 "template <typename T>\n"
274 "class B {};\n"
275 "template <typename T1, typename T2>\n"
276 "class Two {};\n"
277 "namespace nc { class C {}; }\n"
278 "} // na\n"
279 "\n"
280 "namespace na {\n"
281 "namespace nb {\n"
282 "void f() {\n"
283 " B<A> b;\n"
284 " B<nc::C> b_c;\n"
285 " Two<A, nc::C> two;\n"
286 "}\n"
287 "} // nb\n"
288 "} // na\n";
289 std::string Expected = "namespace na {\n"
290 "class A {};\n"
291 "template <typename T>\n"
292 "class B {};\n"
293 "template <typename T1, typename T2>\n"
294 "class Two {};\n"
295 "namespace nc { class C {}; }\n"
296 "} // na\n"
297 "\n"
298 "\n"
299 "namespace x {\n"
300 "namespace y {\n"
301 "void f() {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000302 " ::na::B<::na::A> b;\n"
303 " ::na::B<::na::nc::C> b_c;\n"
304 " ::na::Two<::na::A, ::na::nc::C> two;\n"
Eric Liu8393cb02016-10-31 08:28:29 +0000305 "}\n"
306 "} // namespace y\n"
307 "} // namespace x\n";
308 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
309}
310
Eric Liu495b2112016-09-19 17:40:32 +0000311TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) {
312 std::string Code = "namespace na {\n"
313 "namespace nb {\n"
314 "class FWD;\n"
Eric Liu41552d62016-12-07 14:20:52 +0000315 "class FWD2;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000316 "class A {\n"
317 " FWD *fwd;\n"
318 "};\n"
319 "} // namespace nb\n"
320 "} // namespace na\n";
321 std::string Expected = "namespace na {\n"
322 "namespace nb {\n"
323 "class FWD;\n"
Eric Liu41552d62016-12-07 14:20:52 +0000324 "class FWD2;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000325 "} // namespace nb\n"
326 "} // namespace na\n"
327 "namespace x {\n"
328 "namespace y {\n"
329 "\n"
330 "class A {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000331 " ::na::nb::FWD *fwd;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000332 "};\n"
333 "} // namespace y\n"
334 "} // namespace x\n";
335 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
336}
337
Eric Liu41552d62016-12-07 14:20:52 +0000338TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) {
339 std::string Code = "namespace na {\n"
340 "namespace nb {\n"
341 "class FWD;\n"
342 "template<typename T> class FWD_TEMP;\n"
343 "class A {\n"
344 " FWD *fwd;\n"
345 "};\n"
346 "template<typename T> class TEMP {};\n"
347 "} // namespace nb\n"
348 "} // namespace na\n";
349 std::string Expected = "namespace na {\n"
350 "namespace nb {\n"
351 "class FWD;\n"
352 "template<typename T> class FWD_TEMP;\n"
353 "} // namespace nb\n"
354 "} // namespace na\n"
355 "namespace x {\n"
356 "namespace y {\n"
357 "\n"
358 "class A {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000359 " ::na::nb::FWD *fwd;\n"
Eric Liu41552d62016-12-07 14:20:52 +0000360 "};\n"
361 "template<typename T> class TEMP {};\n"
362 "} // namespace y\n"
363 "} // namespace x\n";
364 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
365}
366
367TEST_F(ChangeNamespaceTest, DontMoveForwardDeclarationInClass) {
368 std::string Code = "namespace na {\n"
369 "namespace nb {\n"
370 "class A {\n"
371 " class FWD;\n"
372 " FWD *fwd;\n"
373 " template<typename T> class FWD_TEMP;\n"
374 "};\n"
375 "} // namespace nb\n"
376 "} // namespace na\n";
377 std::string Expected = "\n\n"
378 "namespace x {\n"
379 "namespace y {\n"
380 "class A {\n"
381 " class FWD;\n"
382 " FWD *fwd;\n"
383 " template<typename T> class FWD_TEMP;\n"
384 "};\n"
385 "} // namespace y\n"
386 "} // namespace x\n";
387 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
388}
389
Eric Liu495b2112016-09-19 17:40:32 +0000390TEST_F(ChangeNamespaceTest, MoveFunctions) {
391 std::string Code = "namespace na {\n"
392 "class C_A {};\n"
393 "namespace nc {\n"
394 "class C_C {};"
395 "} // namespace nc\n"
396 "namespace nb {\n"
397 "void fwd();\n"
398 "void f(C_A ca, nc::C_C cc) {\n"
399 " C_A ca_1 = ca;\n"
400 "}\n"
401 "} // namespace nb\n"
402 "} // namespace na\n";
403
404 std::string Expected = "namespace na {\n"
405 "class C_A {};\n"
406 "namespace nc {\n"
407 "class C_C {};"
408 "} // namespace nc\n"
409 "\n"
410 "} // namespace na\n"
411 "namespace x {\n"
412 "namespace y {\n"
413 "void fwd();\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000414 "void f(::na::C_A ca, ::na::nc::C_C cc) {\n"
415 " ::na::C_A ca_1 = ca;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000416 "}\n"
417 "} // namespace y\n"
418 "} // namespace x\n";
419 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
420}
421
Eric Liu68765a82016-09-21 15:06:12 +0000422TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) {
Eric Liu912d0392016-09-27 12:54:48 +0000423 std::string Code = "class GLOB {};\n"
424 "using BLOG = GLOB;\n"
425 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000426 "namespace nc {\n"
427 "class SAME {};\n"
428 "}\n"
429 "namespace nd {\n"
430 "class SAME {};\n"
431 "}\n"
432 "namespace nb {\n"
433 "using nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000434 "using YO = nd::SAME;\n"
435 "typedef nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000436 "void f(nd::SAME Same) {}\n"
437 "} // namespace nb\n"
438 "} // namespace na\n";
439
Eric Liu912d0392016-09-27 12:54:48 +0000440 std::string Expected = "class GLOB {};\n"
441 "using BLOG = GLOB;\n"
442 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000443 "namespace nc {\n"
444 "class SAME {};\n"
445 "}\n"
446 "namespace nd {\n"
447 "class SAME {};\n"
448 "}\n"
449 "\n"
450 "} // namespace na\n"
451 "namespace x {\n"
452 "namespace y {\n"
453 "using ::na::nc::SAME;\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000454 "using YO = ::na::nd::SAME;\n"
455 "typedef ::na::nd::SAME IDENTICAL;\n"
456 "void f(::na::nd::SAME Same) {}\n"
Eric Liu68765a82016-09-21 15:06:12 +0000457 "} // namespace y\n"
458 "} // namespace x\n";
459 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
460}
461
Eric Liu8685c762016-12-07 17:04:07 +0000462TEST_F(ChangeNamespaceTest, DontFixUsingShadowDeclInClasses) {
463 std::string Code = "namespace na {\n"
464 "class A {};\n"
465 "class Base { public: Base() {} void m() {} };\n"
466 "namespace nb {\n"
467 "class D : public Base {\n"
468 "public:\n"
469 " using AA = A; using B = Base;\n"
470 " using Base::m; using Base::Base;\n"
471 "};"
472 "} // namespace nb\n"
473 "} // namespace na\n";
474
475 std::string Expected = "namespace na {\n"
476 "class A {};\n"
477 "class Base { public: Base() {} void m() {} };\n"
478 "\n"
479 "} // namespace na\n"
480 "namespace x {\n"
481 "namespace y {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000482 "class D : public ::na::Base {\n"
Eric Liu8685c762016-12-07 17:04:07 +0000483 "public:\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000484 " using AA = ::na::A; using B = ::na::Base;\n"
Eric Liu8685c762016-12-07 17:04:07 +0000485 " using Base::m; using Base::Base;\n"
486 "};"
487 "} // namespace y\n"
488 "} // namespace x\n";
489 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
490}
491
Eric Liu68765a82016-09-21 15:06:12 +0000492TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) {
493 std::string Code =
494 "namespace na {\n"
495 "class C_A {\n"
496 "public:\n"
497 " class Nested {\n"
498 " public:\n"
499 " static int NestedX;\n"
500 " static void nestedFunc() {}\n"
501 " };\n"
502 "};\n"
503 "namespace nb {\n"
504 "class C_X {\n"
505 " C_A na;\n"
506 " C_A::Nested nested;\n"
507 " void f() {\n"
508 " C_A::Nested::nestedFunc();\n"
509 " int X = C_A::Nested::NestedX;\n"
510 " }\n"
511 "};\n"
512 "} // namespace nb\n"
513 "} // namespace na\n";
514 std::string Expected =
515 "namespace na {\n"
516 "class C_A {\n"
517 "public:\n"
518 " class Nested {\n"
519 " public:\n"
520 " static int NestedX;\n"
521 " static void nestedFunc() {}\n"
522 " };\n"
523 "};\n"
524 "\n"
525 "} // namespace na\n"
526 "namespace x {\n"
527 "namespace y {\n"
528 "class C_X {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000529 " ::na::C_A na;\n"
530 " ::na::C_A::Nested nested;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000531 " void f() {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000532 " ::na::C_A::Nested::nestedFunc();\n"
533 " int X = ::na::C_A::Nested::NestedX;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000534 " }\n"
535 "};\n"
536 "} // namespace y\n"
537 "} // namespace x\n";
538 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
539}
540
Eric Liu12068d82016-09-22 11:54:00 +0000541TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
542 std::string Code =
543 "namespace na {\n"
544 "class A {\n"
545 "public:\n"
546 " static void f() {}\n"
547 " static void g();\n"
548 "};\n"
549 "void A::g() {}"
550 "void a_f() {}\n"
551 "static void static_f() {}\n"
552 "namespace nb {\n"
553 "void f() { a_f(); static_f(); A::f(); }\n"
554 "void g() { f(); A::g(); }\n"
555 "} // namespace nb\n"
556 "} // namespace na\n";
557 std::string Expected =
558 "namespace na {\n"
559 "class A {\n"
560 "public:\n"
561 " static void f() {}\n"
562 " static void g();\n"
563 "};\n"
564 "void A::g() {}"
565 "void a_f() {}\n"
566 "static void static_f() {}\n"
567 "\n"
568 "} // namespace na\n"
569 "namespace x {\n"
570 "namespace y {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000571 "void f() { ::na::a_f(); ::na::static_f(); ::na::A::f(); }\n"
572 "void g() { f(); ::na::A::g(); }\n"
Eric Liu12068d82016-09-22 11:54:00 +0000573 "} // namespace y\n"
574 "} // namespace x\n";
575 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
576}
577
Eric Liue3f35e42016-12-20 14:39:04 +0000578TEST_F(ChangeNamespaceTest, FixOverloadedOperatorFunctionNameSpecifiers) {
579 std::string Code =
580 "namespace na {\n"
581 "class A {\n"
582 "public:\n"
583 " int x;\n"
584 " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
585 "};\n"
586 "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
587 "namespace nb {\n"
588 "bool f() {\n"
589 " A x, y;\n"
590 " auto f = operator<;\n"
591 " return (x == y) && (x < y) && (operator<(x, y));\n"
592 "}\n"
593 "} // namespace nb\n"
594 "} // namespace na\n";
595 std::string Expected =
596 "namespace na {\n"
597 "class A {\n"
598 "public:\n"
599 " int x;\n"
600 " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
601 "};\n"
602 "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
603 "\n"
604 "} // namespace na\n"
605 "namespace x {\n"
606 "namespace y {\n"
607 "bool f() {\n"
608 " ::na::A x, y;\n"
609 " auto f = ::na::operator<;\n"
610 // FIXME: function calls to overloaded operators are not fixed now even if
611 // they are referenced by qualified names.
612 " return (x == y) && (x < y) && (operator<(x,y));\n"
613 "}\n"
614 "} // namespace y\n"
615 "} // namespace x\n";
616 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
617}
618
Eric Liuda22b3c2016-11-29 14:15:14 +0000619TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
620 std::string Code = "namespace na {\n"
621 "class A {\n"
622 "public:\n"
623 " static void f() {}\n"
624 "};\n"
625 "void a_f() {}\n"
626 "static void s_f() {}\n"
627 "namespace nb {\n"
628 "void f() {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000629 " auto *ref1 = A::f;\n"
630 " auto *ref2 = a_f;\n"
631 " auto *ref3 = s_f;\n"
Eric Liuda22b3c2016-11-29 14:15:14 +0000632 "}\n"
633 "} // namespace nb\n"
634 "} // namespace na\n";
635 std::string Expected =
636 "namespace na {\n"
637 "class A {\n"
638 "public:\n"
639 " static void f() {}\n"
640 "};\n"
641 "void a_f() {}\n"
642 "static void s_f() {}\n"
643 "\n"
644 "} // namespace na\n"
645 "namespace x {\n"
646 "namespace y {\n"
647 "void f() {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000648 " auto *ref1 = ::na::A::f;\n"
649 " auto *ref2 = ::na::a_f;\n"
650 " auto *ref3 = ::na::s_f;\n"
Eric Liuda22b3c2016-11-29 14:15:14 +0000651 "}\n"
652 "} // namespace y\n"
653 "} // namespace x\n";
654 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
655}
656
Eric Liu159f0132016-09-30 04:32:39 +0000657TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
658 std::string Code = "namespace na {\n"
659 "int GlobA;\n"
660 "static int GlobAStatic = 0;\n"
661 "namespace nc { int GlobC; }\n"
662 "namespace nb {\n"
663 "int GlobB;\n"
664 "void f() {\n"
665 " int a = GlobA;\n"
666 " int b = GlobAStatic;\n"
667 " int c = nc::GlobC;\n"
668 "}\n"
669 "} // namespace nb\n"
670 "} // namespace na\n";
671
672 std::string Expected = "namespace na {\n"
673 "int GlobA;\n"
674 "static int GlobAStatic = 0;\n"
675 "namespace nc { int GlobC; }\n"
676 "\n"
677 "} // namespace na\n"
678 "namespace x {\n"
679 "namespace y {\n"
680 "int GlobB;\n"
681 "void f() {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000682 " int a = ::na::GlobA;\n"
683 " int b = ::na::GlobAStatic;\n"
684 " int c = ::na::nc::GlobC;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000685 "}\n"
686 "} // namespace y\n"
687 "} // namespace x\n";
688
689 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
690}
691
692TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
693 std::string Code = "namespace na {\n"
694 "class A {\n"
695 "public:\n"
696 "static int A1;\n"
697 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000698 "};\n"
699 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000700 "namespace nb {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000701 "void f() {\n"
702 " int a = A::A1; int b = A::A2;\n"
703 "}\n"
Eric Liu159f0132016-09-30 04:32:39 +0000704 "} // namespace nb\n"
705 "} // namespace na\n";
706
707 std::string Expected = "namespace na {\n"
708 "class A {\n"
709 "public:\n"
710 "static int A1;\n"
711 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000712 "};\n"
713 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000714 "\n"
715 "} // namespace na\n"
716 "namespace x {\n"
717 "namespace y {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +0000718 "void f() {\n"
719 " int a = ::na::A::A1; int b = ::na::A::A2;\n"
720 "}\n"
Eric Liu159f0132016-09-30 04:32:39 +0000721 "} // namespace y\n"
722 "} // namespace x\n";
723
724 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
725}
726
Haojian Wuef8a6dc2016-10-04 10:35:53 +0000727TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) {
728 std::string Code = "namespace na {\n"
729 "namespace nb {\n"
730 "class A;\n"
731 "class B {};\n"
732 "}"
733 "}";
734 std::string Expected = "namespace na {\n"
735 "namespace nb {\n"
736 "class A;\n"
737 "}\n"
738 "}\n"
739 "namespace x {\n"
740 "namespace y {\n"
741 "\n"
742 "class B {};\n"
743 "} // namespace y\n"
744 "} // namespace x\n";
745 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
746}
747
Eric Liu73f49fd2016-10-12 12:34:18 +0000748TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) {
749 std::string Code = "namespace na {\n"
750 "namespace nb {\n"
751 "\n\n"
752 "// Wild comments.\n"
753 "\n"
754 "// Comments.\n"
755 "// More comments.\n"
756 "class B {\n"
757 " // Private comments.\n"
758 " int a;\n"
759 "};\n"
760 "}\n"
761 "}";
762 std::string Expected = "\n"
763 "\n"
764 "namespace x {\n"
765 "namespace y {\n"
766 "\n\n"
767 "// Wild comments.\n"
768 "\n"
769 "// Comments.\n"
770 "// More comments.\n"
771 "class B {\n"
772 " // Private comments.\n"
773 " int a;\n"
774 "};\n"
775 "} // namespace y\n"
776 "} // namespace x\n";
777 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
778}
779
Eric Liub9bf1b52016-11-08 22:44:17 +0000780TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) {
781 std::string Code = "namespace glob {\n"
782 "class Glob {};\n"
783 "}\n"
784 "using glob::Glob;\n"
785 "namespace na {\n"
786 "namespace nb {\n"
787 "void f() { Glob g; }\n"
788 "} // namespace nb\n"
789 "} // namespace na\n";
790
791 std::string Expected = "namespace glob {\n"
792 "class Glob {};\n"
793 "}\n"
794 "using glob::Glob;\n"
795 "\n"
796 "namespace x {\n"
797 "namespace y {\n"
798 "void f() { Glob g; }\n"
799 "} // namespace y\n"
800 "} // namespace x\n";
801 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
802}
803
804TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) {
805 std::string Code = "namespace glob {\n"
806 "class Glob {};\n"
807 "}\n"
808 "using namespace glob;\n"
809 "namespace na {\n"
810 "namespace nb {\n"
811 "void f() { Glob g; }\n"
812 "} // namespace nb\n"
813 "} // namespace na\n";
814
815 std::string Expected = "namespace glob {\n"
816 "class Glob {};\n"
817 "}\n"
818 "using namespace glob;\n"
819 "\n"
820 "namespace x {\n"
821 "namespace y {\n"
822 "void f() { Glob g; }\n"
823 "} // namespace y\n"
824 "} // namespace x\n";
825 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
826}
827
Eric Liu180dac62016-12-23 10:47:09 +0000828TEST_F(ChangeNamespaceTest, NamespaceAliasInGlobal) {
829 std::string Code = "namespace glob {\n"
830 "class Glob {};\n"
831 "}\n"
832 "namespace glob2 { class Glob2 {}; }\n"
833 "namespace gl = glob;\n"
834 "namespace gl2 = ::glob2;\n"
835 "namespace na {\n"
836 "namespace nb {\n"
837 "void f() { gl::Glob g; gl2::Glob2 g2; }\n"
838 "} // namespace nb\n"
839 "} // namespace na\n";
840
841 std::string Expected =
842 "namespace glob {\n"
843 "class Glob {};\n"
844 "}\n"
845 "namespace glob2 { class Glob2 {}; }\n"
846 "namespace gl = glob;\n"
847 "namespace gl2 = ::glob2;\n"
848 "\n"
849 "namespace x {\n"
850 "namespace y {\n"
851 "void f() { gl::Glob g; gl2::Glob2 g2; }\n"
852 "} // namespace y\n"
853 "} // namespace x\n";
854 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
855}
856
857TEST_F(ChangeNamespaceTest, NamespaceAliasInNamespace) {
858 std::string Code = "namespace glob {\n"
859 "class Glob {};\n"
860 "}\n"
861 "namespace na {\n"
862 "namespace nb {\n"
863 "namespace gl = glob;\n"
864 "void f() { gl::Glob g; }\n"
865 "} // namespace nb\n"
866 "} // namespace na\n";
867
868 std::string Expected = "namespace glob {\n"
869 "class Glob {};\n"
870 "}\n"
871 "\n"
872 "namespace x {\n"
873 "namespace y {\n"
874 "namespace gl = glob;\n"
875 "void f() { gl::Glob g; }\n"
876 "} // namespace y\n"
877 "} // namespace x\n";
878 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
879}
880
881TEST_F(ChangeNamespaceTest, NamespaceAliasInAncestorNamespace) {
882 NewNamespace = "na::nx";
883 std::string Code = "namespace glob {\n"
884 "class Glob {};\n"
885 "}\n"
886 "namespace other { namespace gl = glob; }\n"
887 "namespace na {\n"
888 "namespace ga = glob;\n"
889 "namespace nb {\n"
890 "void f() { ga::Glob g; }\n"
891 "} // namespace nb\n"
892 "} // namespace na\n";
893
894 std::string Expected = "namespace glob {\n"
895 "class Glob {};\n"
896 "}\n"
897 "namespace other { namespace gl = glob; }\n"
898 "namespace na {\n"
899 "namespace ga = glob;\n"
900 "\n"
901 "namespace nx {\n"
902 "void f() { ga::Glob g; }\n"
903 "} // namespace nx\n"
904 "} // namespace na\n";
905 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
906}
907
908TEST_F(ChangeNamespaceTest, NamespaceAliasInOtherNamespace) {
909 std::string Code = "namespace glob {\n"
910 "class Glob {};\n"
911 "}\n"
912 "namespace other { namespace gl = glob; }\n"
913 "namespace na {\n"
914 "namespace ga = glob;\n"
915 "namespace nb {\n"
916 "void f() { glob::Glob g; }\n"
917 "} // namespace nb\n"
918 "} // namespace na\n";
919
920 std::string Expected = "namespace glob {\n"
921 "class Glob {};\n"
922 "}\n"
923 "namespace other { namespace gl = glob; }\n"
924 "namespace na {\n"
925 "namespace ga = glob;\n"
926 "\n"
927 "} // namespace na\n"
928 "namespace x {\n"
929 "namespace y {\n"
930 "void f() { glob::Glob g; }\n"
931 "} // namespace y\n"
932 "} // namespace x\n";
933 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
934}
935
Eric Liub9bf1b52016-11-08 22:44:17 +0000936TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) {
937 std::string Code = "namespace glob {\n"
938 "class Glob {};\n"
939 "}\n"
940 "namespace na {\n"
941 "namespace nb {\n"
942 "void f() { glob::Glob g; }\n"
943 "} // namespace nb\n"
944 "} // namespace na\n"
945 "using glob::Glob;\n"
946 "using namespace glob;\n";
947
948 std::string Expected = "namespace glob {\n"
949 "class Glob {};\n"
950 "}\n"
951 "\n"
952 "namespace x {\n"
953 "namespace y {\n"
954 "void f() { glob::Glob g; }\n"
955 "} // namespace y\n"
956 "} // namespace x\n"
957 "using glob::Glob;\n"
958 "using namespace glob;\n";
959 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
960}
961
962TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) {
963 NewNamespace = "na::nc";
964 std::string Code = "namespace glob {\n"
965 "class Glob {};\n"
966 "}\n"
967 "namespace na {\n"
968 "namespace nb {\n"
969 "void f() { glob::Glob g; }\n"
970 "} // namespace nb\n"
971 "using namespace glob;\n"
972 "} // namespace na\n";
973
974 std::string Expected = "namespace glob {\n"
975 "class Glob {};\n"
976 "}\n"
977 "namespace na {\n"
978 "\n"
979 "namespace nc {\n"
980 "void f() { glob::Glob g; }\n"
981 "} // namespace nc\n"
982 "using namespace glob;\n"
983 "} // namespace na\n";
984 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
985}
986
987TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) {
988 std::string Code = "namespace glob1 {\n"
989 "namespace glob2 {\n"
990 "class Glob {};\n"
991 "}\n"
992 "}\n"
993 "using glob1::glob2::Glob;\n"
994 "using namespace glob1;\n"
995 "namespace na {\n"
996 "namespace nb {\n"
997 "void f() { Glob g; }\n"
998 "} // namespace nb\n"
999 "} // namespace na\n";
1000
1001 std::string Expected = "namespace glob1 {\n"
1002 "namespace glob2 {\n"
1003 "class Glob {};\n"
1004 "}\n"
1005 "}\n"
1006 "using glob1::glob2::Glob;\n"
1007 "using namespace glob1;\n"
1008 "\n"
1009 "namespace x {\n"
1010 "namespace y {\n"
1011 "void f() { Glob g; }\n"
1012 "} // namespace y\n"
1013 "} // namespace x\n";
1014 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1015}
1016
1017TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) {
1018 std::string Code = "namespace glob {\n"
1019 "class Glob {};\n"
1020 "}\n"
1021 "using GLB = glob::Glob;\n"
1022 "using BLG = glob::Glob;\n"
1023 "namespace na {\n"
1024 "namespace nb {\n"
1025 "void f() { GLB g; BLG blg; }\n"
1026 "} // namespace nb\n"
1027 "} // namespace na\n";
1028
1029 std::string Expected = "namespace glob {\n"
1030 "class Glob {};\n"
1031 "}\n"
1032 "using GLB = glob::Glob;\n"
1033 "using BLG = glob::Glob;\n"
1034 "\n"
1035 "namespace x {\n"
1036 "namespace y {\n"
1037 "void f() { GLB g; BLG blg; }\n"
1038 "} // namespace y\n"
1039 "} // namespace x\n";
1040 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1041}
1042
1043TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) {
1044 std::string Code = "namespace na { class C_A {};\n }\n"
1045 "using na::C_A;\n"
1046 "namespace na {\n"
1047 "namespace nb {\n"
1048 "class C_X {\n"
1049 "public:\n"
1050 " C_A a;\n"
1051 "};\n"
1052 "} // namespace nb\n"
1053 "} // namespace na\n";
1054 std::string Expected = "namespace na { class C_A {};\n }\n"
1055 "using na::C_A;\n"
1056 "\n"
1057 "namespace x {\n"
1058 "namespace y {\n"
1059 "class C_X {\n"
1060 "public:\n"
1061 " C_A a;\n"
1062 "};\n"
1063 "} // namespace y\n"
1064 "} // namespace x\n";
1065 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1066}
1067
1068TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) {
1069 std::string Code = "namespace na { class C_A {};\n }\n"
1070 "using namespace na;\n"
1071 "namespace na {\n"
1072 "namespace nb {\n"
1073 "class C_X {\n"
1074 "public:\n"
1075 " C_A ca;\n"
1076 "};\n"
1077 "} // namespace nb\n"
1078 "} // namespace na\n";
1079 std::string Expected = "namespace na { class C_A {};\n }\n"
1080 "using namespace na;\n"
1081 "\n"
1082 "namespace x {\n"
1083 "namespace y {\n"
1084 "class C_X {\n"
1085 "public:\n"
1086 " C_A ca;\n"
1087 "};\n"
1088 "} // namespace y\n"
1089 "} // namespace x\n";
1090 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1091}
1092
1093TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) {
1094 std::string Code = "namespace glob {\n"
1095 "class Glob {};\n"
1096 "}\n"
1097 "namespace na {\n"
1098 "namespace nb {\n"
1099 "void f() {\n"
1100 " using glob::Glob;\n"
1101 " Glob g;\n"
1102 "}\n"
1103 "} // namespace nb\n"
1104 "} // namespace na\n";
1105
1106 std::string Expected = "namespace glob {\n"
1107 "class Glob {};\n"
1108 "}\n"
1109 "\n"
1110 "namespace x {\n"
1111 "namespace y {\n"
1112 "void f() {\n"
1113 " using ::glob::Glob;\n"
1114 " Glob g;\n"
1115 "}\n"
1116 "} // namespace y\n"
1117 "} // namespace x\n";
1118 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1119}
1120
1121TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) {
Eric Liu32158862016-11-14 19:37:55 +00001122 std::string Code = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001123 "namespace na {\n"
1124 "namespace nb {\n"
1125 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +00001126 " using ::na::C_A;\n"
1127 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001128 "}\n"
1129 "} // namespace nb\n"
1130 "} // namespace na\n";
Eric Liu32158862016-11-14 19:37:55 +00001131 std::string Expected = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001132 "\n"
1133 "namespace x {\n"
1134 "namespace y {\n"
1135 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +00001136 " using ::na::C_A;\n"
1137 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001138 "}\n"
1139 "} // namespace y\n"
1140 "} // namespace x\n";
1141 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1142}
1143
1144TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) {
1145 std::string Code = "namespace nx { void f(); }\n"
1146 "namespace na {\n"
1147 "using nx::f;\n"
1148 "namespace nb {\n"
1149 "void d() { f(); }\n"
1150 "} // nb\n"
1151 "} // na\n";
1152
1153 std::string Expected = "namespace nx { void f(); }\n"
1154 "namespace na {\n"
1155 "using nx::f;\n"
1156 "\n"
1157 "} // na\n"
1158 "namespace x {\n"
1159 "namespace y {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +00001160 "void d() { ::nx::f(); }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001161 "} // namespace y\n"
1162 "} // namespace x\n";
1163 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1164}
1165
1166TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) {
1167 OldNamespace = "na";
1168 std::string Code = "namespace nx { void f(); }\n"
1169 "namespace na {\n"
1170 "using ::nx::f;\n"
1171 "void d() { f(); }\n"
1172 "} // na\n";
1173
1174 std::string Expected = "namespace nx { void f(); }\n"
1175 "\n"
1176 "namespace x {\n"
1177 "namespace y {\n"
1178 "using ::nx::f;\n"
1179 "void d() { f(); }\n"
1180 "} // namespace y\n"
1181 "} // namespace x\n";
1182 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1183}
1184
1185TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
1186 OldNamespace = "a::b::c::d";
1187 NewNamespace = "a::b::x::y";
1188 std::string Code = "namespace nx { void f(); void g(); }\n"
1189 "namespace a {\n"
1190 "namespace b {\n"
1191 "using ::nx::f;\n"
1192 "namespace c {\n"
1193 "using ::nx::g;\n"
1194 "namespace d {\n"
1195 "void d() { f(); g(); }\n"
1196 "} // d\n"
1197 "} // c\n"
1198 "} // b\n"
1199 "} // a\n";
1200
1201 std::string Expected = "namespace nx { void f(); void g(); }\n"
1202 "namespace a {\n"
1203 "namespace b {\n"
1204 "using ::nx::f;\n"
1205 "namespace c {\n"
1206 "using ::nx::g;\n"
1207 "\n"
1208 "} // c\n"
1209 "namespace x {\n"
1210 "namespace y {\n"
Eric Liu97f87ad2016-12-07 20:08:02 +00001211 "void d() { f(); ::nx::g(); }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +00001212 "} // namespace y\n"
1213 "} // namespace x\n"
1214 "} // b\n"
1215 "} // a\n";
1216 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1217}
1218
1219TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
1220 OldNamespace = "nb::nc";
1221 NewNamespace = "nb::nd";
1222 std::string Code = "namespace na { class A {}; }\n"
1223 "namespace nb {\n"
1224 "using na::A;\n"
1225 "namespace nc {\n"
1226 "void d() { A a; }\n"
1227 "} // nc\n"
1228 "} // nb\n";
1229
1230 std::string Expected = "namespace na { class A {}; }\n"
1231 "namespace nb {\n"
1232 "using na::A;\n"
1233 "\n"
1234 "namespace nd {\n"
1235 "void d() { A a; }\n"
1236 "} // namespace nd\n"
1237 "} // nb\n";
1238 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1239}
1240
Eric Liu32158862016-11-14 19:37:55 +00001241TEST_F(ChangeNamespaceTest, UsingAliasDecl) {
1242 std::string Code =
1243 "namespace nx { namespace ny { class X {}; } }\n"
1244 "namespace na {\n"
1245 "namespace nb {\n"
1246 "using Y = nx::ny::X;\n"
1247 "void f() { Y y; }\n"
1248 "} // namespace nb\n"
1249 "} // namespace na\n";
1250
1251 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1252 "\n"
1253 "namespace x {\n"
1254 "namespace y {\n"
1255 "using Y = nx::ny::X;\n"
1256 "void f() { Y y; }\n"
1257 "} // namespace y\n"
1258 "} // namespace x\n";
1259 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1260}
1261
1262TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) {
1263 std::string Code =
1264 "namespace nx { namespace ny { class X {}; } }\n"
1265 "using Y = nx::ny::X;\n"
1266 "namespace na {\n"
1267 "namespace nb {\n"
1268 "void f() { Y y; }\n"
1269 "} // namespace nb\n"
1270 "} // namespace na\n";
1271
1272 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1273 "using Y = nx::ny::X;\n"
1274 "\n"
1275 "namespace x {\n"
1276 "namespace y {\n"
1277 "void f() { Y y; }\n"
1278 "} // namespace y\n"
1279 "} // namespace x\n";
1280 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1281}
1282
1283
1284TEST_F(ChangeNamespaceTest, TypedefAliasDecl) {
1285 std::string Code =
1286 "namespace nx { namespace ny { class X {}; } }\n"
1287 "namespace na {\n"
1288 "namespace nb {\n"
1289 "typedef nx::ny::X Y;\n"
1290 "void f() { Y y; }\n"
1291 "} // namespace nb\n"
1292 "} // namespace na\n";
1293
1294 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1295 "\n"
1296 "namespace x {\n"
1297 "namespace y {\n"
1298 "typedef nx::ny::X Y;\n"
1299 "void f() { Y y; }\n"
1300 "} // namespace y\n"
1301 "} // namespace x\n";
1302 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1303}
1304
Eric Liuff51f012016-11-16 16:54:53 +00001305TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) {
1306 std::string Code =
1307 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1308 "namespace na {\n"
1309 "namespace nb {\n"
1310 "class A : public nx::ny::X {\n"
1311 "public:\n"
1312 " A() : X(0) {}\n"
1313 " A(int i);\n"
1314 "};\n"
1315 "A::A(int i) : X(i) {}\n"
1316 "} // namespace nb\n"
1317 "} // namespace na\n";
1318 std::string Expected =
1319 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1320 "\n\n"
1321 "namespace x {\n"
1322 "namespace y {\n"
1323 "class A : public nx::ny::X {\n"
1324 "public:\n"
1325 " A() : X(0) {}\n"
1326 " A(int i);\n"
1327 "};\n"
1328 "A::A(int i) : X(i) {}\n"
1329 "} // namespace y\n"
1330 "} // namespace x\n";
1331 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1332}
1333
1334TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) {
1335 std::string Code =
1336 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1337 "namespace na {\n"
1338 "namespace nb {\n"
1339 "class A : public nx::ny::X {\n"
1340 "public:\n"
1341 " A() : X::X(0) {}\n"
1342 " A(int i);\n"
1343 "};\n"
1344 "A::A(int i) : X::X(i) {}\n"
1345 "} // namespace nb\n"
1346 "} // namespace na\n";
1347 std::string Expected =
1348 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1349 "\n\n"
1350 "namespace x {\n"
1351 "namespace y {\n"
1352 "class A : public nx::ny::X {\n"
1353 "public:\n"
1354 " A() : X::X(0) {}\n"
1355 " A(int i);\n"
1356 "};\n"
1357 "A::A(int i) : X::X(i) {}\n"
1358 "} // namespace y\n"
1359 "} // namespace x\n";
1360 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1361}
1362
1363TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) {
1364 std::string Code =
1365 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1366 "namespace na {\n"
1367 "namespace nb {\n"
1368 "class A : public nx::ny::X {\n"
1369 "public:\n"
1370 " A() : X(0) {}\n"
1371 " A(int i);\n"
1372 "};\n"
1373 "A::A(int i) : X(i) { X x(1);}\n"
1374 "} // namespace nb\n"
1375 "} // namespace na\n";
1376 std::string Expected =
1377 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1378 "\n\n"
1379 "namespace x {\n"
1380 "namespace y {\n"
1381 "class A : public nx::ny::X {\n"
1382 "public:\n"
1383 " A() : X(0) {}\n"
1384 " A(int i);\n"
1385 "};\n"
Eric Liu97f87ad2016-12-07 20:08:02 +00001386 "A::A(int i) : X(i) { ::nx::ny::X x(1);}\n"
Eric Liuff51f012016-11-16 16:54:53 +00001387 "} // namespace y\n"
1388 "} // namespace x\n";
1389 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1390}
1391
Eric Liu2dd0e1b2016-12-05 11:17:04 +00001392TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) {
1393 NewNamespace = "";
1394 std::string Code = "namespace na {\n"
1395 "class C_A {};\n"
1396 "namespace nc {\n"
1397 "class C_C {};"
1398 "} // namespace nc\n"
1399 "namespace nb {\n"
1400 "class C_X {\n"
1401 "public:\n"
1402 " C_A a;\n"
1403 " nc::C_C c;\n"
1404 "};\n"
1405 "class C_Y {\n"
1406 " C_X x;\n"
1407 "};\n"
1408 "} // namespace nb\n"
1409 "} // namespace na\n";
1410 std::string Expected = "namespace na {\n"
1411 "class C_A {};\n"
1412 "namespace nc {\n"
1413 "class C_C {};"
1414 "} // namespace nc\n"
1415 "\n"
1416 "} // namespace na\n"
1417 "class C_X {\n"
1418 "public:\n"
1419 " na::C_A a;\n"
1420 " na::nc::C_C c;\n"
1421 "};\n"
1422 "class C_Y {\n"
1423 " C_X x;\n"
1424 "};\n";
1425 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1426}
1427
Eric Liu97f87ad2016-12-07 20:08:02 +00001428TEST_F(ChangeNamespaceTest, KeepGlobalSpecifier) {
1429 std::string Code = "class Glob {};\n"
1430 "namespace na {\n"
1431 "class C_A {};\n"
1432 "namespace nc {\n"
1433 "class C_C {};"
1434 "} // namespace nc\n"
1435 "namespace nb {\n"
1436 "class C_X {\n"
1437 "public:\n"
1438 " ::Glob glob_1;\n"
1439 " Glob glob_2;\n"
1440 " C_A a_1;\n"
1441 " ::na::C_A a_2;\n"
1442 " nc::C_C c;\n"
1443 "};\n"
1444 "} // namespace nb\n"
1445 "} // namespace na\n";
1446 std::string Expected = "class Glob {};\n"
1447 "namespace na {\n"
1448 "class C_A {};\n"
1449 "namespace nc {\n"
1450 "class C_C {};"
1451 "} // namespace nc\n"
1452 "\n"
1453 "} // namespace na\n"
1454 "namespace x {\n"
1455 "namespace y {\n"
1456 "class C_X {\n"
1457 "public:\n"
1458 " ::Glob glob_1;\n"
1459 " Glob glob_2;\n"
1460 " ::na::C_A a_1;\n"
1461 " ::na::C_A a_2;\n"
1462 " ::na::nc::C_C c;\n"
1463 "};\n"
1464 "} // namespace y\n"
1465 "} // namespace x\n";
1466 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1467}
1468
Eric Liu26cf68a2016-12-15 10:42:35 +00001469TEST_F(ChangeNamespaceTest, UsingAliasInTemplate) {
1470 NewNamespace = "na::nb::nc";
1471 std::string Code = "namespace some_ns {\n"
1472 "template <typename T, typename S>\n"
1473 "class G {};\n"
1474 "} // namespace some_ns\n"
1475 "namespace na {\n"
1476 "template<typename P>\n"
1477 "using GG = some_ns::G<int, P>;\n"
1478 "} // namespace na\n"
1479 "namespace na {\n"
1480 "namespace nb {\n"
1481 "void f() {\n"
1482 " GG<float> g;\n"
1483 "}\n"
1484 "} // namespace nb\n"
1485 "} // namespace na\n";
1486 std::string Expected = "namespace some_ns {\n"
1487 "template <typename T, typename S>\n"
1488 "class G {};\n"
1489 "} // namespace some_ns\n"
1490 "namespace na {\n"
1491 "template<typename P>\n"
1492 "using GG = some_ns::G<int, P>;\n"
1493 "} // namespace na\n"
1494 "namespace na {\n"
1495 "namespace nb {\n"
1496 "namespace nc {\n"
1497 "void f() {\n"
1498 " GG<float> g;\n"
1499 "}\n"
1500 "} // namespace nc\n\n"
1501 "} // namespace nb\n"
1502 "} // namespace na\n";
1503 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1504}
1505
1506TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
1507 NewNamespace = "na::nb::nc";
1508 std::string Code = "namespace some_ns {\n"
1509 "template <typename T, typename S>\n"
1510 "class G {};\n"
1511 "} // namespace some_ns\n"
1512 "namespace na {\n"
1513 "class Base {\n"
1514 "public:\n"
1515 " template<typename P>\n"
1516 " using GG = some_ns::G<int, P>;\n"
Eric Liu0c0aea02016-12-15 13:02:41 +00001517 "\n"
1518 " struct Nested {};\n"
Eric Liu26cf68a2016-12-15 10:42:35 +00001519 "};\n"
1520 "class Derived : public Base {};\n"
1521 "} // namespace na\n"
1522 "namespace na {\n"
1523 "namespace nb {\n"
1524 "void f() {\n"
1525 " Derived::GG<float> g;\n"
Eric Liu0c0aea02016-12-15 13:02:41 +00001526 " const Derived::GG<int> gg;\n"
1527 " const Derived::GG<int>* gg_ptr;\n"
1528 " struct Derived::Nested nested;\n"
1529 " const struct Derived::Nested *nested_ptr;\n"
Eric Liu26cf68a2016-12-15 10:42:35 +00001530 "}\n"
1531 "} // namespace nb\n"
1532 "} // namespace na\n";
1533 std::string Expected = "namespace some_ns {\n"
1534 "template <typename T, typename S>\n"
1535 "class G {};\n"
1536 "} // namespace some_ns\n"
1537 "namespace na {\n"
1538 "class Base {\n"
1539 "public:\n"
1540 " template<typename P>\n"
1541 " using GG = some_ns::G<int, P>;\n"
Eric Liu0c0aea02016-12-15 13:02:41 +00001542 "\n"
1543 " struct Nested {};\n"
Eric Liu26cf68a2016-12-15 10:42:35 +00001544 "};\n"
1545 "class Derived : public Base {};\n"
1546 "} // namespace na\n"
1547 "namespace na {\n"
1548 "namespace nb {\n"
1549 "namespace nc {\n"
1550 "void f() {\n"
1551 " Derived::GG<float> g;\n"
Eric Liu0c0aea02016-12-15 13:02:41 +00001552 " const Derived::GG<int> gg;\n"
1553 " const Derived::GG<int>* gg_ptr;\n"
1554 " struct Derived::Nested nested;\n"
1555 " const struct Derived::Nested *nested_ptr;\n"
Eric Liu26cf68a2016-12-15 10:42:35 +00001556 "}\n"
1557 "} // namespace nc\n\n"
1558 "} // namespace nb\n"
1559 "} // namespace na\n";
1560 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1561}
1562
Eric Liu495b2112016-09-19 17:40:32 +00001563} // anonymous namespace
1564} // namespace change_namespace
1565} // namespace clang