blob: 53684be66aabf41589a8737f5046388ddf088037 [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 Liu495b2112016-09-19 17:40:32 +0000177TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
178 NewNamespace = "na::x::y";
179 std::string Code = "namespace na {\n"
180 "class A {};\n"
181 "namespace nb {\n"
182 "class B {};\n"
183 "} // namespace nb\n"
184 "} // namespace na\n";
185 std::string Expected = "namespace na {\n"
186 "class A {};\n"
187 "\n"
188 "namespace x {\n"
189 "namespace y {\n"
190 "class B {};\n"
191 "} // namespace y\n"
192 "} // namespace x\n"
193 "} // namespace na\n";
194 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
195}
196
197TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) {
198 std::string Code = "namespace na {\n"
199 "class C_A {};\n"
200 "namespace nc {\n"
201 "class C_C {};"
202 "} // namespace nc\n"
203 "namespace nb {\n"
204 "class C_X {\n"
205 "public:\n"
206 " C_A a;\n"
207 " nc::C_C c;\n"
208 "};\n"
209 "class C_Y {\n"
210 " C_X x;\n"
211 "};\n"
212 "} // namespace nb\n"
213 "} // namespace na\n";
214 std::string Expected = "namespace na {\n"
215 "class C_A {};\n"
216 "namespace nc {\n"
217 "class C_C {};"
218 "} // namespace nc\n"
219 "\n"
220 "} // namespace na\n"
221 "namespace x {\n"
222 "namespace y {\n"
223 "class C_X {\n"
224 "public:\n"
225 " na::C_A a;\n"
226 " na::nc::C_C c;\n"
227 "};\n"
228 "class C_Y {\n"
229 " C_X x;\n"
230 "};\n"
231 "} // namespace y\n"
232 "} // namespace x\n";
233 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
234}
235
Eric Liu8393cb02016-10-31 08:28:29 +0000236TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) {
237 std::string Code = "namespace na {\n"
238 "class A {};\n"
239 "template <typename T>\n"
240 "class B {};\n"
241 "template <typename T1, typename T2>\n"
242 "class Two {};\n"
243 "namespace nc { class C {}; }\n"
244 "} // na\n"
245 "\n"
246 "namespace na {\n"
247 "namespace nb {\n"
248 "void f() {\n"
249 " B<A> b;\n"
250 " B<nc::C> b_c;\n"
251 " Two<A, nc::C> two;\n"
252 "}\n"
253 "} // nb\n"
254 "} // na\n";
255 std::string Expected = "namespace na {\n"
256 "class A {};\n"
257 "template <typename T>\n"
258 "class B {};\n"
259 "template <typename T1, typename T2>\n"
260 "class Two {};\n"
261 "namespace nc { class C {}; }\n"
262 "} // na\n"
263 "\n"
264 "\n"
265 "namespace x {\n"
266 "namespace y {\n"
267 "void f() {\n"
268 " na::B<na::A> b;\n"
269 " na::B<na::nc::C> b_c;\n"
270 " na::Two<na::A, na::nc::C> two;\n"
271 "}\n"
272 "} // namespace y\n"
273 "} // namespace x\n";
274 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
275}
276
Eric Liu495b2112016-09-19 17:40:32 +0000277TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) {
278 std::string Code = "namespace na {\n"
279 "namespace nb {\n"
280 "class FWD;\n"
281 "class A {\n"
282 " FWD *fwd;\n"
283 "};\n"
284 "} // namespace nb\n"
285 "} // namespace na\n";
286 std::string Expected = "namespace na {\n"
287 "namespace nb {\n"
288 "class FWD;\n"
289 "} // namespace nb\n"
290 "} // namespace na\n"
291 "namespace x {\n"
292 "namespace y {\n"
293 "\n"
294 "class A {\n"
295 " na::nb::FWD *fwd;\n"
296 "};\n"
297 "} // namespace y\n"
298 "} // namespace x\n";
299 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
300}
301
302TEST_F(ChangeNamespaceTest, MoveFunctions) {
303 std::string Code = "namespace na {\n"
304 "class C_A {};\n"
305 "namespace nc {\n"
306 "class C_C {};"
307 "} // namespace nc\n"
308 "namespace nb {\n"
309 "void fwd();\n"
310 "void f(C_A ca, nc::C_C cc) {\n"
311 " C_A ca_1 = ca;\n"
312 "}\n"
313 "} // namespace nb\n"
314 "} // namespace na\n";
315
316 std::string Expected = "namespace na {\n"
317 "class C_A {};\n"
318 "namespace nc {\n"
319 "class C_C {};"
320 "} // namespace nc\n"
321 "\n"
322 "} // namespace na\n"
323 "namespace x {\n"
324 "namespace y {\n"
325 "void fwd();\n"
326 "void f(na::C_A ca, na::nc::C_C cc) {\n"
327 " na::C_A ca_1 = ca;\n"
328 "}\n"
329 "} // namespace y\n"
330 "} // namespace x\n";
331 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
332}
333
Eric Liu68765a82016-09-21 15:06:12 +0000334TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) {
Eric Liu912d0392016-09-27 12:54:48 +0000335 std::string Code = "class GLOB {};\n"
336 "using BLOG = GLOB;\n"
337 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000338 "namespace nc {\n"
339 "class SAME {};\n"
340 "}\n"
341 "namespace nd {\n"
342 "class SAME {};\n"
343 "}\n"
344 "namespace nb {\n"
345 "using nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000346 "using YO = nd::SAME;\n"
347 "typedef nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000348 "void f(nd::SAME Same) {}\n"
349 "} // namespace nb\n"
350 "} // namespace na\n";
351
Eric Liu912d0392016-09-27 12:54:48 +0000352 std::string Expected = "class GLOB {};\n"
353 "using BLOG = GLOB;\n"
354 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000355 "namespace nc {\n"
356 "class SAME {};\n"
357 "}\n"
358 "namespace nd {\n"
359 "class SAME {};\n"
360 "}\n"
361 "\n"
362 "} // namespace na\n"
363 "namespace x {\n"
364 "namespace y {\n"
365 "using ::na::nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000366 "using YO = na::nd::SAME;\n"
367 "typedef na::nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000368 "void f(na::nd::SAME Same) {}\n"
369 "} // namespace y\n"
370 "} // namespace x\n";
371 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
372}
373
374TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) {
375 std::string Code =
376 "namespace na {\n"
377 "class C_A {\n"
378 "public:\n"
379 " class Nested {\n"
380 " public:\n"
381 " static int NestedX;\n"
382 " static void nestedFunc() {}\n"
383 " };\n"
384 "};\n"
385 "namespace nb {\n"
386 "class C_X {\n"
387 " C_A na;\n"
388 " C_A::Nested nested;\n"
389 " void f() {\n"
390 " C_A::Nested::nestedFunc();\n"
391 " int X = C_A::Nested::NestedX;\n"
392 " }\n"
393 "};\n"
394 "} // namespace nb\n"
395 "} // namespace na\n";
396 std::string Expected =
397 "namespace na {\n"
398 "class C_A {\n"
399 "public:\n"
400 " class Nested {\n"
401 " public:\n"
402 " static int NestedX;\n"
403 " static void nestedFunc() {}\n"
404 " };\n"
405 "};\n"
406 "\n"
407 "} // namespace na\n"
408 "namespace x {\n"
409 "namespace y {\n"
410 "class C_X {\n"
411 " na::C_A na;\n"
412 " na::C_A::Nested nested;\n"
413 " void f() {\n"
414 " na::C_A::Nested::nestedFunc();\n"
415 " int X = na::C_A::Nested::NestedX;\n"
416 " }\n"
417 "};\n"
418 "} // namespace y\n"
419 "} // namespace x\n";
420 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
421}
422
Eric Liu12068d82016-09-22 11:54:00 +0000423TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
424 std::string Code =
425 "namespace na {\n"
426 "class A {\n"
427 "public:\n"
428 " static void f() {}\n"
429 " static void g();\n"
430 "};\n"
431 "void A::g() {}"
432 "void a_f() {}\n"
433 "static void static_f() {}\n"
434 "namespace nb {\n"
435 "void f() { a_f(); static_f(); A::f(); }\n"
436 "void g() { f(); A::g(); }\n"
437 "} // namespace nb\n"
438 "} // namespace na\n";
439 std::string Expected =
440 "namespace na {\n"
441 "class A {\n"
442 "public:\n"
443 " static void f() {}\n"
444 " static void g();\n"
445 "};\n"
446 "void A::g() {}"
447 "void a_f() {}\n"
448 "static void static_f() {}\n"
449 "\n"
450 "} // namespace na\n"
451 "namespace x {\n"
452 "namespace y {\n"
453 "void f() { na::a_f(); na::static_f(); na::A::f(); }\n"
454 "void g() { f(); na::A::g(); }\n"
455 "} // namespace y\n"
456 "} // namespace x\n";
457 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
458}
459
Eric Liuda22b3c2016-11-29 14:15:14 +0000460TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
461 std::string Code = "namespace na {\n"
462 "class A {\n"
463 "public:\n"
464 " static void f() {}\n"
465 "};\n"
466 "void a_f() {}\n"
467 "static void s_f() {}\n"
468 "namespace nb {\n"
469 "void f() {\n"
470 "auto *ref1 = A::f; auto *ref2 = a_f; auto *ref3 = s_f;\n"
471 "}\n"
472 "} // namespace nb\n"
473 "} // namespace na\n";
474 std::string Expected =
475 "namespace na {\n"
476 "class A {\n"
477 "public:\n"
478 " static void f() {}\n"
479 "};\n"
480 "void a_f() {}\n"
481 "static void s_f() {}\n"
482 "\n"
483 "} // namespace na\n"
484 "namespace x {\n"
485 "namespace y {\n"
486 "void f() {\n"
487 "auto *ref1 = na::A::f; auto *ref2 = na::a_f; auto *ref3 = na::s_f;\n"
488 "}\n"
489 "} // namespace y\n"
490 "} // namespace x\n";
491 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
492}
493
Eric Liu159f0132016-09-30 04:32:39 +0000494TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
495 std::string Code = "namespace na {\n"
496 "int GlobA;\n"
497 "static int GlobAStatic = 0;\n"
498 "namespace nc { int GlobC; }\n"
499 "namespace nb {\n"
500 "int GlobB;\n"
501 "void f() {\n"
502 " int a = GlobA;\n"
503 " int b = GlobAStatic;\n"
504 " int c = nc::GlobC;\n"
505 "}\n"
506 "} // namespace nb\n"
507 "} // namespace na\n";
508
509 std::string Expected = "namespace na {\n"
510 "int GlobA;\n"
511 "static int GlobAStatic = 0;\n"
512 "namespace nc { int GlobC; }\n"
513 "\n"
514 "} // namespace na\n"
515 "namespace x {\n"
516 "namespace y {\n"
517 "int GlobB;\n"
518 "void f() {\n"
519 " int a = na::GlobA;\n"
520 " int b = na::GlobAStatic;\n"
521 " int c = na::nc::GlobC;\n"
522 "}\n"
523 "} // namespace y\n"
524 "} // namespace x\n";
525
526 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
527}
528
529TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
530 std::string Code = "namespace na {\n"
531 "class A {\n"
532 "public:\n"
533 "static int A1;\n"
534 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000535 "};\n"
536 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000537 "namespace nb {\n"
538 "void f() { int a = A::A1; int b = A::A2; }"
539 "} // namespace nb\n"
540 "} // namespace na\n";
541
542 std::string Expected = "namespace na {\n"
543 "class A {\n"
544 "public:\n"
545 "static int A1;\n"
546 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000547 "};\n"
548 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000549 "\n"
550 "} // namespace na\n"
551 "namespace x {\n"
552 "namespace y {\n"
553 "void f() { int a = na::A::A1; int b = na::A::A2; }"
554 "} // namespace y\n"
555 "} // namespace x\n";
556
557 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
558}
559
Haojian Wuef8a6dc2016-10-04 10:35:53 +0000560TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) {
561 std::string Code = "namespace na {\n"
562 "namespace nb {\n"
563 "class A;\n"
564 "class B {};\n"
565 "}"
566 "}";
567 std::string Expected = "namespace na {\n"
568 "namespace nb {\n"
569 "class A;\n"
570 "}\n"
571 "}\n"
572 "namespace x {\n"
573 "namespace y {\n"
574 "\n"
575 "class B {};\n"
576 "} // namespace y\n"
577 "} // namespace x\n";
578 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
579}
580
Eric Liu73f49fd2016-10-12 12:34:18 +0000581TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) {
582 std::string Code = "namespace na {\n"
583 "namespace nb {\n"
584 "\n\n"
585 "// Wild comments.\n"
586 "\n"
587 "// Comments.\n"
588 "// More comments.\n"
589 "class B {\n"
590 " // Private comments.\n"
591 " int a;\n"
592 "};\n"
593 "}\n"
594 "}";
595 std::string Expected = "\n"
596 "\n"
597 "namespace x {\n"
598 "namespace y {\n"
599 "\n\n"
600 "// Wild comments.\n"
601 "\n"
602 "// Comments.\n"
603 "// More comments.\n"
604 "class B {\n"
605 " // Private comments.\n"
606 " int a;\n"
607 "};\n"
608 "} // namespace y\n"
609 "} // namespace x\n";
610 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
611}
612
Eric Liub9bf1b52016-11-08 22:44:17 +0000613TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) {
614 std::string Code = "namespace glob {\n"
615 "class Glob {};\n"
616 "}\n"
617 "using glob::Glob;\n"
618 "namespace na {\n"
619 "namespace nb {\n"
620 "void f() { Glob g; }\n"
621 "} // namespace nb\n"
622 "} // namespace na\n";
623
624 std::string Expected = "namespace glob {\n"
625 "class Glob {};\n"
626 "}\n"
627 "using glob::Glob;\n"
628 "\n"
629 "namespace x {\n"
630 "namespace y {\n"
631 "void f() { Glob g; }\n"
632 "} // namespace y\n"
633 "} // namespace x\n";
634 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
635}
636
637TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) {
638 std::string Code = "namespace glob {\n"
639 "class Glob {};\n"
640 "}\n"
641 "using namespace glob;\n"
642 "namespace na {\n"
643 "namespace nb {\n"
644 "void f() { Glob g; }\n"
645 "} // namespace nb\n"
646 "} // namespace na\n";
647
648 std::string Expected = "namespace glob {\n"
649 "class Glob {};\n"
650 "}\n"
651 "using namespace glob;\n"
652 "\n"
653 "namespace x {\n"
654 "namespace y {\n"
655 "void f() { Glob g; }\n"
656 "} // namespace y\n"
657 "} // namespace x\n";
658 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
659}
660
661TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) {
662 std::string Code = "namespace glob {\n"
663 "class Glob {};\n"
664 "}\n"
665 "namespace na {\n"
666 "namespace nb {\n"
667 "void f() { glob::Glob g; }\n"
668 "} // namespace nb\n"
669 "} // namespace na\n"
670 "using glob::Glob;\n"
671 "using namespace glob;\n";
672
673 std::string Expected = "namespace glob {\n"
674 "class Glob {};\n"
675 "}\n"
676 "\n"
677 "namespace x {\n"
678 "namespace y {\n"
679 "void f() { glob::Glob g; }\n"
680 "} // namespace y\n"
681 "} // namespace x\n"
682 "using glob::Glob;\n"
683 "using namespace glob;\n";
684 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
685}
686
687TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) {
688 NewNamespace = "na::nc";
689 std::string Code = "namespace glob {\n"
690 "class Glob {};\n"
691 "}\n"
692 "namespace na {\n"
693 "namespace nb {\n"
694 "void f() { glob::Glob g; }\n"
695 "} // namespace nb\n"
696 "using namespace glob;\n"
697 "} // namespace na\n";
698
699 std::string Expected = "namespace glob {\n"
700 "class Glob {};\n"
701 "}\n"
702 "namespace na {\n"
703 "\n"
704 "namespace nc {\n"
705 "void f() { glob::Glob g; }\n"
706 "} // namespace nc\n"
707 "using namespace glob;\n"
708 "} // namespace na\n";
709 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
710}
711
712TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) {
713 std::string Code = "namespace glob1 {\n"
714 "namespace glob2 {\n"
715 "class Glob {};\n"
716 "}\n"
717 "}\n"
718 "using glob1::glob2::Glob;\n"
719 "using namespace glob1;\n"
720 "namespace na {\n"
721 "namespace nb {\n"
722 "void f() { Glob g; }\n"
723 "} // namespace nb\n"
724 "} // namespace na\n";
725
726 std::string Expected = "namespace glob1 {\n"
727 "namespace glob2 {\n"
728 "class Glob {};\n"
729 "}\n"
730 "}\n"
731 "using glob1::glob2::Glob;\n"
732 "using namespace glob1;\n"
733 "\n"
734 "namespace x {\n"
735 "namespace y {\n"
736 "void f() { Glob g; }\n"
737 "} // namespace y\n"
738 "} // namespace x\n";
739 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
740}
741
742TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) {
743 std::string Code = "namespace glob {\n"
744 "class Glob {};\n"
745 "}\n"
746 "using GLB = glob::Glob;\n"
747 "using BLG = glob::Glob;\n"
748 "namespace na {\n"
749 "namespace nb {\n"
750 "void f() { GLB g; BLG blg; }\n"
751 "} // namespace nb\n"
752 "} // namespace na\n";
753
754 std::string Expected = "namespace glob {\n"
755 "class Glob {};\n"
756 "}\n"
757 "using GLB = glob::Glob;\n"
758 "using BLG = glob::Glob;\n"
759 "\n"
760 "namespace x {\n"
761 "namespace y {\n"
762 "void f() { GLB g; BLG blg; }\n"
763 "} // namespace y\n"
764 "} // namespace x\n";
765 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
766}
767
768TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) {
769 std::string Code = "namespace na { class C_A {};\n }\n"
770 "using na::C_A;\n"
771 "namespace na {\n"
772 "namespace nb {\n"
773 "class C_X {\n"
774 "public:\n"
775 " C_A a;\n"
776 "};\n"
777 "} // namespace nb\n"
778 "} // namespace na\n";
779 std::string Expected = "namespace na { class C_A {};\n }\n"
780 "using na::C_A;\n"
781 "\n"
782 "namespace x {\n"
783 "namespace y {\n"
784 "class C_X {\n"
785 "public:\n"
786 " C_A a;\n"
787 "};\n"
788 "} // namespace y\n"
789 "} // namespace x\n";
790 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
791}
792
793TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) {
794 std::string Code = "namespace na { class C_A {};\n }\n"
795 "using namespace na;\n"
796 "namespace na {\n"
797 "namespace nb {\n"
798 "class C_X {\n"
799 "public:\n"
800 " C_A ca;\n"
801 "};\n"
802 "} // namespace nb\n"
803 "} // namespace na\n";
804 std::string Expected = "namespace na { class C_A {};\n }\n"
805 "using namespace na;\n"
806 "\n"
807 "namespace x {\n"
808 "namespace y {\n"
809 "class C_X {\n"
810 "public:\n"
811 " C_A ca;\n"
812 "};\n"
813 "} // namespace y\n"
814 "} // namespace x\n";
815 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
816}
817
818TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) {
819 std::string Code = "namespace glob {\n"
820 "class Glob {};\n"
821 "}\n"
822 "namespace na {\n"
823 "namespace nb {\n"
824 "void f() {\n"
825 " using glob::Glob;\n"
826 " Glob g;\n"
827 "}\n"
828 "} // namespace nb\n"
829 "} // namespace na\n";
830
831 std::string Expected = "namespace glob {\n"
832 "class Glob {};\n"
833 "}\n"
834 "\n"
835 "namespace x {\n"
836 "namespace y {\n"
837 "void f() {\n"
838 " using ::glob::Glob;\n"
839 " Glob g;\n"
840 "}\n"
841 "} // namespace y\n"
842 "} // namespace x\n";
843 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
844}
845
846TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) {
Eric Liu32158862016-11-14 19:37:55 +0000847 std::string Code = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000848 "namespace na {\n"
849 "namespace nb {\n"
850 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +0000851 " using ::na::C_A;\n"
852 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000853 "}\n"
854 "} // namespace nb\n"
855 "} // namespace na\n";
Eric Liu32158862016-11-14 19:37:55 +0000856 std::string Expected = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000857 "\n"
858 "namespace x {\n"
859 "namespace y {\n"
860 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +0000861 " using ::na::C_A;\n"
862 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000863 "}\n"
864 "} // namespace y\n"
865 "} // namespace x\n";
866 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
867}
868
869TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) {
870 std::string Code = "namespace nx { void f(); }\n"
871 "namespace na {\n"
872 "using nx::f;\n"
873 "namespace nb {\n"
874 "void d() { f(); }\n"
875 "} // nb\n"
876 "} // na\n";
877
878 std::string Expected = "namespace nx { void f(); }\n"
879 "namespace na {\n"
880 "using nx::f;\n"
881 "\n"
882 "} // na\n"
883 "namespace x {\n"
884 "namespace y {\n"
885 "void d() { nx::f(); }\n"
886 "} // namespace y\n"
887 "} // namespace x\n";
888 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
889}
890
891TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) {
892 OldNamespace = "na";
893 std::string Code = "namespace nx { void f(); }\n"
894 "namespace na {\n"
895 "using ::nx::f;\n"
896 "void d() { f(); }\n"
897 "} // na\n";
898
899 std::string Expected = "namespace nx { void f(); }\n"
900 "\n"
901 "namespace x {\n"
902 "namespace y {\n"
903 "using ::nx::f;\n"
904 "void d() { f(); }\n"
905 "} // namespace y\n"
906 "} // namespace x\n";
907 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
908}
909
910TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
911 OldNamespace = "a::b::c::d";
912 NewNamespace = "a::b::x::y";
913 std::string Code = "namespace nx { void f(); void g(); }\n"
914 "namespace a {\n"
915 "namespace b {\n"
916 "using ::nx::f;\n"
917 "namespace c {\n"
918 "using ::nx::g;\n"
919 "namespace d {\n"
920 "void d() { f(); g(); }\n"
921 "} // d\n"
922 "} // c\n"
923 "} // b\n"
924 "} // a\n";
925
926 std::string Expected = "namespace nx { void f(); void g(); }\n"
927 "namespace a {\n"
928 "namespace b {\n"
929 "using ::nx::f;\n"
930 "namespace c {\n"
931 "using ::nx::g;\n"
932 "\n"
933 "} // c\n"
934 "namespace x {\n"
935 "namespace y {\n"
936 "void d() { f(); nx::g(); }\n"
937 "} // namespace y\n"
938 "} // namespace x\n"
939 "} // b\n"
940 "} // a\n";
941 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
942}
943
944TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
945 OldNamespace = "nb::nc";
946 NewNamespace = "nb::nd";
947 std::string Code = "namespace na { class A {}; }\n"
948 "namespace nb {\n"
949 "using na::A;\n"
950 "namespace nc {\n"
951 "void d() { A a; }\n"
952 "} // nc\n"
953 "} // nb\n";
954
955 std::string Expected = "namespace na { class A {}; }\n"
956 "namespace nb {\n"
957 "using na::A;\n"
958 "\n"
959 "namespace nd {\n"
960 "void d() { A a; }\n"
961 "} // namespace nd\n"
962 "} // nb\n";
963 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
964}
965
Eric Liu32158862016-11-14 19:37:55 +0000966TEST_F(ChangeNamespaceTest, UsingAliasDecl) {
967 std::string Code =
968 "namespace nx { namespace ny { class X {}; } }\n"
969 "namespace na {\n"
970 "namespace nb {\n"
971 "using Y = nx::ny::X;\n"
972 "void f() { Y y; }\n"
973 "} // namespace nb\n"
974 "} // namespace na\n";
975
976 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
977 "\n"
978 "namespace x {\n"
979 "namespace y {\n"
980 "using Y = nx::ny::X;\n"
981 "void f() { Y y; }\n"
982 "} // namespace y\n"
983 "} // namespace x\n";
984 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
985}
986
987TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) {
988 std::string Code =
989 "namespace nx { namespace ny { class X {}; } }\n"
990 "using Y = nx::ny::X;\n"
991 "namespace na {\n"
992 "namespace nb {\n"
993 "void f() { Y y; }\n"
994 "} // namespace nb\n"
995 "} // namespace na\n";
996
997 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
998 "using Y = nx::ny::X;\n"
999 "\n"
1000 "namespace x {\n"
1001 "namespace y {\n"
1002 "void f() { Y y; }\n"
1003 "} // namespace y\n"
1004 "} // namespace x\n";
1005 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1006}
1007
1008
1009TEST_F(ChangeNamespaceTest, TypedefAliasDecl) {
1010 std::string Code =
1011 "namespace nx { namespace ny { class X {}; } }\n"
1012 "namespace na {\n"
1013 "namespace nb {\n"
1014 "typedef nx::ny::X Y;\n"
1015 "void f() { Y y; }\n"
1016 "} // namespace nb\n"
1017 "} // namespace na\n";
1018
1019 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1020 "\n"
1021 "namespace x {\n"
1022 "namespace y {\n"
1023 "typedef nx::ny::X Y;\n"
1024 "void f() { Y y; }\n"
1025 "} // namespace y\n"
1026 "} // namespace x\n";
1027 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1028}
1029
Eric Liuff51f012016-11-16 16:54:53 +00001030TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) {
1031 std::string Code =
1032 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1033 "namespace na {\n"
1034 "namespace nb {\n"
1035 "class A : public nx::ny::X {\n"
1036 "public:\n"
1037 " A() : X(0) {}\n"
1038 " A(int i);\n"
1039 "};\n"
1040 "A::A(int i) : X(i) {}\n"
1041 "} // namespace nb\n"
1042 "} // namespace na\n";
1043 std::string Expected =
1044 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1045 "\n\n"
1046 "namespace x {\n"
1047 "namespace y {\n"
1048 "class A : public nx::ny::X {\n"
1049 "public:\n"
1050 " A() : X(0) {}\n"
1051 " A(int i);\n"
1052 "};\n"
1053 "A::A(int i) : X(i) {}\n"
1054 "} // namespace y\n"
1055 "} // namespace x\n";
1056 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1057}
1058
1059TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) {
1060 std::string Code =
1061 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1062 "namespace na {\n"
1063 "namespace nb {\n"
1064 "class A : public nx::ny::X {\n"
1065 "public:\n"
1066 " A() : X::X(0) {}\n"
1067 " A(int i);\n"
1068 "};\n"
1069 "A::A(int i) : X::X(i) {}\n"
1070 "} // namespace nb\n"
1071 "} // namespace na\n";
1072 std::string Expected =
1073 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1074 "\n\n"
1075 "namespace x {\n"
1076 "namespace y {\n"
1077 "class A : public nx::ny::X {\n"
1078 "public:\n"
1079 " A() : X::X(0) {}\n"
1080 " A(int i);\n"
1081 "};\n"
1082 "A::A(int i) : X::X(i) {}\n"
1083 "} // namespace y\n"
1084 "} // namespace x\n";
1085 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1086}
1087
1088TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) {
1089 std::string Code =
1090 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1091 "namespace na {\n"
1092 "namespace nb {\n"
1093 "class A : public nx::ny::X {\n"
1094 "public:\n"
1095 " A() : X(0) {}\n"
1096 " A(int i);\n"
1097 "};\n"
1098 "A::A(int i) : X(i) { X x(1);}\n"
1099 "} // namespace nb\n"
1100 "} // namespace na\n";
1101 std::string Expected =
1102 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1103 "\n\n"
1104 "namespace x {\n"
1105 "namespace y {\n"
1106 "class A : public nx::ny::X {\n"
1107 "public:\n"
1108 " A() : X(0) {}\n"
1109 " A(int i);\n"
1110 "};\n"
1111 "A::A(int i) : X(i) { nx::ny::X x(1);}\n"
1112 "} // namespace y\n"
1113 "} // namespace x\n";
1114 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1115}
1116
Eric Liu2dd0e1b2016-12-05 11:17:04 +00001117TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) {
1118 NewNamespace = "";
1119 std::string Code = "namespace na {\n"
1120 "class C_A {};\n"
1121 "namespace nc {\n"
1122 "class C_C {};"
1123 "} // namespace nc\n"
1124 "namespace nb {\n"
1125 "class C_X {\n"
1126 "public:\n"
1127 " C_A a;\n"
1128 " nc::C_C c;\n"
1129 "};\n"
1130 "class C_Y {\n"
1131 " C_X x;\n"
1132 "};\n"
1133 "} // namespace nb\n"
1134 "} // namespace na\n";
1135 std::string Expected = "namespace na {\n"
1136 "class C_A {};\n"
1137 "namespace nc {\n"
1138 "class C_C {};"
1139 "} // namespace nc\n"
1140 "\n"
1141 "} // namespace na\n"
1142 "class C_X {\n"
1143 "public:\n"
1144 " na::C_A a;\n"
1145 " na::nc::C_C c;\n"
1146 "};\n"
1147 "class C_Y {\n"
1148 " C_X x;\n"
1149 "};\n";
1150 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1151}
1152
Eric Liu495b2112016-09-19 17:40:32 +00001153} // anonymous namespace
1154} // namespace change_namespace
1155} // namespace clang