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