blob: 9beecedbb7d2ac0139f0148e4eec3f3d6119453b [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"
Eric Liu41552d62016-12-07 14:20:52 +0000281 "class FWD2;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000282 "class A {\n"
283 " FWD *fwd;\n"
284 "};\n"
285 "} // namespace nb\n"
286 "} // namespace na\n";
287 std::string Expected = "namespace na {\n"
288 "namespace nb {\n"
289 "class FWD;\n"
Eric Liu41552d62016-12-07 14:20:52 +0000290 "class FWD2;\n"
Eric Liu495b2112016-09-19 17:40:32 +0000291 "} // namespace nb\n"
292 "} // namespace na\n"
293 "namespace x {\n"
294 "namespace y {\n"
295 "\n"
296 "class A {\n"
297 " na::nb::FWD *fwd;\n"
298 "};\n"
299 "} // namespace y\n"
300 "} // namespace x\n";
301 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
302}
303
Eric Liu41552d62016-12-07 14:20:52 +0000304TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) {
305 std::string Code = "namespace na {\n"
306 "namespace nb {\n"
307 "class FWD;\n"
308 "template<typename T> class FWD_TEMP;\n"
309 "class A {\n"
310 " FWD *fwd;\n"
311 "};\n"
312 "template<typename T> class TEMP {};\n"
313 "} // namespace nb\n"
314 "} // namespace na\n";
315 std::string Expected = "namespace na {\n"
316 "namespace nb {\n"
317 "class FWD;\n"
318 "template<typename T> class FWD_TEMP;\n"
319 "} // namespace nb\n"
320 "} // namespace na\n"
321 "namespace x {\n"
322 "namespace y {\n"
323 "\n"
324 "class A {\n"
325 " na::nb::FWD *fwd;\n"
326 "};\n"
327 "template<typename T> class TEMP {};\n"
328 "} // namespace y\n"
329 "} // namespace x\n";
330 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
331}
332
333TEST_F(ChangeNamespaceTest, DontMoveForwardDeclarationInClass) {
334 std::string Code = "namespace na {\n"
335 "namespace nb {\n"
336 "class A {\n"
337 " class FWD;\n"
338 " FWD *fwd;\n"
339 " template<typename T> class FWD_TEMP;\n"
340 "};\n"
341 "} // namespace nb\n"
342 "} // namespace na\n";
343 std::string Expected = "\n\n"
344 "namespace x {\n"
345 "namespace y {\n"
346 "class A {\n"
347 " class FWD;\n"
348 " FWD *fwd;\n"
349 " template<typename T> class FWD_TEMP;\n"
350 "};\n"
351 "} // namespace y\n"
352 "} // namespace x\n";
353 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
354}
355
Eric Liu495b2112016-09-19 17:40:32 +0000356TEST_F(ChangeNamespaceTest, MoveFunctions) {
357 std::string Code = "namespace na {\n"
358 "class C_A {};\n"
359 "namespace nc {\n"
360 "class C_C {};"
361 "} // namespace nc\n"
362 "namespace nb {\n"
363 "void fwd();\n"
364 "void f(C_A ca, nc::C_C cc) {\n"
365 " C_A ca_1 = ca;\n"
366 "}\n"
367 "} // namespace nb\n"
368 "} // namespace na\n";
369
370 std::string Expected = "namespace na {\n"
371 "class C_A {};\n"
372 "namespace nc {\n"
373 "class C_C {};"
374 "} // namespace nc\n"
375 "\n"
376 "} // namespace na\n"
377 "namespace x {\n"
378 "namespace y {\n"
379 "void fwd();\n"
380 "void f(na::C_A ca, na::nc::C_C cc) {\n"
381 " na::C_A ca_1 = ca;\n"
382 "}\n"
383 "} // namespace y\n"
384 "} // namespace x\n";
385 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
386}
387
Eric Liu68765a82016-09-21 15:06:12 +0000388TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) {
Eric Liu912d0392016-09-27 12:54:48 +0000389 std::string Code = "class GLOB {};\n"
390 "using BLOG = GLOB;\n"
391 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000392 "namespace nc {\n"
393 "class SAME {};\n"
394 "}\n"
395 "namespace nd {\n"
396 "class SAME {};\n"
397 "}\n"
398 "namespace nb {\n"
399 "using nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000400 "using YO = nd::SAME;\n"
401 "typedef nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000402 "void f(nd::SAME Same) {}\n"
403 "} // namespace nb\n"
404 "} // namespace na\n";
405
Eric Liu912d0392016-09-27 12:54:48 +0000406 std::string Expected = "class GLOB {};\n"
407 "using BLOG = GLOB;\n"
408 "namespace na {\n"
Eric Liu68765a82016-09-21 15:06:12 +0000409 "namespace nc {\n"
410 "class SAME {};\n"
411 "}\n"
412 "namespace nd {\n"
413 "class SAME {};\n"
414 "}\n"
415 "\n"
416 "} // namespace na\n"
417 "namespace x {\n"
418 "namespace y {\n"
419 "using ::na::nc::SAME;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000420 "using YO = na::nd::SAME;\n"
421 "typedef na::nd::SAME IDENTICAL;\n"
Eric Liu68765a82016-09-21 15:06:12 +0000422 "void f(na::nd::SAME Same) {}\n"
423 "} // namespace y\n"
424 "} // namespace x\n";
425 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
426}
427
Eric Liu8685c762016-12-07 17:04:07 +0000428TEST_F(ChangeNamespaceTest, DontFixUsingShadowDeclInClasses) {
429 std::string Code = "namespace na {\n"
430 "class A {};\n"
431 "class Base { public: Base() {} void m() {} };\n"
432 "namespace nb {\n"
433 "class D : public Base {\n"
434 "public:\n"
435 " using AA = A; using B = Base;\n"
436 " using Base::m; using Base::Base;\n"
437 "};"
438 "} // namespace nb\n"
439 "} // namespace na\n";
440
441 std::string Expected = "namespace na {\n"
442 "class A {};\n"
443 "class Base { public: Base() {} void m() {} };\n"
444 "\n"
445 "} // namespace na\n"
446 "namespace x {\n"
447 "namespace y {\n"
448 "class D : public na::Base {\n"
449 "public:\n"
450 " using AA = na::A; using B = na::Base;\n"
451 " using Base::m; using Base::Base;\n"
452 "};"
453 "} // namespace y\n"
454 "} // namespace x\n";
455 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
456}
457
Eric Liu68765a82016-09-21 15:06:12 +0000458TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) {
459 std::string Code =
460 "namespace na {\n"
461 "class C_A {\n"
462 "public:\n"
463 " class Nested {\n"
464 " public:\n"
465 " static int NestedX;\n"
466 " static void nestedFunc() {}\n"
467 " };\n"
468 "};\n"
469 "namespace nb {\n"
470 "class C_X {\n"
471 " C_A na;\n"
472 " C_A::Nested nested;\n"
473 " void f() {\n"
474 " C_A::Nested::nestedFunc();\n"
475 " int X = C_A::Nested::NestedX;\n"
476 " }\n"
477 "};\n"
478 "} // namespace nb\n"
479 "} // namespace na\n";
480 std::string Expected =
481 "namespace na {\n"
482 "class C_A {\n"
483 "public:\n"
484 " class Nested {\n"
485 " public:\n"
486 " static int NestedX;\n"
487 " static void nestedFunc() {}\n"
488 " };\n"
489 "};\n"
490 "\n"
491 "} // namespace na\n"
492 "namespace x {\n"
493 "namespace y {\n"
494 "class C_X {\n"
495 " na::C_A na;\n"
496 " na::C_A::Nested nested;\n"
497 " void f() {\n"
498 " na::C_A::Nested::nestedFunc();\n"
499 " int X = na::C_A::Nested::NestedX;\n"
500 " }\n"
501 "};\n"
502 "} // namespace y\n"
503 "} // namespace x\n";
504 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
505}
506
Eric Liu12068d82016-09-22 11:54:00 +0000507TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
508 std::string Code =
509 "namespace na {\n"
510 "class A {\n"
511 "public:\n"
512 " static void f() {}\n"
513 " static void g();\n"
514 "};\n"
515 "void A::g() {}"
516 "void a_f() {}\n"
517 "static void static_f() {}\n"
518 "namespace nb {\n"
519 "void f() { a_f(); static_f(); A::f(); }\n"
520 "void g() { f(); A::g(); }\n"
521 "} // namespace nb\n"
522 "} // namespace na\n";
523 std::string Expected =
524 "namespace na {\n"
525 "class A {\n"
526 "public:\n"
527 " static void f() {}\n"
528 " static void g();\n"
529 "};\n"
530 "void A::g() {}"
531 "void a_f() {}\n"
532 "static void static_f() {}\n"
533 "\n"
534 "} // namespace na\n"
535 "namespace x {\n"
536 "namespace y {\n"
537 "void f() { na::a_f(); na::static_f(); na::A::f(); }\n"
538 "void g() { f(); na::A::g(); }\n"
539 "} // namespace y\n"
540 "} // namespace x\n";
541 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
542}
543
Eric Liuda22b3c2016-11-29 14:15:14 +0000544TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
545 std::string Code = "namespace na {\n"
546 "class A {\n"
547 "public:\n"
548 " static void f() {}\n"
549 "};\n"
550 "void a_f() {}\n"
551 "static void s_f() {}\n"
552 "namespace nb {\n"
553 "void f() {\n"
554 "auto *ref1 = A::f; auto *ref2 = a_f; auto *ref3 = s_f;\n"
555 "}\n"
556 "} // namespace nb\n"
557 "} // namespace na\n";
558 std::string Expected =
559 "namespace na {\n"
560 "class A {\n"
561 "public:\n"
562 " static void f() {}\n"
563 "};\n"
564 "void a_f() {}\n"
565 "static void s_f() {}\n"
566 "\n"
567 "} // namespace na\n"
568 "namespace x {\n"
569 "namespace y {\n"
570 "void f() {\n"
571 "auto *ref1 = na::A::f; auto *ref2 = na::a_f; auto *ref3 = na::s_f;\n"
572 "}\n"
573 "} // namespace y\n"
574 "} // namespace x\n";
575 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
576}
577
Eric Liu159f0132016-09-30 04:32:39 +0000578TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
579 std::string Code = "namespace na {\n"
580 "int GlobA;\n"
581 "static int GlobAStatic = 0;\n"
582 "namespace nc { int GlobC; }\n"
583 "namespace nb {\n"
584 "int GlobB;\n"
585 "void f() {\n"
586 " int a = GlobA;\n"
587 " int b = GlobAStatic;\n"
588 " int c = nc::GlobC;\n"
589 "}\n"
590 "} // namespace nb\n"
591 "} // namespace na\n";
592
593 std::string Expected = "namespace na {\n"
594 "int GlobA;\n"
595 "static int GlobAStatic = 0;\n"
596 "namespace nc { int GlobC; }\n"
597 "\n"
598 "} // namespace na\n"
599 "namespace x {\n"
600 "namespace y {\n"
601 "int GlobB;\n"
602 "void f() {\n"
603 " int a = na::GlobA;\n"
604 " int b = na::GlobAStatic;\n"
605 " int c = na::nc::GlobC;\n"
606 "}\n"
607 "} // namespace y\n"
608 "} // namespace x\n";
609
610 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
611}
612
613TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
614 std::string Code = "namespace na {\n"
615 "class A {\n"
616 "public:\n"
617 "static int A1;\n"
618 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000619 "};\n"
620 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000621 "namespace nb {\n"
622 "void f() { int a = A::A1; int b = A::A2; }"
623 "} // namespace nb\n"
624 "} // namespace na\n";
625
626 std::string Expected = "namespace na {\n"
627 "class A {\n"
628 "public:\n"
629 "static int A1;\n"
630 "static int A2;\n"
Eric Liuff51f012016-11-16 16:54:53 +0000631 "};\n"
632 "int A::A1 = 0;\n"
Eric Liu159f0132016-09-30 04:32:39 +0000633 "\n"
634 "} // namespace na\n"
635 "namespace x {\n"
636 "namespace y {\n"
637 "void f() { int a = na::A::A1; int b = na::A::A2; }"
638 "} // namespace y\n"
639 "} // namespace x\n";
640
641 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
642}
643
Haojian Wuef8a6dc2016-10-04 10:35:53 +0000644TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) {
645 std::string Code = "namespace na {\n"
646 "namespace nb {\n"
647 "class A;\n"
648 "class B {};\n"
649 "}"
650 "}";
651 std::string Expected = "namespace na {\n"
652 "namespace nb {\n"
653 "class A;\n"
654 "}\n"
655 "}\n"
656 "namespace x {\n"
657 "namespace y {\n"
658 "\n"
659 "class B {};\n"
660 "} // namespace y\n"
661 "} // namespace x\n";
662 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
663}
664
Eric Liu73f49fd2016-10-12 12:34:18 +0000665TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) {
666 std::string Code = "namespace na {\n"
667 "namespace nb {\n"
668 "\n\n"
669 "// Wild comments.\n"
670 "\n"
671 "// Comments.\n"
672 "// More comments.\n"
673 "class B {\n"
674 " // Private comments.\n"
675 " int a;\n"
676 "};\n"
677 "}\n"
678 "}";
679 std::string Expected = "\n"
680 "\n"
681 "namespace x {\n"
682 "namespace y {\n"
683 "\n\n"
684 "// Wild comments.\n"
685 "\n"
686 "// Comments.\n"
687 "// More comments.\n"
688 "class B {\n"
689 " // Private comments.\n"
690 " int a;\n"
691 "};\n"
692 "} // namespace y\n"
693 "} // namespace x\n";
694 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
695}
696
Eric Liub9bf1b52016-11-08 22:44:17 +0000697TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) {
698 std::string Code = "namespace glob {\n"
699 "class Glob {};\n"
700 "}\n"
701 "using glob::Glob;\n"
702 "namespace na {\n"
703 "namespace nb {\n"
704 "void f() { Glob g; }\n"
705 "} // namespace nb\n"
706 "} // namespace na\n";
707
708 std::string Expected = "namespace glob {\n"
709 "class Glob {};\n"
710 "}\n"
711 "using glob::Glob;\n"
712 "\n"
713 "namespace x {\n"
714 "namespace y {\n"
715 "void f() { Glob g; }\n"
716 "} // namespace y\n"
717 "} // namespace x\n";
718 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
719}
720
721TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) {
722 std::string Code = "namespace glob {\n"
723 "class Glob {};\n"
724 "}\n"
725 "using namespace glob;\n"
726 "namespace na {\n"
727 "namespace nb {\n"
728 "void f() { Glob g; }\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 namespace glob;\n"
736 "\n"
737 "namespace x {\n"
738 "namespace y {\n"
739 "void f() { Glob g; }\n"
740 "} // namespace y\n"
741 "} // namespace x\n";
742 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
743}
744
745TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) {
746 std::string Code = "namespace glob {\n"
747 "class Glob {};\n"
748 "}\n"
749 "namespace na {\n"
750 "namespace nb {\n"
751 "void f() { glob::Glob g; }\n"
752 "} // namespace nb\n"
753 "} // namespace na\n"
754 "using glob::Glob;\n"
755 "using namespace glob;\n";
756
757 std::string Expected = "namespace glob {\n"
758 "class Glob {};\n"
759 "}\n"
760 "\n"
761 "namespace x {\n"
762 "namespace y {\n"
763 "void f() { glob::Glob g; }\n"
764 "} // namespace y\n"
765 "} // namespace x\n"
766 "using glob::Glob;\n"
767 "using namespace glob;\n";
768 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
769}
770
771TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) {
772 NewNamespace = "na::nc";
773 std::string Code = "namespace glob {\n"
774 "class Glob {};\n"
775 "}\n"
776 "namespace na {\n"
777 "namespace nb {\n"
778 "void f() { glob::Glob g; }\n"
779 "} // namespace nb\n"
780 "using namespace glob;\n"
781 "} // namespace na\n";
782
783 std::string Expected = "namespace glob {\n"
784 "class Glob {};\n"
785 "}\n"
786 "namespace na {\n"
787 "\n"
788 "namespace nc {\n"
789 "void f() { glob::Glob g; }\n"
790 "} // namespace nc\n"
791 "using namespace glob;\n"
792 "} // namespace na\n";
793 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
794}
795
796TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) {
797 std::string Code = "namespace glob1 {\n"
798 "namespace glob2 {\n"
799 "class Glob {};\n"
800 "}\n"
801 "}\n"
802 "using glob1::glob2::Glob;\n"
803 "using namespace glob1;\n"
804 "namespace na {\n"
805 "namespace nb {\n"
806 "void f() { Glob g; }\n"
807 "} // namespace nb\n"
808 "} // namespace na\n";
809
810 std::string Expected = "namespace glob1 {\n"
811 "namespace glob2 {\n"
812 "class Glob {};\n"
813 "}\n"
814 "}\n"
815 "using glob1::glob2::Glob;\n"
816 "using namespace glob1;\n"
817 "\n"
818 "namespace x {\n"
819 "namespace y {\n"
820 "void f() { Glob g; }\n"
821 "} // namespace y\n"
822 "} // namespace x\n";
823 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
824}
825
826TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) {
827 std::string Code = "namespace glob {\n"
828 "class Glob {};\n"
829 "}\n"
830 "using GLB = glob::Glob;\n"
831 "using BLG = glob::Glob;\n"
832 "namespace na {\n"
833 "namespace nb {\n"
834 "void f() { GLB g; BLG blg; }\n"
835 "} // namespace nb\n"
836 "} // namespace na\n";
837
838 std::string Expected = "namespace glob {\n"
839 "class Glob {};\n"
840 "}\n"
841 "using GLB = glob::Glob;\n"
842 "using BLG = glob::Glob;\n"
843 "\n"
844 "namespace x {\n"
845 "namespace y {\n"
846 "void f() { GLB g; BLG blg; }\n"
847 "} // namespace y\n"
848 "} // namespace x\n";
849 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
850}
851
852TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) {
853 std::string Code = "namespace na { class C_A {};\n }\n"
854 "using na::C_A;\n"
855 "namespace na {\n"
856 "namespace nb {\n"
857 "class C_X {\n"
858 "public:\n"
859 " C_A a;\n"
860 "};\n"
861 "} // namespace nb\n"
862 "} // namespace na\n";
863 std::string Expected = "namespace na { class C_A {};\n }\n"
864 "using na::C_A;\n"
865 "\n"
866 "namespace x {\n"
867 "namespace y {\n"
868 "class C_X {\n"
869 "public:\n"
870 " C_A a;\n"
871 "};\n"
872 "} // namespace y\n"
873 "} // namespace x\n";
874 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
875}
876
877TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) {
878 std::string Code = "namespace na { class C_A {};\n }\n"
879 "using namespace na;\n"
880 "namespace na {\n"
881 "namespace nb {\n"
882 "class C_X {\n"
883 "public:\n"
884 " C_A ca;\n"
885 "};\n"
886 "} // namespace nb\n"
887 "} // namespace na\n";
888 std::string Expected = "namespace na { class C_A {};\n }\n"
889 "using namespace na;\n"
890 "\n"
891 "namespace x {\n"
892 "namespace y {\n"
893 "class C_X {\n"
894 "public:\n"
895 " C_A ca;\n"
896 "};\n"
897 "} // namespace y\n"
898 "} // namespace x\n";
899 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
900}
901
902TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) {
903 std::string Code = "namespace glob {\n"
904 "class Glob {};\n"
905 "}\n"
906 "namespace na {\n"
907 "namespace nb {\n"
908 "void f() {\n"
909 " using glob::Glob;\n"
910 " Glob g;\n"
911 "}\n"
912 "} // namespace nb\n"
913 "} // namespace na\n";
914
915 std::string Expected = "namespace glob {\n"
916 "class Glob {};\n"
917 "}\n"
918 "\n"
919 "namespace x {\n"
920 "namespace y {\n"
921 "void f() {\n"
922 " using ::glob::Glob;\n"
923 " Glob g;\n"
924 "}\n"
925 "} // namespace y\n"
926 "} // namespace x\n";
927 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
928}
929
930TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) {
Eric Liu32158862016-11-14 19:37:55 +0000931 std::string Code = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000932 "namespace na {\n"
933 "namespace nb {\n"
934 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +0000935 " using ::na::C_A;\n"
936 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000937 "}\n"
938 "} // namespace nb\n"
939 "} // namespace na\n";
Eric Liu32158862016-11-14 19:37:55 +0000940 std::string Expected = "namespace na { class C_A {}; }\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000941 "\n"
942 "namespace x {\n"
943 "namespace y {\n"
944 "void f() {\n"
Eric Liu32158862016-11-14 19:37:55 +0000945 " using ::na::C_A;\n"
946 " C_A ca;\n"
Eric Liub9bf1b52016-11-08 22:44:17 +0000947 "}\n"
948 "} // namespace y\n"
949 "} // namespace x\n";
950 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
951}
952
953TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) {
954 std::string Code = "namespace nx { void f(); }\n"
955 "namespace na {\n"
956 "using nx::f;\n"
957 "namespace nb {\n"
958 "void d() { f(); }\n"
959 "} // nb\n"
960 "} // na\n";
961
962 std::string Expected = "namespace nx { void f(); }\n"
963 "namespace na {\n"
964 "using nx::f;\n"
965 "\n"
966 "} // na\n"
967 "namespace x {\n"
968 "namespace y {\n"
969 "void d() { nx::f(); }\n"
970 "} // namespace y\n"
971 "} // namespace x\n";
972 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
973}
974
975TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) {
976 OldNamespace = "na";
977 std::string Code = "namespace nx { void f(); }\n"
978 "namespace na {\n"
979 "using ::nx::f;\n"
980 "void d() { f(); }\n"
981 "} // na\n";
982
983 std::string Expected = "namespace nx { void f(); }\n"
984 "\n"
985 "namespace x {\n"
986 "namespace y {\n"
987 "using ::nx::f;\n"
988 "void d() { f(); }\n"
989 "} // namespace y\n"
990 "} // namespace x\n";
991 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
992}
993
994TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
995 OldNamespace = "a::b::c::d";
996 NewNamespace = "a::b::x::y";
997 std::string Code = "namespace nx { void f(); void g(); }\n"
998 "namespace a {\n"
999 "namespace b {\n"
1000 "using ::nx::f;\n"
1001 "namespace c {\n"
1002 "using ::nx::g;\n"
1003 "namespace d {\n"
1004 "void d() { f(); g(); }\n"
1005 "} // d\n"
1006 "} // c\n"
1007 "} // b\n"
1008 "} // a\n";
1009
1010 std::string Expected = "namespace nx { void f(); void g(); }\n"
1011 "namespace a {\n"
1012 "namespace b {\n"
1013 "using ::nx::f;\n"
1014 "namespace c {\n"
1015 "using ::nx::g;\n"
1016 "\n"
1017 "} // c\n"
1018 "namespace x {\n"
1019 "namespace y {\n"
1020 "void d() { f(); nx::g(); }\n"
1021 "} // namespace y\n"
1022 "} // namespace x\n"
1023 "} // b\n"
1024 "} // a\n";
1025 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1026}
1027
1028TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
1029 OldNamespace = "nb::nc";
1030 NewNamespace = "nb::nd";
1031 std::string Code = "namespace na { class A {}; }\n"
1032 "namespace nb {\n"
1033 "using na::A;\n"
1034 "namespace nc {\n"
1035 "void d() { A a; }\n"
1036 "} // nc\n"
1037 "} // nb\n";
1038
1039 std::string Expected = "namespace na { class A {}; }\n"
1040 "namespace nb {\n"
1041 "using na::A;\n"
1042 "\n"
1043 "namespace nd {\n"
1044 "void d() { A a; }\n"
1045 "} // namespace nd\n"
1046 "} // nb\n";
1047 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1048}
1049
Eric Liu32158862016-11-14 19:37:55 +00001050TEST_F(ChangeNamespaceTest, UsingAliasDecl) {
1051 std::string Code =
1052 "namespace nx { namespace ny { class X {}; } }\n"
1053 "namespace na {\n"
1054 "namespace nb {\n"
1055 "using Y = nx::ny::X;\n"
1056 "void f() { Y y; }\n"
1057 "} // namespace nb\n"
1058 "} // namespace na\n";
1059
1060 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1061 "\n"
1062 "namespace x {\n"
1063 "namespace y {\n"
1064 "using Y = nx::ny::X;\n"
1065 "void f() { Y y; }\n"
1066 "} // namespace y\n"
1067 "} // namespace x\n";
1068 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1069}
1070
1071TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) {
1072 std::string Code =
1073 "namespace nx { namespace ny { class X {}; } }\n"
1074 "using Y = nx::ny::X;\n"
1075 "namespace na {\n"
1076 "namespace nb {\n"
1077 "void f() { Y y; }\n"
1078 "} // namespace nb\n"
1079 "} // namespace na\n";
1080
1081 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1082 "using Y = nx::ny::X;\n"
1083 "\n"
1084 "namespace x {\n"
1085 "namespace y {\n"
1086 "void f() { Y y; }\n"
1087 "} // namespace y\n"
1088 "} // namespace x\n";
1089 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1090}
1091
1092
1093TEST_F(ChangeNamespaceTest, TypedefAliasDecl) {
1094 std::string Code =
1095 "namespace nx { namespace ny { class X {}; } }\n"
1096 "namespace na {\n"
1097 "namespace nb {\n"
1098 "typedef nx::ny::X Y;\n"
1099 "void f() { Y y; }\n"
1100 "} // namespace nb\n"
1101 "} // namespace na\n";
1102
1103 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1104 "\n"
1105 "namespace x {\n"
1106 "namespace y {\n"
1107 "typedef nx::ny::X Y;\n"
1108 "void f() { Y y; }\n"
1109 "} // namespace y\n"
1110 "} // namespace x\n";
1111 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1112}
1113
Eric Liuff51f012016-11-16 16:54:53 +00001114TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) {
1115 std::string Code =
1116 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1117 "namespace na {\n"
1118 "namespace nb {\n"
1119 "class A : public nx::ny::X {\n"
1120 "public:\n"
1121 " A() : X(0) {}\n"
1122 " A(int i);\n"
1123 "};\n"
1124 "A::A(int i) : X(i) {}\n"
1125 "} // namespace nb\n"
1126 "} // namespace na\n";
1127 std::string Expected =
1128 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1129 "\n\n"
1130 "namespace x {\n"
1131 "namespace y {\n"
1132 "class A : public nx::ny::X {\n"
1133 "public:\n"
1134 " A() : X(0) {}\n"
1135 " A(int i);\n"
1136 "};\n"
1137 "A::A(int i) : X(i) {}\n"
1138 "} // namespace y\n"
1139 "} // namespace x\n";
1140 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1141}
1142
1143TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) {
1144 std::string Code =
1145 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1146 "namespace na {\n"
1147 "namespace nb {\n"
1148 "class A : public nx::ny::X {\n"
1149 "public:\n"
1150 " A() : X::X(0) {}\n"
1151 " A(int i);\n"
1152 "};\n"
1153 "A::A(int i) : X::X(i) {}\n"
1154 "} // namespace nb\n"
1155 "} // namespace na\n";
1156 std::string Expected =
1157 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1158 "\n\n"
1159 "namespace x {\n"
1160 "namespace y {\n"
1161 "class A : public nx::ny::X {\n"
1162 "public:\n"
1163 " A() : X::X(0) {}\n"
1164 " A(int i);\n"
1165 "};\n"
1166 "A::A(int i) : X::X(i) {}\n"
1167 "} // namespace y\n"
1168 "} // namespace x\n";
1169 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1170}
1171
1172TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) {
1173 std::string Code =
1174 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1175 "namespace na {\n"
1176 "namespace nb {\n"
1177 "class A : public nx::ny::X {\n"
1178 "public:\n"
1179 " A() : X(0) {}\n"
1180 " A(int i);\n"
1181 "};\n"
1182 "A::A(int i) : X(i) { X x(1);}\n"
1183 "} // namespace nb\n"
1184 "} // namespace na\n";
1185 std::string Expected =
1186 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1187 "\n\n"
1188 "namespace x {\n"
1189 "namespace y {\n"
1190 "class A : public nx::ny::X {\n"
1191 "public:\n"
1192 " A() : X(0) {}\n"
1193 " A(int i);\n"
1194 "};\n"
1195 "A::A(int i) : X(i) { nx::ny::X x(1);}\n"
1196 "} // namespace y\n"
1197 "} // namespace x\n";
1198 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1199}
1200
Eric Liu2dd0e1b2016-12-05 11:17:04 +00001201TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) {
1202 NewNamespace = "";
1203 std::string Code = "namespace na {\n"
1204 "class C_A {};\n"
1205 "namespace nc {\n"
1206 "class C_C {};"
1207 "} // namespace nc\n"
1208 "namespace nb {\n"
1209 "class C_X {\n"
1210 "public:\n"
1211 " C_A a;\n"
1212 " nc::C_C c;\n"
1213 "};\n"
1214 "class C_Y {\n"
1215 " C_X x;\n"
1216 "};\n"
1217 "} // namespace nb\n"
1218 "} // namespace na\n";
1219 std::string Expected = "namespace na {\n"
1220 "class C_A {};\n"
1221 "namespace nc {\n"
1222 "class C_C {};"
1223 "} // namespace nc\n"
1224 "\n"
1225 "} // namespace na\n"
1226 "class C_X {\n"
1227 "public:\n"
1228 " na::C_A a;\n"
1229 " na::nc::C_C c;\n"
1230 "};\n"
1231 "class C_Y {\n"
1232 " C_X x;\n"
1233 "};\n";
1234 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1235}
1236
Eric Liu495b2112016-09-19 17:40:32 +00001237} // anonymous namespace
1238} // namespace change_namespace
1239} // namespace clang