blob: 8d102080b4137e6a81fd9df6e4a85e57414eeebe [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);
46 tooling::runToolOnCodeWithArgs(Factory->create(), Code, {"-std=c++11"},
47 FileName);
48 formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite);
49 return format(Context.getRewrittenText(ID));
50 }
51
52 std::string format(llvm::StringRef Code) {
53 tooling::Replacements Replaces = format::reformat(
54 format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())});
55 auto ChangedCode = tooling::applyAllReplacements(Code, Replaces);
56 EXPECT_TRUE(static_cast<bool>(ChangedCode));
57 if (!ChangedCode) {
58 llvm::errs() << llvm::toString(ChangedCode.takeError());
59 return "";
60 }
61 return *ChangedCode;
62 }
63
64protected:
65 std::string FileName = "input.cc";
66 std::string OldNamespace = "na::nb";
67 std::string NewNamespace = "x::y";
68 std::string FilePattern = "input.cc";
69};
70
71TEST_F(ChangeNamespaceTest, NoMatchingNamespace) {
72 std::string Code = "namespace na {\n"
73 "namespace nx {\n"
74 "class A {};\n"
75 "} // namespace nx\n"
76 "} // namespace na\n";
77 std::string Expected = "namespace na {\n"
78 "namespace nx {\n"
79 "class A {};\n"
80 "} // namespace nx\n"
81 "} // namespace na\n";
82 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
83}
84
85TEST_F(ChangeNamespaceTest, SimpleMoveWithoutTypeRefs) {
86 std::string Code = "namespace na {\n"
87 "namespace nb {\n"
88 "class A {};\n"
89 "} // namespace nb\n"
90 "} // namespace na\n";
91 std::string Expected = "\n\n"
92 "namespace x {\n"
93 "namespace y {\n"
94 "class A {};\n"
95 "} // namespace y\n"
96 "} // namespace x\n";
97 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
98}
99
100TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) {
101 NewNamespace = "na::nc";
102 std::string Code = "namespace na {\n"
103 "namespace nb {\n"
104 "class A {};\n"
105 "} // namespace nb\n"
106 "} // namespace na\n";
107 std::string Expected = "namespace na {\n"
108 "\n"
109 "namespace nc {\n"
110 "class A {};\n"
111 "} // namespace nc\n"
112 "} // namespace na\n";
113 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
114}
115
Eric Liu447164d2016-10-05 15:52:39 +0000116TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) {
117 NewNamespace = "na::nc";
118 std::string Code = "namespace na {\n"
119 "class A {};\n"
120 "namespace nb {\n"
121 "class X { A a; };\n"
122 "} // namespace nb\n"
123 "} // namespace na\n";
124 std::string Expected = "namespace na {\n"
125 "class A {};\n"
126 "\n"
127 "namespace nc {\n"
128 "class X { A a; };\n"
129 "} // namespace nc\n"
130 "} // namespace na\n";
131 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
132}
133
Eric Liu495b2112016-09-19 17:40:32 +0000134TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
135 NewNamespace = "na::x::y";
136 std::string Code = "namespace na {\n"
137 "class A {};\n"
138 "namespace nb {\n"
139 "class B {};\n"
140 "} // namespace nb\n"
141 "} // namespace na\n";
142 std::string Expected = "namespace na {\n"
143 "class A {};\n"
144 "\n"
145 "namespace x {\n"
146 "namespace y {\n"
147 "class B {};\n"
148 "} // namespace y\n"
149 "} // namespace x\n"
150 "} // namespace na\n";
151 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
152}
153
154TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) {
155 std::string Code = "namespace na {\n"
156 "class C_A {};\n"
157 "namespace nc {\n"
158 "class C_C {};"
159 "} // namespace nc\n"
160 "namespace nb {\n"
161 "class C_X {\n"
162 "public:\n"
163 " C_A a;\n"
164 " nc::C_C c;\n"
165 "};\n"
166 "class C_Y {\n"
167 " C_X x;\n"
168 "};\n"
169 "} // namespace nb\n"
170 "} // namespace na\n";
171 std::string Expected = "namespace na {\n"
172 "class C_A {};\n"
173 "namespace nc {\n"
174 "class C_C {};"
175 "} // namespace nc\n"
176 "\n"
177 "} // namespace na\n"
178 "namespace x {\n"
179 "namespace y {\n"
180 "class C_X {\n"
181 "public:\n"
182 " na::C_A a;\n"
183 " na::nc::C_C c;\n"
184 "};\n"
185 "class C_Y {\n"
186 " C_X x;\n"
187 "};\n"
188 "} // namespace y\n"
189 "} // namespace x\n";
190 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
191}
192
Eric Liu8393cb02016-10-31 08:28:29 +0000193TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) {
194 std::string Code = "namespace na {\n"
195 "class A {};\n"
196 "template <typename T>\n"
197 "class B {};\n"
198 "template <typename T1, typename T2>\n"
199 "class Two {};\n"
200 "namespace nc { class C {}; }\n"
201 "} // na\n"
202 "\n"
203 "namespace na {\n"
204 "namespace nb {\n"
205 "void f() {\n"
206 " B<A> b;\n"
207 " B<nc::C> b_c;\n"
208 " Two<A, nc::C> two;\n"
209 "}\n"
210 "} // nb\n"
211 "} // na\n";
212 std::string Expected = "namespace na {\n"
213 "class A {};\n"
214 "template <typename T>\n"
215 "class B {};\n"
216 "template <typename T1, typename T2>\n"
217 "class Two {};\n"
218 "namespace nc { class C {}; }\n"
219 "} // na\n"
220 "\n"
221 "\n"
222 "namespace x {\n"
223 "namespace y {\n"
224 "void f() {\n"
225 " na::B<na::A> b;\n"
226 " na::B<na::nc::C> b_c;\n"
227 " na::Two<na::A, na::nc::C> two;\n"
228 "}\n"
229 "} // namespace y\n"
230 "} // namespace x\n";
231 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
232}
233
Eric Liu495b2112016-09-19 17:40:32 +0000234TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) {
235 std::string Code = "namespace na {\n"
236 "namespace nb {\n"
237 "class FWD;\n"
238 "class A {\n"
239 " FWD *fwd;\n"
240 "};\n"
241 "} // namespace nb\n"
242 "} // namespace na\n";
243 std::string Expected = "namespace na {\n"
244 "namespace nb {\n"
245 "class FWD;\n"
246 "} // namespace nb\n"
247 "} // namespace na\n"
248 "namespace x {\n"
249 "namespace y {\n"
250 "\n"
251 "class A {\n"
252 " na::nb::FWD *fwd;\n"
253 "};\n"
254 "} // namespace y\n"
255 "} // namespace x\n";
256 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
257}
258
259TEST_F(ChangeNamespaceTest, MoveFunctions) {
260 std::string Code = "namespace na {\n"
261 "class C_A {};\n"
262 "namespace nc {\n"
263 "class C_C {};"
264 "} // namespace nc\n"
265 "namespace nb {\n"
266 "void fwd();\n"
267 "void f(C_A ca, nc::C_C cc) {\n"
268 " C_A ca_1 = ca;\n"
269 "}\n"
270 "} // namespace nb\n"
271 "} // namespace na\n";
272
273 std::string Expected = "namespace na {\n"
274 "class C_A {};\n"
275 "namespace nc {\n"
276 "class C_C {};"
277 "} // namespace nc\n"
278 "\n"
279 "} // namespace na\n"
280 "namespace x {\n"
281 "namespace y {\n"
282 "void fwd();\n"
283 "void f(na::C_A ca, na::nc::C_C cc) {\n"
284 " na::C_A ca_1 = ca;\n"
285 "}\n"
286 "} // namespace y\n"
287 "} // namespace x\n";
288 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
289}
290
Eric Liu912d0392016-09-27 12:54:48 +0000291TEST_F(ChangeNamespaceTest, DoNotCrashWithLambdaAsParameter) {
292 std::string Code =
293 "#include <functional>\n"
294 "void f(std::function<void(int)> func, int param) { func(param); } "
295 "void g() { f([](int x) {}, 1); }";
296
297 std::string Expected =
298 "#include <functional>\n"
299 "void f(std::function<void(int)> func, int param) { func(param); } "
300 "void g() { f([](int x) {}, 1); }";
301 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
302}
303
Eric Liu68765a82016-09-21 15:06:12 +0000304TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) {
Eric Liu912d0392016-09-27 12:54:48 +0000305 std::string Code = "class GLOB {};\n"
306 "using BLOG = GLOB;\n"
307 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000308 "namespace nc {\n"
309 "class SAME {};\n"
310 "}\n"
311 "namespace nd {\n"
312 "class SAME {};\n"
313 "}\n"
314 "namespace nb {\n"
315 "using nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000316 "using YO = nd::SAME;\n"
317 "typedef nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000318 "void f(nd::SAME Same) {}\n"
319 "} // namespace nb\n"
320 "} // namespace na\n";
321
Eric Liu912d0392016-09-27 12:54:48 +0000322 std::string Expected = "class GLOB {};\n"
323 "using BLOG = GLOB;\n"
324 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000325 "namespace nc {\n"
326 "class SAME {};\n"
327 "}\n"
328 "namespace nd {\n"
329 "class SAME {};\n"
330 "}\n"
331 "\n"
332 "} // namespace na\n"
333 "namespace x {\n"
334 "namespace y {\n"
335 "using ::na::nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000336 "using YO = na::nd::SAME;\n"
337 "typedef na::nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000338 "void f(na::nd::SAME Same) {}\n"
339 "} // namespace y\n"
340 "} // namespace x\n";
341 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
342}
343
344TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) {
345 std::string Code =
346 "namespace na {\n"
347 "class C_A {\n"
348 "public:\n"
349 " class Nested {\n"
350 " public:\n"
351 " static int NestedX;\n"
352 " static void nestedFunc() {}\n"
353 " };\n"
354 "};\n"
355 "namespace nb {\n"
356 "class C_X {\n"
357 " C_A na;\n"
358 " C_A::Nested nested;\n"
359 " void f() {\n"
360 " C_A::Nested::nestedFunc();\n"
361 " int X = C_A::Nested::NestedX;\n"
362 " }\n"
363 "};\n"
364 "} // namespace nb\n"
365 "} // namespace na\n";
366 std::string Expected =
367 "namespace na {\n"
368 "class C_A {\n"
369 "public:\n"
370 " class Nested {\n"
371 " public:\n"
372 " static int NestedX;\n"
373 " static void nestedFunc() {}\n"
374 " };\n"
375 "};\n"
376 "\n"
377 "} // namespace na\n"
378 "namespace x {\n"
379 "namespace y {\n"
380 "class C_X {\n"
381 " na::C_A na;\n"
382 " na::C_A::Nested nested;\n"
383 " void f() {\n"
384 " na::C_A::Nested::nestedFunc();\n"
385 " int X = na::C_A::Nested::NestedX;\n"
386 " }\n"
387 "};\n"
388 "} // namespace y\n"
389 "} // namespace x\n";
390 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
391}
392
Eric Liu12068d82016-09-22 11:54:00 +0000393TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
394 std::string Code =
395 "namespace na {\n"
396 "class A {\n"
397 "public:\n"
398 " static void f() {}\n"
399 " static void g();\n"
400 "};\n"
401 "void A::g() {}"
402 "void a_f() {}\n"
403 "static void static_f() {}\n"
404 "namespace nb {\n"
405 "void f() { a_f(); static_f(); A::f(); }\n"
406 "void g() { f(); A::g(); }\n"
407 "} // namespace nb\n"
408 "} // namespace na\n";
409 std::string Expected =
410 "namespace na {\n"
411 "class A {\n"
412 "public:\n"
413 " static void f() {}\n"
414 " static void g();\n"
415 "};\n"
416 "void A::g() {}"
417 "void a_f() {}\n"
418 "static void static_f() {}\n"
419 "\n"
420 "} // namespace na\n"
421 "namespace x {\n"
422 "namespace y {\n"
423 "void f() { na::a_f(); na::static_f(); na::A::f(); }\n"
424 "void g() { f(); na::A::g(); }\n"
425 "} // namespace y\n"
426 "} // namespace x\n";
427 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
428}
429
Eric Liu159f0132016-09-30 04:32:39 +0000430TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
431 std::string Code = "namespace na {\n"
432 "int GlobA;\n"
433 "static int GlobAStatic = 0;\n"
434 "namespace nc { int GlobC; }\n"
435 "namespace nb {\n"
436 "int GlobB;\n"
437 "void f() {\n"
438 " int a = GlobA;\n"
439 " int b = GlobAStatic;\n"
440 " int c = nc::GlobC;\n"
441 "}\n"
442 "} // namespace nb\n"
443 "} // namespace na\n";
444
445 std::string Expected = "namespace na {\n"
446 "int GlobA;\n"
447 "static int GlobAStatic = 0;\n"
448 "namespace nc { int GlobC; }\n"
449 "\n"
450 "} // namespace na\n"
451 "namespace x {\n"
452 "namespace y {\n"
453 "int GlobB;\n"
454 "void f() {\n"
455 " int a = na::GlobA;\n"
456 " int b = na::GlobAStatic;\n"
457 " int c = na::nc::GlobC;\n"
458 "}\n"
459 "} // namespace y\n"
460 "} // namespace x\n";
461
462 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
463}
464
465TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
466 std::string Code = "namespace na {\n"
467 "class A {\n"
468 "public:\n"
469 "static int A1;\n"
470 "static int A2;\n"
471 "}\n"
472 "static int A::A1 = 0;\n"
473 "namespace nb {\n"
474 "void f() { int a = A::A1; int b = A::A2; }"
475 "} // namespace nb\n"
476 "} // namespace na\n";
477
478 std::string Expected = "namespace na {\n"
479 "class A {\n"
480 "public:\n"
481 "static int A1;\n"
482 "static int A2;\n"
483 "}\n"
484 "static int A::A1 = 0;\n"
485 "\n"
486 "} // namespace na\n"
487 "namespace x {\n"
488 "namespace y {\n"
489 "void f() { int a = na::A::A1; int b = na::A::A2; }"
490 "} // namespace y\n"
491 "} // namespace x\n";
492
493 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
494}
495
Haojian Wuef8a6dc2016-10-04 10:35:53 +0000496TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) {
497 std::string Code = "namespace na {\n"
498 "namespace nb {\n"
499 "class A;\n"
500 "class B {};\n"
501 "}"
502 "}";
503 std::string Expected = "namespace na {\n"
504 "namespace nb {\n"
505 "class A;\n"
506 "}\n"
507 "}\n"
508 "namespace x {\n"
509 "namespace y {\n"
510 "\n"
511 "class B {};\n"
512 "} // namespace y\n"
513 "} // namespace x\n";
514 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
515}
516
Eric Liu73f49fd2016-10-12 12:34:18 +0000517TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) {
518 std::string Code = "namespace na {\n"
519 "namespace nb {\n"
520 "\n\n"
521 "// Wild comments.\n"
522 "\n"
523 "// Comments.\n"
524 "// More comments.\n"
525 "class B {\n"
526 " // Private comments.\n"
527 " int a;\n"
528 "};\n"
529 "}\n"
530 "}";
531 std::string Expected = "\n"
532 "\n"
533 "namespace x {\n"
534 "namespace y {\n"
535 "\n\n"
536 "// Wild comments.\n"
537 "\n"
538 "// Comments.\n"
539 "// More comments.\n"
540 "class B {\n"
541 " // Private comments.\n"
542 " int a;\n"
543 "};\n"
544 "} // namespace y\n"
545 "} // namespace x\n";
546 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
547}
548
Eric Liub9bf1b52016-11-08 22:44:17 +0000549TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) {
550 std::string Code = "namespace glob {\n"
551 "class Glob {};\n"
552 "}\n"
553 "using glob::Glob;\n"
554 "namespace na {\n"
555 "namespace nb {\n"
556 "void f() { Glob g; }\n"
557 "} // namespace nb\n"
558 "} // namespace na\n";
559
560 std::string Expected = "namespace glob {\n"
561 "class Glob {};\n"
562 "}\n"
563 "using glob::Glob;\n"
564 "\n"
565 "namespace x {\n"
566 "namespace y {\n"
567 "void f() { Glob g; }\n"
568 "} // namespace y\n"
569 "} // namespace x\n";
570 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
571}
572
573TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) {
574 std::string Code = "namespace glob {\n"
575 "class Glob {};\n"
576 "}\n"
577 "using namespace glob;\n"
578 "namespace na {\n"
579 "namespace nb {\n"
580 "void f() { Glob g; }\n"
581 "} // namespace nb\n"
582 "} // namespace na\n";
583
584 std::string Expected = "namespace glob {\n"
585 "class Glob {};\n"
586 "}\n"
587 "using namespace glob;\n"
588 "\n"
589 "namespace x {\n"
590 "namespace y {\n"
591 "void f() { Glob g; }\n"
592 "} // namespace y\n"
593 "} // namespace x\n";
594 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
595}
596
597TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) {
598 std::string Code = "namespace glob {\n"
599 "class Glob {};\n"
600 "}\n"
601 "namespace na {\n"
602 "namespace nb {\n"
603 "void f() { glob::Glob g; }\n"
604 "} // namespace nb\n"
605 "} // namespace na\n"
606 "using glob::Glob;\n"
607 "using namespace glob;\n";
608
609 std::string Expected = "namespace glob {\n"
610 "class Glob {};\n"
611 "}\n"
612 "\n"
613 "namespace x {\n"
614 "namespace y {\n"
615 "void f() { glob::Glob g; }\n"
616 "} // namespace y\n"
617 "} // namespace x\n"
618 "using glob::Glob;\n"
619 "using namespace glob;\n";
620 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
621}
622
623TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) {
624 NewNamespace = "na::nc";
625 std::string Code = "namespace glob {\n"
626 "class Glob {};\n"
627 "}\n"
628 "namespace na {\n"
629 "namespace nb {\n"
630 "void f() { glob::Glob g; }\n"
631 "} // namespace nb\n"
632 "using namespace glob;\n"
633 "} // namespace na\n";
634
635 std::string Expected = "namespace glob {\n"
636 "class Glob {};\n"
637 "}\n"
638 "namespace na {\n"
639 "\n"
640 "namespace nc {\n"
641 "void f() { glob::Glob g; }\n"
642 "} // namespace nc\n"
643 "using namespace glob;\n"
644 "} // namespace na\n";
645 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
646}
647
648TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) {
649 std::string Code = "namespace glob1 {\n"
650 "namespace glob2 {\n"
651 "class Glob {};\n"
652 "}\n"
653 "}\n"
654 "using glob1::glob2::Glob;\n"
655 "using namespace glob1;\n"
656 "namespace na {\n"
657 "namespace nb {\n"
658 "void f() { Glob g; }\n"
659 "} // namespace nb\n"
660 "} // namespace na\n";
661
662 std::string Expected = "namespace glob1 {\n"
663 "namespace glob2 {\n"
664 "class Glob {};\n"
665 "}\n"
666 "}\n"
667 "using glob1::glob2::Glob;\n"
668 "using namespace glob1;\n"
669 "\n"
670 "namespace x {\n"
671 "namespace y {\n"
672 "void f() { Glob g; }\n"
673 "} // namespace y\n"
674 "} // namespace x\n";
675 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
676}
677
678TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) {
679 std::string Code = "namespace glob {\n"
680 "class Glob {};\n"
681 "}\n"
682 "using GLB = glob::Glob;\n"
683 "using BLG = glob::Glob;\n"
684 "namespace na {\n"
685 "namespace nb {\n"
686 "void f() { GLB g; BLG blg; }\n"
687 "} // namespace nb\n"
688 "} // namespace na\n";
689
690 std::string Expected = "namespace glob {\n"
691 "class Glob {};\n"
692 "}\n"
693 "using GLB = glob::Glob;\n"
694 "using BLG = glob::Glob;\n"
695 "\n"
696 "namespace x {\n"
697 "namespace y {\n"
698 "void f() { GLB g; BLG blg; }\n"
699 "} // namespace y\n"
700 "} // namespace x\n";
701 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
702}
703
704TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) {
705 std::string Code = "namespace na { class C_A {};\n }\n"
706 "using na::C_A;\n"
707 "namespace na {\n"
708 "namespace nb {\n"
709 "class C_X {\n"
710 "public:\n"
711 " C_A a;\n"
712 "};\n"
713 "} // namespace nb\n"
714 "} // namespace na\n";
715 std::string Expected = "namespace na { class C_A {};\n }\n"
716 "using na::C_A;\n"
717 "\n"
718 "namespace x {\n"
719 "namespace y {\n"
720 "class C_X {\n"
721 "public:\n"
722 " C_A a;\n"
723 "};\n"
724 "} // namespace y\n"
725 "} // namespace x\n";
726 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
727}
728
729TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) {
730 std::string Code = "namespace na { class C_A {};\n }\n"
731 "using namespace na;\n"
732 "namespace na {\n"
733 "namespace nb {\n"
734 "class C_X {\n"
735 "public:\n"
736 " C_A ca;\n"
737 "};\n"
738 "} // namespace nb\n"
739 "} // namespace na\n";
740 std::string Expected = "namespace na { class C_A {};\n }\n"
741 "using namespace na;\n"
742 "\n"
743 "namespace x {\n"
744 "namespace y {\n"
745 "class C_X {\n"
746 "public:\n"
747 " C_A ca;\n"
748 "};\n"
749 "} // namespace y\n"
750 "} // namespace x\n";
751 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
752}
753
754TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) {
755 std::string Code = "namespace glob {\n"
756 "class Glob {};\n"
757 "}\n"
758 "namespace na {\n"
759 "namespace nb {\n"
760 "void f() {\n"
761 " using glob::Glob;\n"
762 " Glob g;\n"
763 "}\n"
764 "} // namespace nb\n"
765 "} // namespace na\n";
766
767 std::string Expected = "namespace glob {\n"
768 "class Glob {};\n"
769 "}\n"
770 "\n"
771 "namespace x {\n"
772 "namespace y {\n"
773 "void f() {\n"
774 " using ::glob::Glob;\n"
775 " Glob g;\n"
776 "}\n"
777 "} // namespace y\n"
778 "} // namespace x\n";
779 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
780}
781
782TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) {
783 std::string Code = "namespace na { class C_A {};\n }\n"
784 "namespace na {\n"
785 "namespace nb {\n"
786 "void f() {\n"
787 " using na::CA;\n"
788 " CA ca;\n"
789 "}\n"
790 "} // namespace nb\n"
791 "} // namespace na\n";
792 std::string Expected = "namespace na { class C_A {};\n }\n"
793 "\n"
794 "namespace x {\n"
795 "namespace y {\n"
796 "void f() {\n"
797 " using na::CA;\n"
798 " CA ca;\n"
799 "}\n"
800 "} // namespace y\n"
801 "} // namespace x\n";
802 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
803}
804
805TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) {
806 std::string Code = "namespace nx { void f(); }\n"
807 "namespace na {\n"
808 "using nx::f;\n"
809 "namespace nb {\n"
810 "void d() { f(); }\n"
811 "} // nb\n"
812 "} // na\n";
813
814 std::string Expected = "namespace nx { void f(); }\n"
815 "namespace na {\n"
816 "using nx::f;\n"
817 "\n"
818 "} // na\n"
819 "namespace x {\n"
820 "namespace y {\n"
821 "void d() { nx::f(); }\n"
822 "} // namespace y\n"
823 "} // namespace x\n";
824 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
825}
826
827TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) {
828 OldNamespace = "na";
829 std::string Code = "namespace nx { void f(); }\n"
830 "namespace na {\n"
831 "using ::nx::f;\n"
832 "void d() { f(); }\n"
833 "} // na\n";
834
835 std::string Expected = "namespace nx { void f(); }\n"
836 "\n"
837 "namespace x {\n"
838 "namespace y {\n"
839 "using ::nx::f;\n"
840 "void d() { f(); }\n"
841 "} // namespace y\n"
842 "} // namespace x\n";
843 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
844}
845
846TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
847 OldNamespace = "a::b::c::d";
848 NewNamespace = "a::b::x::y";
849 std::string Code = "namespace nx { void f(); void g(); }\n"
850 "namespace a {\n"
851 "namespace b {\n"
852 "using ::nx::f;\n"
853 "namespace c {\n"
854 "using ::nx::g;\n"
855 "namespace d {\n"
856 "void d() { f(); g(); }\n"
857 "} // d\n"
858 "} // c\n"
859 "} // b\n"
860 "} // a\n";
861
862 std::string Expected = "namespace nx { void f(); void g(); }\n"
863 "namespace a {\n"
864 "namespace b {\n"
865 "using ::nx::f;\n"
866 "namespace c {\n"
867 "using ::nx::g;\n"
868 "\n"
869 "} // c\n"
870 "namespace x {\n"
871 "namespace y {\n"
872 "void d() { f(); nx::g(); }\n"
873 "} // namespace y\n"
874 "} // namespace x\n"
875 "} // b\n"
876 "} // a\n";
877 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
878}
879
880TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
881 OldNamespace = "nb::nc";
882 NewNamespace = "nb::nd";
883 std::string Code = "namespace na { class A {}; }\n"
884 "namespace nb {\n"
885 "using na::A;\n"
886 "namespace nc {\n"
887 "void d() { A a; }\n"
888 "} // nc\n"
889 "} // nb\n";
890
891 std::string Expected = "namespace na { class A {}; }\n"
892 "namespace nb {\n"
893 "using na::A;\n"
894 "\n"
895 "namespace nd {\n"
896 "void d() { A a; }\n"
897 "} // namespace nd\n"
898 "} // nb\n";
899 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
900}
901
Eric Liu495b2112016-09-19 17:40:32 +0000902} // anonymous namespace
903} // namespace change_namespace
904} // namespace clang