1//===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ChangeNamespace.h"
10#include "unittests/Tooling/RewriterTestContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12#include "clang/Basic/FileManager.h"
13#include "clang/Basic/FileSystemOptions.h"
14#include "clang/Format/Format.h"
15#include "clang/Frontend/CompilerInstance.h"
16#include "clang/Frontend/PCHContainerOperations.h"
17#include "clang/Tooling/Refactoring.h"
18#include "clang/Tooling/Tooling.h"
19#include "llvm/ADT/IntrusiveRefCntPtr.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/MemoryBuffer.h"
22#include "llvm/Support/VirtualFileSystem.h"
23#include "gtest/gtest.h"
24#include <memory>
25#include <string>
26#include <vector>
27
28namespace clang {
29namespace change_namespace {
30namespace {
31
32class ChangeNamespaceTest : public ::testing::Test {
33public:
34 std::string runChangeNamespaceOnCode(llvm::StringRef Code) {
35 clang::RewriterTestContext Context;
36 clang::FileID ID = Context.createInMemoryFile(Name: FileName, Content: Code);
37
38 std::map<std::string, tooling::Replacements> FileToReplacements;
39 change_namespace::ChangeNamespaceTool NamespaceTool(
40 OldNamespace, NewNamespace, FilePattern,
41 /*AllowedSymbolPatterns*/ {}, &FileToReplacements);
42 ast_matchers::MatchFinder Finder;
43 NamespaceTool.registerMatchers(Finder: &Finder);
44 std::unique_ptr<tooling::FrontendActionFactory> Factory =
45 tooling::newFrontendActionFactory(ConsumerFactory: &Finder);
46 if (!tooling::runToolOnCodeWithArgs(ToolAction: Factory->create(), Code, Args: {"-std=c++11"},
47 FileName))
48 return "";
49 formatAndApplyAllReplacements(FileToReplaces: FileToReplacements, Rewrite&: Context.Rewrite);
50 return format(Code: Context.getRewrittenText(ID));
51 }
52
53 std::string format(llvm::StringRef Code) {
54 tooling::Replacements Replaces = format::reformat(
55 Style: format::getLLVMStyle(), Code, Ranges: {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(E: 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
101TEST_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 "} // namespace nb\n"
114 "} // namespace na\n";
115 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
116}
117
118TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithSurroundingNewLines) {
119 NewNamespace = "na::nb::nc";
120 std::string Code = "namespace na {\n"
121 "namespace nb {\n"
122 "\n"
123 "class A {};\n"
124 "\n"
125 "} // namespace nb\n"
126 "} // namespace na\n";
127 std::string Expected = "namespace na {\n"
128 "namespace nb {\n"
129 "namespace nc {\n"
130 "\n"
131 "class A {};\n"
132 "\n"
133 "} // namespace nc\n"
134 "} // namespace nb\n"
135 "} // namespace na\n";
136 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
137}
138
139TEST_F(ChangeNamespaceTest, MoveOldNsWithSurroundingNewLines) {
140 NewNamespace = "nx::ny";
141 std::string Code = "namespace na {\n"
142 "namespace nb {\n"
143 "\n"
144 "class A {};\n"
145 "\n"
146 "} // namespace nb\n"
147 "} // namespace na\n";
148 std::string Expected = "\n\n"
149 "namespace nx {\n"
150 "namespace ny {\n"
151 "\n"
152 "class A {};\n"
153 "\n"
154 "} // namespace ny\n"
155 "} // namespace nx\n";
156 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
157}
158
159TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithRefs) {
160 NewNamespace = "na::nb::nc";
161 std::string Code = "namespace na {\n"
162 "class A {};\n"
163 "namespace nb {\n"
164 "class B {};\n"
165 "class C {};\n"
166 "void f() { A a; B b; }\n"
167 "} // namespace nb\n"
168 "} // namespace na\n";
169 std::string Expected = "namespace na {\n"
170 "class A {};\n"
171 "namespace nb {\n"
172 "namespace nc {\n"
173 "class B {};\n"
174 "class C {};\n"
175 "void f() { A a; B b; }\n"
176 "} // namespace nc\n"
177 "} // namespace nb\n"
178 "} // namespace na\n";
179 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
180}
181
182TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) {
183 NewNamespace = "na::nc";
184 std::string Code = "namespace na {\n"
185 "namespace nb {\n"
186 "class A {};\n"
187 "} // namespace nb\n"
188 "} // namespace na\n";
189 std::string Expected = "namespace na {\n"
190 "\n"
191 "namespace nc {\n"
192 "class A {};\n"
193 "} // namespace nc\n"
194 "} // namespace na\n";
195 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
196}
197
198TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) {
199 NewNamespace = "na::nc";
200 std::string Code = "namespace na {\n"
201 "class A {};\n"
202 "namespace nb {\n"
203 "class X { A a; };\n"
204 "} // namespace nb\n"
205 "} // namespace na\n";
206 std::string Expected = "namespace na {\n"
207 "class A {};\n"
208 "\n"
209 "namespace nc {\n"
210 "class X { A a; };\n"
211 "} // namespace nc\n"
212 "} // namespace na\n";
213 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
214}
215
216TEST_F(ChangeNamespaceTest, MoveIntoExistingNamespaceAndShortenRefs) {
217 std::string Code = "namespace x {\n"
218 "namespace z {\n"
219 "class Z {};\n"
220 "} // namespace z\n"
221 "namespace y {\n"
222 "class T {};\n"
223 "} // namespace y\n"
224 "} // namespace x\n"
225 "namespace na {\n"
226 "class A{};\n"
227 "namespace nb {\n"
228 "class X { A a; x::z::Z zz; x::y::T t; };\n"
229 "} // namespace nb\n"
230 "} // namespace na\n";
231 std::string Expected = "namespace x {\n"
232 "namespace z {\n"
233 "class Z {};\n"
234 "} // namespace z\n"
235 "namespace y {\n"
236 "class T {};\n"
237 "} // namespace y\n"
238 "} // namespace x\n"
239 "namespace na {\n"
240 "class A {};\n\n"
241 "} // namespace na\n"
242 "namespace x {\n"
243 "namespace y {\n"
244 "class X { na::A a; z::Z zz; T t; };\n"
245 "} // namespace y\n"
246 "} // namespace x\n";
247 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
248}
249
250TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) {
251 NewNamespace = "na::x::y";
252 std::string Code = "namespace na {\n"
253 "class A {};\n"
254 "namespace nb {\n"
255 "class B {};\n"
256 "} // namespace nb\n"
257 "} // namespace na\n";
258 std::string Expected = "namespace na {\n"
259 "class A {};\n"
260 "\n"
261 "namespace x {\n"
262 "namespace y {\n"
263 "class B {};\n"
264 "} // namespace y\n"
265 "} // namespace x\n"
266 "} // namespace na\n";
267 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
268}
269
270TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) {
271 std::string Code = "namespace na {\n"
272 "class C_A {};\n"
273 "namespace nc {\n"
274 "class C_C {};"
275 "} // namespace nc\n"
276 "namespace nb {\n"
277 "class C_X {\n"
278 "public:\n"
279 " C_A a;\n"
280 " nc::C_C c;\n"
281 "};\n"
282 "class C_Y {\n"
283 " C_X x;\n"
284 "};\n"
285 "} // namespace nb\n"
286 "} // namespace na\n";
287 std::string Expected = "namespace na {\n"
288 "class C_A {};\n"
289 "namespace nc {\n"
290 "class C_C {};"
291 "} // namespace nc\n"
292 "\n"
293 "} // namespace na\n"
294 "namespace x {\n"
295 "namespace y {\n"
296 "class C_X {\n"
297 "public:\n"
298 " na::C_A a;\n"
299 " na::nc::C_C c;\n"
300 "};\n"
301 "class C_Y {\n"
302 " C_X x;\n"
303 "};\n"
304 "} // namespace y\n"
305 "} // namespace x\n";
306 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
307}
308
309TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) {
310 std::string Code = "namespace na {\n"
311 "class A {};\n"
312 "template <typename T>\n"
313 "class B {};\n"
314 "template <typename T1, typename T2>\n"
315 "class Two {};\n"
316 "namespace nc { class C {}; }\n"
317 "} // na\n"
318 "\n"
319 "namespace na {\n"
320 "namespace nb {\n"
321 "void f() {\n"
322 " B<A> b;\n"
323 " B<nc::C> b_c;\n"
324 " Two<A, nc::C> two;\n"
325 "}\n"
326 "} // nb\n"
327 "} // na\n";
328 std::string Expected = "namespace na {\n"
329 "class A {};\n"
330 "template <typename T>\n"
331 "class B {};\n"
332 "template <typename T1, typename T2>\n"
333 "class Two {};\n"
334 "namespace nc { class C {}; }\n"
335 "} // na\n"
336 "\n"
337 "\n"
338 "namespace x {\n"
339 "namespace y {\n"
340 "void f() {\n"
341 " na::B<na::A> b;\n"
342 " na::B<na::nc::C> b_c;\n"
343 " na::Two<na::A, na::nc::C> two;\n"
344 "}\n"
345 "} // namespace y\n"
346 "} // namespace x\n";
347 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
348}
349
350TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) {
351 std::string Code = "namespace na {\n"
352 "namespace nb {\n"
353 "class FWD;\n"
354 "class FWD2;\n"
355 "class A {\n"
356 " FWD *fwd;\n"
357 "};\n"
358 "} // namespace nb\n"
359 "} // namespace na\n";
360 std::string Expected = "namespace na {\n"
361 "namespace nb {\n"
362 "class FWD;\n"
363 "class FWD2;\n"
364 "} // namespace nb\n"
365 "} // namespace na\n"
366 "namespace x {\n"
367 "namespace y {\n"
368 "\n"
369 "class A {\n"
370 " na::nb::FWD *fwd;\n"
371 "};\n"
372 "} // namespace y\n"
373 "} // namespace x\n";
374 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
375}
376
377TEST_F(ChangeNamespaceTest, InsertForwardDeclsProperly) {
378 std::string Code = "namespace na {\n"
379 "namespace nb {\n"
380 "\n"
381 "class FWD;\n"
382 "class FWD2;\n"
383 "class A {\n"
384 " FWD *fwd;\n"
385 "};\n"
386 "\n"
387 "} // namespace nb\n"
388 "} // namespace na\n";
389 std::string Expected = "namespace na {\n"
390 "namespace nb {\n"
391 "class FWD;\n"
392 "class FWD2;\n"
393 "} // namespace nb\n"
394 "} // namespace na\n"
395 "namespace x {\n"
396 "namespace y {\n"
397 "\n"
398 "class A {\n"
399 " na::nb::FWD *fwd;\n"
400 "};\n"
401 "\n"
402 "} // namespace y\n"
403 "} // namespace x\n";
404 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
405}
406
407TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) {
408 std::string Code = "namespace na {\n"
409 "namespace nb {\n"
410 "class FWD;\n"
411 "template<typename T> class FWD_TEMP;\n"
412 "class A {\n"
413 " FWD *fwd;\n"
414 "};\n"
415 "template<typename T> class TEMP {};\n"
416 "} // namespace nb\n"
417 "} // namespace na\n";
418 std::string Expected = "namespace na {\n"
419 "namespace nb {\n"
420 "class FWD;\n"
421 "template<typename T> class FWD_TEMP;\n"
422 "} // namespace nb\n"
423 "} // namespace na\n"
424 "namespace x {\n"
425 "namespace y {\n"
426 "\n"
427 "class A {\n"
428 " na::nb::FWD *fwd;\n"
429 "};\n"
430 "template<typename T> class TEMP {};\n"
431 "} // namespace y\n"
432 "} // namespace x\n";
433 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
434}
435
436TEST_F(ChangeNamespaceTest, DontMoveForwardDeclarationInClass) {
437 std::string Code = "namespace na {\n"
438 "namespace nb {\n"
439 "class A {\n"
440 " class FWD;\n"
441 " FWD *fwd;\n"
442 " template<typename T> class FWD_TEMP;\n"
443 "};\n"
444 "} // namespace nb\n"
445 "} // namespace na\n";
446 std::string Expected = "\n\n"
447 "namespace x {\n"
448 "namespace y {\n"
449 "class A {\n"
450 " class FWD;\n"
451 " FWD *fwd;\n"
452 " template<typename T> class FWD_TEMP;\n"
453 "};\n"
454 "} // namespace y\n"
455 "} // namespace x\n";
456 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
457}
458
459TEST_F(ChangeNamespaceTest, MoveFunctions) {
460 std::string Code = "namespace na {\n"
461 "class C_A {};\n"
462 "namespace nc {\n"
463 "class C_C {};"
464 "} // namespace nc\n"
465 "namespace nb {\n"
466 "void fwd();\n"
467 "void f(C_A ca, nc::C_C cc) {\n"
468 " C_A ca_1 = ca;\n"
469 "}\n"
470 "} // namespace nb\n"
471 "} // namespace na\n";
472
473 std::string Expected = "namespace na {\n"
474 "class C_A {};\n"
475 "namespace nc {\n"
476 "class C_C {};"
477 "} // namespace nc\n"
478 "\n"
479 "} // namespace na\n"
480 "namespace x {\n"
481 "namespace y {\n"
482 "void fwd();\n"
483 "void f(na::C_A ca, na::nc::C_C cc) {\n"
484 " na::C_A ca_1 = ca;\n"
485 "}\n"
486 "} // namespace y\n"
487 "} // namespace x\n";
488 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
489}
490
491TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) {
492 std::string Code = "class GLOB {};\n"
493 "using BLOG = GLOB;\n"
494 "namespace na {\n"
495 "namespace nc {\n"
496 "class SAME {};\n"
497 "}\n"
498 "namespace nd {\n"
499 "class SAME {};\n"
500 "}\n"
501 "namespace nb {\n"
502 "using nc::SAME;\n"
503 "using YO = nd::SAME;\n"
504 "typedef nd::SAME IDENTICAL;\n"
505 "void f(nd::SAME Same) {}\n"
506 "} // namespace nb\n"
507 "} // namespace na\n";
508
509 std::string Expected = "class GLOB {};\n"
510 "using BLOG = GLOB;\n"
511 "namespace na {\n"
512 "namespace nc {\n"
513 "class SAME {};\n"
514 "}\n"
515 "namespace nd {\n"
516 "class SAME {};\n"
517 "}\n"
518 "\n"
519 "} // namespace na\n"
520 "namespace x {\n"
521 "namespace y {\n"
522 "using ::na::nc::SAME;\n"
523 "using YO = na::nd::SAME;\n"
524 "typedef na::nd::SAME IDENTICAL;\n"
525 "void f(na::nd::SAME Same) {}\n"
526 "} // namespace y\n"
527 "} // namespace x\n";
528 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
529}
530
531TEST_F(ChangeNamespaceTest, DontFixUsingShadowDeclInClasses) {
532 std::string Code = "namespace na {\n"
533 "class A {};\n"
534 "class Base { public: Base() {} void m() {} };\n"
535 "namespace nb {\n"
536 "class D : public Base {\n"
537 "public:\n"
538 " using AA = A; using B = Base;\n"
539 " using Base::m; using Base::Base;\n"
540 "};"
541 "} // namespace nb\n"
542 "} // namespace na\n";
543
544 std::string Expected = "namespace na {\n"
545 "class A {};\n"
546 "class Base { public: Base() {} void m() {} };\n"
547 "\n"
548 "} // namespace na\n"
549 "namespace x {\n"
550 "namespace y {\n"
551 "class D : public na::Base {\n"
552 "public:\n"
553 " using AA = na::A; using B = na::Base;\n"
554 " using Base::m; using Base::Base;\n"
555 "};"
556 "} // namespace y\n"
557 "} // namespace x\n";
558 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
559}
560
561TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) {
562 std::string Code =
563 "namespace na {\n"
564 "class C_A {\n"
565 "public:\n"
566 " class Nested {\n"
567 " public:\n"
568 " static int NestedX;\n"
569 " static void nestedFunc() {}\n"
570 " };\n"
571 "};\n"
572 "namespace nb {\n"
573 "class C_X {\n"
574 " C_A na;\n"
575 " C_A::Nested nested;\n"
576 " void f() {\n"
577 " C_A::Nested::nestedFunc();\n"
578 " int X = C_A::Nested::NestedX;\n"
579 " }\n"
580 "};\n"
581 "} // namespace nb\n"
582 "} // namespace na\n";
583 std::string Expected =
584 "namespace na {\n"
585 "class C_A {\n"
586 "public:\n"
587 " class Nested {\n"
588 " public:\n"
589 " static int NestedX;\n"
590 " static void nestedFunc() {}\n"
591 " };\n"
592 "};\n"
593 "\n"
594 "} // namespace na\n"
595 "namespace x {\n"
596 "namespace y {\n"
597 "class C_X {\n"
598 " na::C_A na;\n"
599 " na::C_A::Nested nested;\n"
600 " void f() {\n"
601 " na::C_A::Nested::nestedFunc();\n"
602 " int X = na::C_A::Nested::NestedX;\n"
603 " }\n"
604 "};\n"
605 "} // namespace y\n"
606 "} // namespace x\n";
607 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
608}
609
610TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
611 std::string Code =
612 "namespace na {\n"
613 "class A {\n"
614 "public:\n"
615 " static void f() {}\n"
616 " static void g();\n"
617 "};\n"
618 "void A::g() {}"
619 "void a_f() {}\n"
620 "static void static_f() {}\n"
621 "namespace nb {\n"
622 "void f() { a_f(); static_f(); A::f(); }\n"
623 "void g() { f(); A::g(); }\n"
624 "} // namespace nb\n"
625 "} // namespace na\n";
626 std::string Expected =
627 "namespace na {\n"
628 "class A {\n"
629 "public:\n"
630 " static void f() {}\n"
631 " static void g();\n"
632 "};\n"
633 "void A::g() {}"
634 "void a_f() {}\n"
635 "static void static_f() {}\n"
636 "\n"
637 "} // namespace na\n"
638 "namespace x {\n"
639 "namespace y {\n"
640 "void f() { na::a_f(); na::static_f(); na::A::f(); }\n"
641 "void g() { f(); na::A::g(); }\n"
642 "} // namespace y\n"
643 "} // namespace x\n";
644 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
645}
646
647TEST_F(ChangeNamespaceTest, FixOverloadedOperatorFunctionNameSpecifiers) {
648 std::string Code =
649 "namespace na {\n"
650 "class A {\n"
651 "public:\n"
652 " int x;\n"
653 " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
654 "};\n"
655 "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
656 "namespace nb {\n"
657 "bool f() {\n"
658 " A x, y;\n"
659 " auto f = operator<;\n"
660 " return (x == y) && (x < y) && (operator<(x, y));\n"
661 "}\n"
662 "} // namespace nb\n"
663 "} // namespace na\n";
664 std::string Expected =
665 "namespace na {\n"
666 "class A {\n"
667 "public:\n"
668 " int x;\n"
669 " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
670 "};\n"
671 "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
672 "\n"
673 "} // namespace na\n"
674 "namespace x {\n"
675 "namespace y {\n"
676 "bool f() {\n"
677 " na::A x, y;\n"
678 " auto f = na::operator<;\n"
679 // FIXME: function calls to overloaded operators are not fixed now even if
680 // they are referenced by qualified names.
681 " return (x == y) && (x < y) && (operator<(x,y));\n"
682 "}\n"
683 "} // namespace y\n"
684 "} // namespace x\n";
685 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
686}
687
688TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
689 std::string Code = "namespace na {\n"
690 "class A {\n"
691 "public:\n"
692 " static void f() {}\n"
693 "};\n"
694 "void a_f() {}\n"
695 "static void s_f() {}\n"
696 "namespace nb {\n"
697 "void f() {\n"
698 " auto *ref1 = A::f;\n"
699 " auto *ref2 = a_f;\n"
700 " auto *ref3 = s_f;\n"
701 "}\n"
702 "} // namespace nb\n"
703 "} // namespace na\n";
704 std::string Expected =
705 "namespace na {\n"
706 "class A {\n"
707 "public:\n"
708 " static void f() {}\n"
709 "};\n"
710 "void a_f() {}\n"
711 "static void s_f() {}\n"
712 "\n"
713 "} // namespace na\n"
714 "namespace x {\n"
715 "namespace y {\n"
716 "void f() {\n"
717 " auto *ref1 = na::A::f;\n"
718 " auto *ref2 = na::a_f;\n"
719 " auto *ref3 = na::s_f;\n"
720 "}\n"
721 "} // namespace y\n"
722 "} // namespace x\n";
723 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
724}
725
726TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
727 std::string Code = "namespace na {\n"
728 "int GlobA;\n"
729 "static int GlobAStatic = 0;\n"
730 "namespace nc { int GlobC; }\n"
731 "namespace nb {\n"
732 "int GlobB;\n"
733 "void f() {\n"
734 " int a = GlobA;\n"
735 " int b = GlobAStatic;\n"
736 " int c = nc::GlobC;\n"
737 "}\n"
738 "} // namespace nb\n"
739 "} // namespace na\n";
740
741 std::string Expected = "namespace na {\n"
742 "int GlobA;\n"
743 "static int GlobAStatic = 0;\n"
744 "namespace nc { int GlobC; }\n"
745 "\n"
746 "} // namespace na\n"
747 "namespace x {\n"
748 "namespace y {\n"
749 "int GlobB;\n"
750 "void f() {\n"
751 " int a = na::GlobA;\n"
752 " int b = na::GlobAStatic;\n"
753 " int c = na::nc::GlobC;\n"
754 "}\n"
755 "} // namespace y\n"
756 "} // namespace x\n";
757
758 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
759}
760
761TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
762 std::string Code = "namespace na {\n"
763 "class A {\n"
764 "public:\n"
765 "static int A1;\n"
766 "static int A2;\n"
767 "};\n"
768 "int A::A1 = 0;\n"
769 "namespace nb {\n"
770 "void f() {\n"
771 " int a = A::A1; int b = A::A2;\n"
772 "}\n"
773 "} // namespace nb\n"
774 "} // namespace na\n";
775
776 std::string Expected = "namespace na {\n"
777 "class A {\n"
778 "public:\n"
779 "static int A1;\n"
780 "static int A2;\n"
781 "};\n"
782 "int A::A1 = 0;\n"
783 "\n"
784 "} // namespace na\n"
785 "namespace x {\n"
786 "namespace y {\n"
787 "void f() {\n"
788 " int a = na::A::A1; int b = na::A::A2;\n"
789 "}\n"
790 "} // namespace y\n"
791 "} // namespace x\n";
792
793 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
794}
795
796TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) {
797 std::string Code = "namespace na {\n"
798 "namespace nb {\n"
799 "class A;\n"
800 "class B {};\n"
801 "}"
802 "}";
803 std::string Expected = "namespace na {\n"
804 "namespace nb {\n"
805 "class A;\n"
806 "}\n"
807 "}\n"
808 "namespace x {\n"
809 "namespace y {\n"
810 "\n"
811 "class B {};\n"
812 "} // namespace y\n"
813 "} // namespace x\n";
814 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
815}
816
817TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) {
818 std::string Code = "namespace na {\n"
819 "namespace nb {\n"
820 "\n\n"
821 "// Wild comments.\n"
822 "\n"
823 "// Comments.\n"
824 "// More comments.\n"
825 "class B {\n"
826 " // Private comments.\n"
827 " int a;\n"
828 "};\n"
829 "}\n"
830 "}";
831 std::string Expected = "\n"
832 "\n"
833 "namespace x {\n"
834 "namespace y {\n"
835 "\n\n"
836 "// Wild comments.\n"
837 "\n"
838 "// Comments.\n"
839 "// More comments.\n"
840 "class B {\n"
841 " // Private comments.\n"
842 " int a;\n"
843 "};\n"
844 "} // namespace y\n"
845 "} // namespace x\n";
846 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
847}
848
849TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) {
850 std::string Code = "namespace glob {\n"
851 "class Glob {};\n"
852 "void GFunc() {}\n"
853 "}\n"
854 "using glob::Glob;\n"
855 "using glob::GFunc;\n"
856 "namespace na {\n"
857 "namespace nb {\n"
858 "void f() { Glob g; GFunc(); }\n"
859 "} // namespace nb\n"
860 "} // namespace na\n";
861
862 std::string Expected = "namespace glob {\n"
863 "class Glob {};\n"
864 "void GFunc() {}\n"
865 "}\n"
866 "using glob::Glob;\n"
867 "using glob::GFunc;\n"
868 "\n"
869 "namespace x {\n"
870 "namespace y {\n"
871 "void f() { Glob g; GFunc(); }\n"
872 "} // namespace y\n"
873 "} // namespace x\n";
874 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
875}
876
877TEST_F(ChangeNamespaceTest, UsingShadowDeclsInAnonymousNamespaces) {
878 std::string Code = "namespace util {\n"
879 "class Util {};\n"
880 "void func() {}\n"
881 "}\n"
882 "namespace na {\n"
883 "namespace nb {\n"
884 "namespace {\n"
885 "using ::util::Util;\n"
886 "using ::util::func;\n"
887 "void f() { Util u; func(); }\n"
888 "}\n"
889 "} // namespace nb\n"
890 "} // namespace na\n";
891
892 std::string Expected = "namespace util {\n"
893 "class Util {};\n"
894 "void func() {}\n"
895 "} // namespace util\n"
896 "\n"
897 "namespace x {\n"
898 "namespace y {\n"
899 "namespace {\n"
900 "using ::util::Util;\n"
901 "using ::util::func;\n"
902 "void f() { Util u; func(); }\n"
903 "}\n"
904 "} // namespace y\n"
905 "} // namespace x\n";
906 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
907}
908
909TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) {
910 std::string Code = "namespace glob {\n"
911 "class Glob {};\n"
912 "}\n"
913 "using namespace glob;\n"
914 "namespace na {\n"
915 "namespace nb {\n"
916 "void f() { Glob g; }\n"
917 "} // namespace nb\n"
918 "} // namespace na\n";
919
920 std::string Expected = "namespace glob {\n"
921 "class Glob {};\n"
922 "}\n"
923 "using namespace glob;\n"
924 "\n"
925 "namespace x {\n"
926 "namespace y {\n"
927 "void f() { Glob g; }\n"
928 "} // namespace y\n"
929 "} // namespace x\n";
930 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
931}
932
933TEST_F(ChangeNamespaceTest, NamespaceAliasInGlobal) {
934 std::string Code = "namespace glob {\n"
935 "class Glob {};\n"
936 "}\n"
937 "namespace glob2 { class Glob2 {}; }\n"
938 "namespace gl = glob;\n"
939 "namespace gl2 = glob2;\n"
940 "namespace na {\n"
941 "namespace nb {\n"
942 "void f() { gl::Glob g; gl2::Glob2 g2; }\n"
943 "} // namespace nb\n"
944 "} // namespace na\n";
945
946 std::string Expected =
947 "namespace glob {\n"
948 "class Glob {};\n"
949 "}\n"
950 "namespace glob2 { class Glob2 {}; }\n"
951 "namespace gl = glob;\n"
952 "namespace gl2 = glob2;\n"
953 "\n"
954 "namespace x {\n"
955 "namespace y {\n"
956 "void f() { gl::Glob g; gl2::Glob2 g2; }\n"
957 "} // namespace y\n"
958 "} // namespace x\n";
959 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
960}
961
962TEST_F(ChangeNamespaceTest, NamespaceAliasInNamespace) {
963 std::string Code = "namespace glob {\n"
964 "class Glob {};\n"
965 "}\n"
966 "namespace na {\n"
967 "namespace nb {\n"
968 "namespace gl = glob;\n"
969 "void f() { gl::Glob g; }\n"
970 "} // namespace nb\n"
971 "} // namespace na\n";
972
973 std::string Expected = "namespace glob {\n"
974 "class Glob {};\n"
975 "}\n"
976 "\n"
977 "namespace x {\n"
978 "namespace y {\n"
979 "namespace gl = glob;\n"
980 "void f() { gl::Glob g; }\n"
981 "} // namespace y\n"
982 "} // namespace x\n";
983 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
984}
985
986TEST_F(ChangeNamespaceTest, NamespaceAliasInAncestorNamespace) {
987 NewNamespace = "na::nx";
988 std::string Code = "namespace glob {\n"
989 "class Glob {};\n"
990 "}\n"
991 "namespace other { namespace gl = glob; }\n"
992 "namespace na {\n"
993 "namespace ga = glob;\n"
994 "namespace nb {\n"
995 "void f() { ga::Glob g; }\n"
996 "} // namespace nb\n"
997 "} // namespace na\n";
998
999 std::string Expected = "namespace glob {\n"
1000 "class Glob {};\n"
1001 "}\n"
1002 "namespace other { namespace gl = glob; }\n"
1003 "namespace na {\n"
1004 "namespace ga = glob;\n"
1005 "\n"
1006 "namespace nx {\n"
1007 "void f() { ga::Glob g; }\n"
1008 "} // namespace nx\n"
1009 "} // namespace na\n";
1010 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1011}
1012
1013TEST_F(ChangeNamespaceTest, NamespaceAliasInOtherNamespace) {
1014 std::string Code = "namespace glob {\n"
1015 "class Glob {};\n"
1016 "}\n"
1017 "namespace other { namespace gl = glob; }\n"
1018 "namespace na {\n"
1019 "namespace ga = glob;\n"
1020 "namespace nb {\n"
1021 "void f() { glob::Glob g; }\n"
1022 "} // namespace nb\n"
1023 "} // namespace na\n";
1024
1025 std::string Expected = "namespace glob {\n"
1026 "class Glob {};\n"
1027 "}\n"
1028 "namespace other { namespace gl = glob; }\n"
1029 "namespace na {\n"
1030 "namespace ga = glob;\n"
1031 "\n"
1032 "} // namespace na\n"
1033 "namespace x {\n"
1034 "namespace y {\n"
1035 "void f() { glob::Glob g; }\n"
1036 "} // namespace y\n"
1037 "} // namespace x\n";
1038 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1039}
1040
1041TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) {
1042 std::string Code = "namespace glob {\n"
1043 "class Glob {};\n"
1044 "}\n"
1045 "namespace na {\n"
1046 "namespace nb {\n"
1047 "void f() { glob::Glob g; }\n"
1048 "} // namespace nb\n"
1049 "} // namespace na\n"
1050 "using glob::Glob;\n"
1051 "using namespace glob;\n";
1052
1053 std::string Expected = "namespace glob {\n"
1054 "class Glob {};\n"
1055 "}\n"
1056 "\n"
1057 "namespace x {\n"
1058 "namespace y {\n"
1059 "void f() { glob::Glob g; }\n"
1060 "} // namespace y\n"
1061 "} // namespace x\n"
1062 "using glob::Glob;\n"
1063 "using namespace glob;\n";
1064 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1065}
1066
1067TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) {
1068 NewNamespace = "na::nc";
1069 std::string Code = "namespace glob {\n"
1070 "class Glob {};\n"
1071 "}\n"
1072 "namespace na {\n"
1073 "namespace nb {\n"
1074 "void f() { glob::Glob g; }\n"
1075 "} // namespace nb\n"
1076 "using namespace glob;\n"
1077 "} // namespace na\n";
1078
1079 std::string Expected = "namespace glob {\n"
1080 "class Glob {};\n"
1081 "}\n"
1082 "namespace na {\n"
1083 "\n"
1084 "namespace nc {\n"
1085 "void f() { glob::Glob g; }\n"
1086 "} // namespace nc\n"
1087 "using namespace glob;\n"
1088 "} // namespace na\n";
1089 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1090}
1091
1092TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) {
1093 std::string Code = "namespace glob1 {\n"
1094 "namespace glob2 {\n"
1095 "class Glob {};\n"
1096 "}\n"
1097 "}\n"
1098 "using glob1::glob2::Glob;\n"
1099 "using namespace glob1;\n"
1100 "namespace na {\n"
1101 "namespace nb {\n"
1102 "void f() { Glob g; }\n"
1103 "} // namespace nb\n"
1104 "} // namespace na\n";
1105
1106 std::string Expected = "namespace glob1 {\n"
1107 "namespace glob2 {\n"
1108 "class Glob {};\n"
1109 "}\n"
1110 "}\n"
1111 "using glob1::glob2::Glob;\n"
1112 "using namespace glob1;\n"
1113 "\n"
1114 "namespace x {\n"
1115 "namespace y {\n"
1116 "void f() { Glob g; }\n"
1117 "} // namespace y\n"
1118 "} // namespace x\n";
1119 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1120}
1121
1122TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) {
1123 std::string Code = "namespace glob {\n"
1124 "class Glob {};\n"
1125 "}\n"
1126 "using GLB = glob::Glob;\n"
1127 "using BLG = glob::Glob;\n"
1128 "namespace na {\n"
1129 "namespace nb {\n"
1130 "void f() { GLB g; BLG blg; }\n"
1131 "} // namespace nb\n"
1132 "} // namespace na\n";
1133
1134 std::string Expected = "namespace glob {\n"
1135 "class Glob {};\n"
1136 "}\n"
1137 "using GLB = glob::Glob;\n"
1138 "using BLG = glob::Glob;\n"
1139 "\n"
1140 "namespace x {\n"
1141 "namespace y {\n"
1142 "void f() { GLB g; BLG blg; }\n"
1143 "} // namespace y\n"
1144 "} // namespace x\n";
1145 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1146}
1147
1148TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) {
1149 std::string Code = "namespace na { class C_A {};\n }\n"
1150 "using na::C_A;\n"
1151 "namespace na {\n"
1152 "namespace nb {\n"
1153 "class C_X {\n"
1154 "public:\n"
1155 " C_A a;\n"
1156 "};\n"
1157 "} // namespace nb\n"
1158 "} // namespace na\n";
1159 std::string Expected = "namespace na { class C_A {};\n }\n"
1160 "using na::C_A;\n"
1161 "\n"
1162 "namespace x {\n"
1163 "namespace y {\n"
1164 "class C_X {\n"
1165 "public:\n"
1166 " C_A a;\n"
1167 "};\n"
1168 "} // namespace y\n"
1169 "} // namespace x\n";
1170 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1171}
1172
1173TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) {
1174 std::string Code = "namespace na { class C_A {};\n }\n"
1175 "using namespace na;\n"
1176 "namespace na {\n"
1177 "namespace nb {\n"
1178 "class C_X {\n"
1179 "public:\n"
1180 " C_A ca;\n"
1181 "};\n"
1182 "} // namespace nb\n"
1183 "} // namespace na\n";
1184 std::string Expected = "namespace na { class C_A {};\n }\n"
1185 "using namespace na;\n"
1186 "\n"
1187 "namespace x {\n"
1188 "namespace y {\n"
1189 "class C_X {\n"
1190 "public:\n"
1191 " C_A ca;\n"
1192 "};\n"
1193 "} // namespace y\n"
1194 "} // namespace x\n";
1195 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1196}
1197
1198TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) {
1199 std::string Code = "namespace glob {\n"
1200 "class Glob {};\n"
1201 "}\n"
1202 "namespace na {\n"
1203 "namespace nb {\n"
1204 "void f() {\n"
1205 " using glob::Glob;\n"
1206 " Glob g;\n"
1207 "}\n"
1208 "} // namespace nb\n"
1209 "} // namespace na\n";
1210
1211 std::string Expected = "namespace glob {\n"
1212 "class Glob {};\n"
1213 "}\n"
1214 "\n"
1215 "namespace x {\n"
1216 "namespace y {\n"
1217 "void f() {\n"
1218 " using ::glob::Glob;\n"
1219 " Glob g;\n"
1220 "}\n"
1221 "} // namespace y\n"
1222 "} // namespace x\n";
1223 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1224}
1225
1226TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) {
1227 std::string Code = "namespace na { class C_A {}; }\n"
1228 "namespace na {\n"
1229 "namespace nb {\n"
1230 "void f() {\n"
1231 " using ::na::C_A;\n"
1232 " C_A ca;\n"
1233 "}\n"
1234 "} // namespace nb\n"
1235 "} // namespace na\n";
1236 std::string Expected = "namespace na { class C_A {}; }\n"
1237 "\n"
1238 "namespace x {\n"
1239 "namespace y {\n"
1240 "void f() {\n"
1241 " using ::na::C_A;\n"
1242 " C_A ca;\n"
1243 "}\n"
1244 "} // namespace y\n"
1245 "} // namespace x\n";
1246 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1247}
1248
1249TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) {
1250 std::string Code = "namespace nx { void f(); }\n"
1251 "namespace na {\n"
1252 "using nx::f;\n"
1253 "namespace nb {\n"
1254 "void d() { f(); }\n"
1255 "} // nb\n"
1256 "} // na\n";
1257
1258 std::string Expected = "namespace nx { void f(); }\n"
1259 "namespace na {\n"
1260 "using nx::f;\n"
1261 "\n"
1262 "} // na\n"
1263 "namespace x {\n"
1264 "namespace y {\n"
1265 "void d() { nx::f(); }\n"
1266 "} // namespace y\n"
1267 "} // namespace x\n";
1268 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1269}
1270
1271TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) {
1272 OldNamespace = "na";
1273 std::string Code = "namespace nx { void f(); }\n"
1274 "namespace na {\n"
1275 "using ::nx::f;\n"
1276 "void d() { f(); }\n"
1277 "} // na\n";
1278
1279 std::string Expected = "namespace nx { void f(); }\n"
1280 "\n"
1281 "namespace x {\n"
1282 "namespace y {\n"
1283 "using ::nx::f;\n"
1284 "void d() { f(); }\n"
1285 "} // namespace y\n"
1286 "} // namespace x\n";
1287 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1288}
1289
1290TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
1291 OldNamespace = "a::b::c::d";
1292 NewNamespace = "a::b::x::y";
1293 std::string Code = "namespace nx { void f(); void g(); }\n"
1294 "namespace a {\n"
1295 "namespace b {\n"
1296 "using ::nx::f;\n"
1297 "namespace c {\n"
1298 "using ::nx::g;\n"
1299 "namespace d {\n"
1300 "void d() { f(); g(); }\n"
1301 "} // d\n"
1302 "} // c\n"
1303 "} // b\n"
1304 "} // a\n";
1305
1306 std::string Expected = "namespace nx { void f(); void g(); }\n"
1307 "namespace a {\n"
1308 "namespace b {\n"
1309 "using ::nx::f;\n"
1310 "namespace c {\n"
1311 "using ::nx::g;\n"
1312 "\n"
1313 "} // c\n"
1314 "namespace x {\n"
1315 "namespace y {\n"
1316 "void d() { f(); nx::g(); }\n"
1317 "} // namespace y\n"
1318 "} // namespace x\n"
1319 "} // b\n"
1320 "} // a\n";
1321 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1322}
1323
1324TEST_F(ChangeNamespaceTest, UsingShadowDeclInTheParentOfOldNamespace) {
1325 OldNamespace = "nb::nc";
1326 NewNamespace = "nb::nd";
1327 std::string Code = "namespace na { class A {}; }\n"
1328 "namespace nb {\n"
1329 "using na::A;\n"
1330 "namespace nc {\n"
1331 "void d() { A a; }\n"
1332 "} // nc\n"
1333 "} // nb\n";
1334
1335 std::string Expected = "namespace na { class A {}; }\n"
1336 "namespace nb {\n"
1337 "using na::A;\n"
1338 "\n"
1339 "namespace nd {\n"
1340 "void d() { A a; }\n"
1341 "} // namespace nd\n"
1342 "} // nb\n";
1343 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1344}
1345
1346TEST_F(ChangeNamespaceTest, UsingShadowDeclInOldNamespace) {
1347 OldNamespace = "nb";
1348 NewNamespace = "nc";
1349 std::string Code = "namespace na { class A {}; }\n"
1350 "namespace nb {\n"
1351 "using na::A;\n"
1352 "void d() { A a; }\n"
1353 "struct X { A a; };\n"
1354 "} // nb\n";
1355
1356 std::string Expected = "namespace na { class A {}; }\n"
1357 "\n"
1358 "namespace nc {\n"
1359 "using ::na::A;\n"
1360 "void d() { A a; }\n"
1361 "struct X { A a; };\n"
1362 "} // namespace nc\n";
1363 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1364}
1365
1366TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateClass) {
1367 OldNamespace = "nb";
1368 NewNamespace = "nc";
1369 std::string Code = "namespace na {\n"
1370 "template <typename T>\n"
1371 "class A { T t; };\n"
1372 "} // namespace na\n"
1373 "namespace nb {\n"
1374 "using na::A;\n"
1375 "void d() { A<int> a; }\n"
1376 "} // nb\n";
1377
1378 std::string Expected = "namespace na {\n"
1379 "template <typename T>\n"
1380 "class A { T t; };\n"
1381 "} // namespace na\n"
1382 "\n"
1383 "namespace nc {\n"
1384 "using ::na::A;\n"
1385 "void d() { A<int> a; }\n"
1386 "} // namespace nc\n";
1387 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1388}
1389
1390TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateFunction) {
1391 OldNamespace = "nb";
1392 NewNamespace = "nc";
1393 std::string Code = "namespace na {\n"
1394 "template <typename T>\n"
1395 "void f() { T t; };\n"
1396 "} // namespace na\n"
1397 "namespace nb {\n"
1398 "using na::f;\n"
1399 "void d() { f<int>(); }\n"
1400 "} // nb\n";
1401
1402 std::string Expected = "namespace na {\n"
1403 "template <typename T>\n"
1404 "void f() { T t; };\n"
1405 "} // namespace na\n"
1406 "\n"
1407 "namespace nc {\n"
1408 "using ::na::f;\n"
1409 "void d() { f<int>(); }\n"
1410 "} // namespace nc\n";
1411 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1412}
1413
1414TEST_F(ChangeNamespaceTest, UsingAliasDecl) {
1415 std::string Code =
1416 "namespace nx { namespace ny { class X {}; } }\n"
1417 "namespace na {\n"
1418 "namespace nb {\n"
1419 "using Y = nx::ny::X;\n"
1420 "void f() { Y y; }\n"
1421 "} // namespace nb\n"
1422 "} // namespace na\n";
1423
1424 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1425 "\n"
1426 "namespace x {\n"
1427 "namespace y {\n"
1428 "using Y = nx::ny::X;\n"
1429 "void f() { Y y; }\n"
1430 "} // namespace y\n"
1431 "} // namespace x\n";
1432 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1433}
1434
1435TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) {
1436 std::string Code =
1437 "namespace nx { namespace ny { class X {}; } }\n"
1438 "using Y = nx::ny::X;\n"
1439 "namespace na {\n"
1440 "namespace nb {\n"
1441 "void f() { Y y; }\n"
1442 "} // namespace nb\n"
1443 "} // namespace na\n";
1444
1445 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1446 "using Y = nx::ny::X;\n"
1447 "\n"
1448 "namespace x {\n"
1449 "namespace y {\n"
1450 "void f() { Y y; }\n"
1451 "} // namespace y\n"
1452 "} // namespace x\n";
1453 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1454}
1455
1456
1457TEST_F(ChangeNamespaceTest, TypedefAliasDecl) {
1458 std::string Code =
1459 "namespace nx { namespace ny { class X {}; } }\n"
1460 "namespace na {\n"
1461 "namespace nb {\n"
1462 "typedef nx::ny::X Y;\n"
1463 "void f() { Y y; }\n"
1464 "} // namespace nb\n"
1465 "} // namespace na\n";
1466
1467 std::string Expected = "namespace nx { namespace ny { class X {}; } }\n"
1468 "\n"
1469 "namespace x {\n"
1470 "namespace y {\n"
1471 "typedef nx::ny::X Y;\n"
1472 "void f() { Y y; }\n"
1473 "} // namespace y\n"
1474 "} // namespace x\n";
1475 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1476}
1477
1478TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) {
1479 std::string Code =
1480 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1481 "namespace na {\n"
1482 "namespace nb {\n"
1483 "class A : public nx::ny::X {\n"
1484 "public:\n"
1485 " A() : X(0) {}\n"
1486 " A(int i);\n"
1487 "};\n"
1488 "A::A(int i) : X(i) {}\n"
1489 "} // namespace nb\n"
1490 "} // namespace na\n";
1491 std::string Expected =
1492 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1493 "\n\n"
1494 "namespace x {\n"
1495 "namespace y {\n"
1496 "class A : public nx::ny::X {\n"
1497 "public:\n"
1498 " A() : X(0) {}\n"
1499 " A(int i);\n"
1500 "};\n"
1501 "A::A(int i) : X(i) {}\n"
1502 "} // namespace y\n"
1503 "} // namespace x\n";
1504 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1505}
1506
1507TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) {
1508 std::string Code =
1509 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1510 "namespace na {\n"
1511 "namespace nb {\n"
1512 "class A : public nx::ny::X {\n"
1513 "public:\n"
1514 " A() : X::X(0) {}\n"
1515 " A(int i);\n"
1516 "};\n"
1517 "A::A(int i) : X::X(i) {}\n"
1518 "} // namespace nb\n"
1519 "} // namespace na\n";
1520 std::string Expected =
1521 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1522 "\n\n"
1523 "namespace x {\n"
1524 "namespace y {\n"
1525 "class A : public nx::ny::X {\n"
1526 "public:\n"
1527 " A() : X::X(0) {}\n"
1528 " A(int i);\n"
1529 "};\n"
1530 "A::A(int i) : X::X(i) {}\n"
1531 "} // namespace y\n"
1532 "} // namespace x\n";
1533 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1534}
1535
1536TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) {
1537 std::string Code =
1538 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1539 "namespace na {\n"
1540 "namespace nb {\n"
1541 "class A : public nx::ny::X {\n"
1542 "public:\n"
1543 " A() : X(0) {}\n"
1544 " A(int i);\n"
1545 "};\n"
1546 "A::A(int i) : X(i) { X x(1);}\n"
1547 "} // namespace nb\n"
1548 "} // namespace na\n";
1549 std::string Expected =
1550 "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n"
1551 "\n\n"
1552 "namespace x {\n"
1553 "namespace y {\n"
1554 "class A : public nx::ny::X {\n"
1555 "public:\n"
1556 " A() : X(0) {}\n"
1557 " A(int i);\n"
1558 "};\n"
1559 "A::A(int i) : X(i) { nx::ny::X x(1);}\n"
1560 "} // namespace y\n"
1561 "} // namespace x\n";
1562 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1563}
1564
1565TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) {
1566 NewNamespace = "";
1567 std::string Code = "namespace na {\n"
1568 "class C_A {};\n"
1569 "namespace nc {\n"
1570 "class C_C {};"
1571 "} // namespace nc\n"
1572 "namespace nb {\n"
1573 "class C_X {\n"
1574 "public:\n"
1575 " C_A a;\n"
1576 " nc::C_C c;\n"
1577 "};\n"
1578 "class C_Y {\n"
1579 " C_X x;\n"
1580 "};\n"
1581 "} // namespace nb\n"
1582 "} // namespace na\n";
1583 std::string Expected = "namespace na {\n"
1584 "class C_A {};\n"
1585 "namespace nc {\n"
1586 "class C_C {};"
1587 "} // namespace nc\n"
1588 "\n"
1589 "} // namespace na\n"
1590 "class C_X {\n"
1591 "public:\n"
1592 " na::C_A a;\n"
1593 " na::nc::C_C c;\n"
1594 "};\n"
1595 "class C_Y {\n"
1596 " C_X x;\n"
1597 "};\n";
1598 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1599}
1600
1601TEST_F(ChangeNamespaceTest, KeepGlobalSpecifier) {
1602 std::string Code = "class Glob {};\n"
1603 "namespace na {\n"
1604 "class C_A {};\n"
1605 "namespace nc {\n"
1606 "class C_C {};"
1607 "} // namespace nc\n"
1608 "namespace nb {\n"
1609 "class C_X {\n"
1610 "public:\n"
1611 " ::Glob glob_1;\n"
1612 " Glob glob_2;\n"
1613 " C_A a_1;\n"
1614 " ::na::C_A a_2;\n"
1615 " nc::C_C c;\n"
1616 "};\n"
1617 "} // namespace nb\n"
1618 "} // namespace na\n";
1619 std::string Expected = "class Glob {};\n"
1620 "namespace na {\n"
1621 "class C_A {};\n"
1622 "namespace nc {\n"
1623 "class C_C {};"
1624 "} // namespace nc\n"
1625 "\n"
1626 "} // namespace na\n"
1627 "namespace x {\n"
1628 "namespace y {\n"
1629 "class C_X {\n"
1630 "public:\n"
1631 " ::Glob glob_1;\n"
1632 " Glob glob_2;\n"
1633 " na::C_A a_1;\n"
1634 " ::na::C_A a_2;\n"
1635 " na::nc::C_C c;\n"
1636 "};\n"
1637 "} // namespace y\n"
1638 "} // namespace x\n";
1639 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1640}
1641
1642TEST_F(ChangeNamespaceTest, UsingAliasInTemplate) {
1643 NewNamespace = "na::nb::nc";
1644 std::string Code = "namespace some_ns {\n"
1645 "template <typename T, typename S>\n"
1646 "class G {};\n"
1647 "} // namespace some_ns\n"
1648 "namespace na {\n"
1649 "template<typename P>\n"
1650 "using GG = some_ns::G<int, P>;\n"
1651 "} // namespace na\n"
1652 "namespace na {\n"
1653 "namespace nb {\n"
1654 "void f() {\n"
1655 " GG<float> g;\n"
1656 "}\n"
1657 "} // namespace nb\n"
1658 "} // namespace na\n";
1659 std::string Expected = "namespace some_ns {\n"
1660 "template <typename T, typename S>\n"
1661 "class G {};\n"
1662 "} // namespace some_ns\n"
1663 "namespace na {\n"
1664 "template<typename P>\n"
1665 "using GG = some_ns::G<int, P>;\n"
1666 "} // namespace na\n"
1667 "namespace na {\n"
1668 "namespace nb {\n"
1669 "namespace nc {\n"
1670 "void f() {\n"
1671 " GG<float> g;\n"
1672 "}\n"
1673 "} // namespace nc\n"
1674 "} // namespace nb\n"
1675 "} // namespace na\n";
1676 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1677}
1678
1679TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
1680 NewNamespace = "na::nb::nc";
1681 std::string Code = "namespace some_ns {\n"
1682 "template <typename T, typename S>\n"
1683 "class G {};\n"
1684 "} // namespace some_ns\n"
1685 "namespace na {\n"
1686 "class Base {\n"
1687 "public:\n"
1688 " template<typename P>\n"
1689 " using GG = some_ns::G<int, P>;\n"
1690 "\n"
1691 " struct Nested {};\n"
1692 "};\n"
1693 "class Derived : public Base {};\n"
1694 "} // namespace na\n"
1695 "namespace na {\n"
1696 "namespace nb {\n"
1697 "void f() {\n"
1698 " Derived::GG<float> g;\n"
1699 " const Derived::GG<int> gg;\n"
1700 " const Derived::GG<int>* gg_ptr;\n"
1701 " struct Derived::Nested nested;\n"
1702 " const struct Derived::Nested *nested_ptr;\n"
1703 "}\n"
1704 "} // namespace nb\n"
1705 "} // namespace na\n";
1706 std::string Expected = "namespace some_ns {\n"
1707 "template <typename T, typename S>\n"
1708 "class G {};\n"
1709 "} // namespace some_ns\n"
1710 "namespace na {\n"
1711 "class Base {\n"
1712 "public:\n"
1713 " template<typename P>\n"
1714 " using GG = some_ns::G<int, P>;\n"
1715 "\n"
1716 " struct Nested {};\n"
1717 "};\n"
1718 "class Derived : public Base {};\n"
1719 "} // namespace na\n"
1720 "namespace na {\n"
1721 "namespace nb {\n"
1722 "namespace nc {\n"
1723 "void f() {\n"
1724 " Derived::GG<float> g;\n"
1725 " const Derived::GG<int> gg;\n"
1726 " const Derived::GG<int>* gg_ptr;\n"
1727 " struct Derived::Nested nested;\n"
1728 " const struct Derived::Nested *nested_ptr;\n"
1729 "}\n"
1730 "} // namespace nc\n"
1731 "} // namespace nb\n"
1732 "} // namespace na\n";
1733 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1734}
1735
1736TEST_F(ChangeNamespaceTest, ExistingNamespaceConflictWithNewNamespace) {
1737 OldNamespace = "nx";
1738 NewNamespace = "ny::na::nc";
1739 std::string Code = "namespace na {\n"
1740 "class A {};\n"
1741 "} // namespace na\n"
1742 "namespace nb {\n"
1743 "class B {};\n"
1744 "} // namespace nb\n"
1745 "namespace nx {\n"
1746 "class X {\n"
1747 " na::A a; nb::B b;\n"
1748 "};\n"
1749 "} // namespace nx\n";
1750 std::string Expected = "namespace na {\n"
1751 "class A {};\n"
1752 "} // namespace na\n"
1753 "namespace nb {\n"
1754 "class B {};\n"
1755 "} // namespace nb\n"
1756 "\n"
1757 "namespace ny {\n"
1758 "namespace na {\n"
1759 "namespace nc {\n"
1760 "class X {\n"
1761 " ::na::A a; nb::B b;\n"
1762 "};\n"
1763 "} // namespace nc\n"
1764 "} // namespace na\n"
1765 "} // namespace ny\n";
1766 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1767}
1768
1769TEST_F(ChangeNamespaceTest, SymbolConflictWithNewNamespace) {
1770 OldNamespace = "nx";
1771 NewNamespace = "ny::na::nc";
1772 std::string Code = "namespace na {\n"
1773 "class A {};\n"
1774 "namespace nb {\n"
1775 "class B {};\n"
1776 "} // namespace nb\n"
1777 "} // namespace na\n"
1778 "namespace ny {\n"
1779 "class Y {};\n"
1780 "}\n"
1781 "namespace nx {\n"
1782 "class X {\n"
1783 " na::A a; na::nb::B b;\n"
1784 " ny::Y y;"
1785 "};\n"
1786 "} // namespace nx\n";
1787 std::string Expected = "namespace na {\n"
1788 "class A {};\n"
1789 "namespace nb {\n"
1790 "class B {};\n"
1791 "} // namespace nb\n"
1792 "} // namespace na\n"
1793 "namespace ny {\n"
1794 "class Y {};\n"
1795 "}\n"
1796 "\n"
1797 "namespace ny {\n"
1798 "namespace na {\n"
1799 "namespace nc {\n"
1800 "class X {\n"
1801 " ::na::A a; ::na::nb::B b;\n"
1802 " Y y;\n"
1803 "};\n"
1804 "} // namespace nc\n"
1805 "} // namespace na\n"
1806 "} // namespace ny\n";
1807 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1808}
1809
1810TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifier) {
1811 OldNamespace = "nx";
1812 NewNamespace = "ny::na";
1813 std::string Code = "class G {};\n"
1814 "namespace ny {\n"
1815 "class Y {};\n"
1816 "namespace na {\n"
1817 "class A {};\n"
1818 "namespace nc { class C {}; } // namespace nc\n"
1819 "}\n // namespace na\n"
1820 "}\n // namespace ny\n"
1821 "namespace nx {\n"
1822 "class X {\n"
1823 " G g; ny::Y y; ny::na::A a; ny::na::nc::C c;\n"
1824 "};\n"
1825 "} // namespace nx\n";
1826 std::string Expected = "class G {};\n"
1827 "namespace ny {\n"
1828 "class Y {};\n"
1829 "namespace na {\n"
1830 "class A {};\n"
1831 "namespace nc { class C {}; } // namespace nc\n"
1832 "}\n // namespace na\n"
1833 "}\n // namespace ny\n"
1834 "\n"
1835 "namespace ny {\n"
1836 "namespace na {\n"
1837 "class X {\n"
1838 " G g; Y y; A a; nc::C c;\n"
1839 "};\n"
1840 "} // namespace na\n"
1841 "} // namespace ny\n";
1842 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1843}
1844
1845TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifierInAnonymousNamespace) {
1846 OldNamespace = "nx";
1847 NewNamespace = "ny::na";
1848 std::string Code = "class G {};\n"
1849 "namespace ny {\n"
1850 "class Y {};\n"
1851 "namespace na {\n"
1852 "class A {};\n"
1853 "namespace nc { class C {}; } // namespace nc\n"
1854 "}\n // namespace na\n"
1855 "}\n // namespace ny\n"
1856 "namespace nx {\n"
1857 "namespace {\n"
1858 "class X {\n"
1859 " G g; ::ny::Y y; ::ny::na::A a; ::ny::na::nc::C c;\n"
1860 "};\n"
1861 "} // namespace\n"
1862 "} // namespace nx\n";
1863 std::string Expected = "class G {};\n"
1864 "namespace ny {\n"
1865 "class Y {};\n"
1866 "namespace na {\n"
1867 "class A {};\n"
1868 "namespace nc { class C {}; } // namespace nc\n"
1869 "}\n // namespace na\n"
1870 "}\n // namespace ny\n"
1871 "\n"
1872 "namespace ny {\n"
1873 "namespace na {\n"
1874 "namespace {\n"
1875 "class X {\n"
1876 " G g; Y y; A a; nc::C c;\n"
1877 "};\n"
1878 "} // namespace\n"
1879 "} // namespace na\n"
1880 "} // namespace ny\n";
1881 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1882}
1883
1884TEST_F(ChangeNamespaceTest, SimpleMoveEnum) {
1885 std::string Code = "namespace na {\n"
1886 "namespace nb {\n"
1887 "enum class X { X1, X2 };\n"
1888 "enum Y { Y1, Y2 };\n"
1889 "} // namespace nb\n"
1890 "} // namespace na\n";
1891 std::string Expected = "\n\nnamespace x {\n"
1892 "namespace y {\n"
1893 "enum class X { X1, X2 };\n"
1894 "enum Y { Y1, Y2 };\n"
1895 "} // namespace y\n"
1896 "} // namespace x\n";
1897
1898 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1899}
1900
1901TEST_F(ChangeNamespaceTest, ReferencesToEnums) {
1902 std::string Code = "enum Glob { G1, G2 };\n"
1903 "namespace na {\n"
1904 "enum class X { X1 };\n"
1905 "enum Y { Y1, Y2 };\n"
1906 "namespace nb {\n"
1907 "void f() {\n"
1908 " Glob g1 = Glob::G1;\n"
1909 " Glob g2 = G2;\n"
1910 " X x1 = X::X1;\n"
1911 " Y y1 = Y::Y1;\n"
1912 " Y y2 = Y2;\n"
1913 "}\n"
1914 "} // namespace nb\n"
1915 "} // namespace na\n";
1916 std::string Expected = "enum Glob { G1, G2 };\n"
1917 "namespace na {\n"
1918 "enum class X { X1 };\n"
1919 "enum Y { Y1, Y2 };\n"
1920 "\n"
1921 "} // namespace na\n"
1922 "namespace x {\n"
1923 "namespace y {\n"
1924 "void f() {\n"
1925 " Glob g1 = Glob::G1;\n"
1926 " Glob g2 = G2;\n"
1927 " na::X x1 = na::X::X1;\n"
1928 " na::Y y1 = na::Y::Y1;\n"
1929 " na::Y y2 = na::Y2;\n"
1930 "}\n"
1931 "} // namespace y\n"
1932 "} // namespace x\n";
1933
1934 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1935}
1936
1937TEST_F(ChangeNamespaceTest, NoRedundantEnumUpdate) {
1938 std::string Code = "namespace ns {\n"
1939 "enum class X { X1 };\n"
1940 "enum Y { Y1, Y2 };\n"
1941 "} // namespace ns\n"
1942 "namespace na {\n"
1943 "namespace nb {\n"
1944 "void f() {\n"
1945 " ns::X x1 = ns::X::X1;\n"
1946 " ns::Y y1 = ns::Y::Y1;\n"
1947 " ns::Y y2 = ns::Y2;\n"
1948 "}\n"
1949 "} // namespace nb\n"
1950 "} // namespace na\n";
1951 std::string Expected = "namespace ns {\n"
1952 "enum class X { X1 };\n"
1953 "enum Y { Y1, Y2 };\n"
1954 "} // namespace ns\n"
1955 "\n"
1956 "namespace x {\n"
1957 "namespace y {\n"
1958 "void f() {\n"
1959 " ns::X x1 = ns::X::X1;\n"
1960 " ns::Y y1 = ns::Y::Y1;\n"
1961 " ns::Y y2 = ns::Y2;\n"
1962 "}\n"
1963 "} // namespace y\n"
1964 "} // namespace x\n";
1965 ;
1966
1967 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
1968}
1969
1970TEST_F(ChangeNamespaceTest, EnumsAndUsingShadows) {
1971 std::string Code = "namespace ns {\n"
1972 "enum class X { X1 };\n"
1973 "enum Y { Y1, Y2, Y3 };\n"
1974 "} // namespace ns\n"
1975 "using ns::X;\n"
1976 "using ns::Y;\n"
1977 "using ns::Y::Y2;\n"
1978 "using ns::Y::Y3;\n"
1979 "namespace na {\n"
1980 "namespace nb {\n"
1981 "void f() {\n"
1982 " X x1 = X::X1;\n"
1983 " Y y1 = Y::Y1;\n"
1984 " Y y2 = Y2;\n"
1985 " Y y3 = Y3;\n"
1986 "}\n"
1987 "} // namespace nb\n"
1988 "} // namespace na\n";
1989 std::string Expected = "namespace ns {\n"
1990 "enum class X { X1 };\n"
1991 "enum Y { Y1, Y2, Y3 };\n"
1992 "} // namespace ns\n"
1993 "using ns::X;\n"
1994 "using ns::Y;\n"
1995 "using ns::Y::Y2;\n"
1996 "using ns::Y::Y3;\n"
1997 "\n"
1998 "namespace x {\n"
1999 "namespace y {\n"
2000 "void f() {\n"
2001 " X x1 = X::X1;\n"
2002 " Y y1 = Y::Y1;\n"
2003 " Y y2 = Y2;\n"
2004 " Y y3 = Y3;\n"
2005 "}\n"
2006 "} // namespace y\n"
2007 "} // namespace x\n";
2008
2009 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2010}
2011
2012TEST_F(ChangeNamespaceTest, EnumsAndAliases) {
2013 std::string Code = "namespace ns {\n"
2014 "enum class X { X1 };\n"
2015 "enum Y { Y1, Y2, Y3 };\n"
2016 "} // namespace ns\n"
2017 "typedef ns::X TX;\n"
2018 "typedef ns::Y TY;\n"
2019 "using UX = ns::X;\n"
2020 "using UY = ns::Y;\n"
2021 "namespace na {\n"
2022 "namespace nb {\n"
2023 "void f() {\n"
2024 " ns::X x1 = ns::X::X1;\n"
2025 " TX tx1 = TX::X1;\n"
2026 " UX ux1 = UX::X1;\n"
2027 " ns::Y y1 = ns::Y::Y1;\n"
2028 " TY ty1 = TY::Y1;\n"
2029 " UY uy1 = UY::Y1;\n"
2030 "}\n"
2031 "} // namespace nb\n"
2032 "} // namespace na\n";
2033 std::string Expected = "namespace ns {\n"
2034 "enum class X { X1 };\n"
2035 "enum Y { Y1, Y2, Y3 };\n"
2036 "} // namespace ns\n"
2037 "typedef ns::X TX;\n"
2038 "typedef ns::Y TY;\n"
2039 "using UX = ns::X;\n"
2040 "using UY = ns::Y;\n"
2041 "\n"
2042 "namespace x {\n"
2043 "namespace y {\n"
2044 "void f() {\n"
2045 " ns::X x1 = ns::X::X1;\n"
2046 " TX tx1 = TX::X1;\n"
2047 " UX ux1 = UX::X1;\n"
2048 " ns::Y y1 = ns::Y::Y1;\n"
2049 " TY ty1 = TY::Y1;\n"
2050 " UY uy1 = UY::Y1;\n"
2051 "}\n"
2052 "} // namespace y\n"
2053 "} // namespace x\n";
2054
2055 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2056}
2057
2058TEST_F(ChangeNamespaceTest, EnumInClass) {
2059 std::string Code = "namespace na {\n"
2060 "struct X { enum E { E1 }; };\n"
2061 "namespace nb {\n"
2062 "void f() {\n"
2063 " X::E e = X::E1;\n"
2064 " X::E ee = X::E::E1;\n"
2065 "}\n"
2066 "} // namespace nb\n"
2067 "} // namespace na\n";
2068 std::string Expected = "namespace na {\n"
2069 "struct X { enum E { E1 }; };\n"
2070 "\n"
2071 "} // namespace na\n"
2072 "namespace x {\n"
2073 "namespace y {\n"
2074 "void f() {\n"
2075 " na::X::E e = na::X::E1;\n"
2076 " na::X::E ee = na::X::E::E1;\n"
2077 "}\n"
2078 "} // namespace y\n"
2079 "} // namespace x\n";
2080
2081 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2082}
2083
2084TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) {
2085 std::string Code = "namespace na {\n"
2086 "struct X {};\n"
2087 "namespace nb {\n"
2088 "template <typename TT>\n"
2089 "void TempTemp(const TT& t) {\n"
2090 " TT tmp;\n"
2091 "}\n"
2092 "template <typename T>\n"
2093 "void Temp(const T& t) {\n"
2094 " T tmp = t;\n"
2095 " TempTemp(tmp);\n"
2096 " TempTemp(t);\n"
2097 "}\n"
2098 "void f() {\n"
2099 " X x;\n"
2100 " Temp(x);\n"
2101 "}\n"
2102 "} // namespace nb\n"
2103 "} // namespace na\n";
2104 std::string Expected = "namespace na {\n"
2105 "struct X {};\n"
2106 "\n"
2107 "} // namespace na\n"
2108 "namespace x {\n"
2109 "namespace y {\n"
2110 "template <typename TT>\n"
2111 "void TempTemp(const TT& t) {\n"
2112 " TT tmp;\n"
2113 "}\n"
2114 "template <typename T>\n"
2115 "void Temp(const T& t) {\n"
2116 " T tmp = t;\n"
2117 " TempTemp(tmp);\n"
2118 " TempTemp(t);\n"
2119 "}\n"
2120 "void f() {\n"
2121 " na::X x;\n"
2122 " Temp(x);\n"
2123 "}\n"
2124 "} // namespace y\n"
2125 "} // namespace x\n";
2126
2127 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2128}
2129
2130TEST_F(ChangeNamespaceTest, DefaultMoveConstructors) {
2131 std::string Code = "namespace na {\n"
2132 "class B {\n"
2133 " public:\n"
2134 " B() = default;\n"
2135 " // Allow move only.\n"
2136 " B(B&&) = default;\n"
2137 " B& operator=(B&&) = default;\n"
2138 " B(const B&) = delete;\n"
2139 " B& operator=(const B&) = delete;\n"
2140 " private:\n"
2141 " int ref_;\n"
2142 "};\n"
2143 "} // namespace na\n"
2144 "namespace na {\n"
2145 "namespace nb {\n"
2146 "class A {\n"
2147 "public:\n"
2148 " A() = default;\n"
2149 " A(A&&) = default;\n"
2150 " A& operator=(A&&) = default;\n"
2151 "private:\n"
2152 " B b;\n"
2153 " A(const A&) = delete;\n"
2154 " A& operator=(const A&) = delete;\n"
2155 "};\n"
2156 "void f() { A a; a = A(); A aa = A(); }\n"
2157 "} // namespace nb\n"
2158 "} // namespace na\n";
2159 std::string Expected = "namespace na {\n"
2160 "class B {\n"
2161 " public:\n"
2162 " B() = default;\n"
2163 " // Allow move only.\n"
2164 " B(B&&) = default;\n"
2165 " B& operator=(B&&) = default;\n"
2166 " B(const B&) = delete;\n"
2167 " B& operator=(const B&) = delete;\n"
2168 " private:\n"
2169 " int ref_;\n"
2170 "};\n"
2171 "} // namespace na\n"
2172 "\n"
2173 "namespace x {\n"
2174 "namespace y {\n"
2175 "class A {\n"
2176 "public:\n"
2177 " A() = default;\n"
2178 " A(A&&) = default;\n"
2179 " A& operator=(A&&) = default;\n"
2180 "private:\n"
2181 " na::B b;\n"
2182 " A(const A&) = delete;\n"
2183 " A& operator=(const A&) = delete;\n"
2184 "};\n"
2185 "void f() { A a; a = A(); A aa = A(); }\n"
2186 "} // namespace y\n"
2187 "} // namespace x\n";
2188 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2189}
2190
2191TEST_F(ChangeNamespaceTest, InjectedClassNameInFriendDecl) {
2192 OldNamespace = "d";
2193 NewNamespace = "e";
2194 std::string Code = "namespace a{\n"
2195 "template <typename T>\n"
2196 "class Base {\n"
2197 " public:\n"
2198 " void f() {\n"
2199 " T t;\n"
2200 " t.priv();\n"
2201 " }\n"
2202 "};\n"
2203 "} // namespace a\n"
2204 "namespace d {\n"
2205 "class D : public a::Base<D> {\n"
2206 " private:\n"
2207 " friend class Base<D>;\n"
2208 " void priv() {}\n"
2209 " Base b;\n"
2210 "};\n"
2211 "\n"
2212 "void f() {\n"
2213 " D d;\n"
2214 " a:: Base<D> b;\n"
2215 " b.f();\n"
2216 "}\n"
2217 "} // namespace d\n";
2218 std::string Expected = "namespace a{\n"
2219 "template <typename T>\n"
2220 "class Base {\n"
2221 " public:\n"
2222 " void f() {\n"
2223 " T t;\n"
2224 " t.priv();\n"
2225 " }\n"
2226 "};\n"
2227 "} // namespace a\n"
2228 "\n"
2229 "namespace e {\n"
2230 "class D : public a::Base<D> {\n"
2231 " private:\n"
2232 " friend class a::Base<D>;\n"
2233 " void priv() {}\n"
2234 " a::Base b;\n"
2235 "};\n"
2236 "\n"
2237 "void f() {\n"
2238 " D d;\n"
2239 " a::Base<D> b;\n"
2240 " b.f();\n"
2241 "}\n"
2242 "} // namespace e\n";
2243 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2244}
2245
2246TEST_F(ChangeNamespaceTest, FullyQualifyConflictNamespace) {
2247 std::string Code =
2248 "namespace x { namespace util { class Some {}; } }\n"
2249 "namespace x { namespace y {namespace base { class Base {}; } } }\n"
2250 "namespace util { class Status {}; }\n"
2251 "namespace base { class Base {}; }\n"
2252 "namespace na {\n"
2253 "namespace nb {\n"
2254 "void f() {\n"
2255 " util::Status s1; x::util::Some s2;\n"
2256 " base::Base b1; x::y::base::Base b2;\n"
2257 "}\n"
2258 "} // namespace nb\n"
2259 "} // namespace na\n";
2260
2261 std::string Expected =
2262 "namespace x { namespace util { class Some {}; } }\n"
2263 "namespace x { namespace y {namespace base { class Base {}; } } }\n"
2264 "namespace util { class Status {}; }\n"
2265 "namespace base { class Base {}; }\n"
2266 "\n"
2267 "namespace x {\n"
2268 "namespace y {\n"
2269 "void f() {\n"
2270 " ::util::Status s1; util::Some s2;\n"
2271 " ::base::Base b1; base::Base b2;\n"
2272 "}\n"
2273 "} // namespace y\n"
2274 "} // namespace x\n";
2275
2276 EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
2277}
2278
2279} // anonymous namespace
2280} // namespace change_namespace
2281} // namespace clang
2282

source code of clang-tools-extra/unittests/clang-change-namespace/ChangeNamespaceTests.cpp