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