brintos

brintos / llvm-project-archived public Read only

0
0
Text · 85.3 KiB · 4a6352c Raw
2282 lines · cpp
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-exception6//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(FileName, 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);44    std::unique_ptr<tooling::FrontendActionFactory> Factory =45        tooling::newFrontendActionFactory(&Finder);46    if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, {"-std=c++11"},47                                        FileName))48      return "";49    formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite);50    return format(Context.getRewrittenText(ID));51  }52 53  std::string format(llvm::StringRef Code) {54    tooling::Replacements Replaces = format::reformat(55        format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())});56    auto ChangedCode = tooling::applyAllReplacements(Code, Replaces);57    EXPECT_TRUE(static_cast<bool>(ChangedCode));58    if (!ChangedCode) {59      llvm::errs() << llvm::toString(ChangedCode.takeError());60      return "";61    }62    return *ChangedCode;63  }64 65protected:66  std::string FileName = "input.cc";67  std::string OldNamespace = "na::nb";68  std::string NewNamespace = "x::y";69  std::string FilePattern = "input.cc";70};71 72TEST_F(ChangeNamespaceTest, NoMatchingNamespace) {73  std::string Code = "namespace na {\n"74                     "namespace nx {\n"75                     "class A {};\n"76                     "} // namespace nx\n"77                     "} // namespace na\n";78  std::string Expected = "namespace na {\n"79                         "namespace nx {\n"80                         "class A {};\n"81                         "} // namespace nx\n"82                         "} // namespace na\n";83  EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));84}85 86TEST_F(ChangeNamespaceTest, SimpleMoveWithoutTypeRefs) {87  std::string Code = "namespace na {\n"88                     "namespace nb {\n"89                     "class A {};\n"90                     "} // namespace nb\n"91                     "} // namespace na\n";92  std::string Expected = "\n\n"93                         "namespace x {\n"94                         "namespace y {\n"95                         "class A {};\n"96                         "} // namespace y\n"97                         "} // namespace x\n";98  EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));99}100 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 if680      // 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 namespace2280} // namespace change_namespace2281} // namespace clang2282