Index: change-namespace/ChangeNamespace.h =================================================================== --- change-namespace/ChangeNamespace.h +++ change-namespace/ChangeNamespace.h @@ -142,6 +142,9 @@ // Records all using declarations, which can be used to shorten namespace // specifiers. llvm::SmallPtrSet UsingDecls; + // Records all type alias declarations, which can be used to shorten namespace + // specifiers. + llvm::SmallPtrSet TypeAliasDecls; // Records all using namespace declarations, which can be used to shorten // namespace specifiers. llvm::SmallPtrSet UsingNamespaceDecls; Index: change-namespace/ChangeNamespace.cpp =================================================================== --- change-namespace/ChangeNamespace.cpp +++ change-namespace/ChangeNamespace.cpp @@ -287,6 +287,11 @@ usingDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs) .bind("using"), this); + // Match using declarations. + Finder->addMatcher( + typeAliasDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs) + .bind("type_alias"), + this); // Match using namespace declarations. Finder->addMatcher(usingDirectiveDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs) @@ -374,6 +379,9 @@ const ast_matchers::MatchFinder::MatchResult &Result) { if (const auto *Using = Result.Nodes.getNodeAs("using")) { UsingDecls.insert(Using); + } else if (const auto *AliasDecl = + Result.Nodes.getNodeAs("type_alias")) { + TypeAliasDecls.insert(AliasDecl); } else if (const auto *UsingNamespace = Result.Nodes.getNodeAs( "using_namespace")) { Index: unittests/change-namespace/ChangeNamespaceTests.cpp =================================================================== --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ unittests/change-namespace/ChangeNamespaceTests.cpp @@ -822,22 +822,22 @@ } TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) { - std::string Code = "namespace na { class C_A {};\n }\n" + std::string Code = "namespace na { class C_A {}; }\n" "namespace na {\n" "namespace nb {\n" "void f() {\n" - " using na::CA;\n" - " CA ca;\n" + " using ::na::C_A;\n" + " C_A ca;\n" "}\n" "} // namespace nb\n" "} // namespace na\n"; - std::string Expected = "namespace na { class C_A {};\n }\n" + std::string Expected = "namespace na { class C_A {}; }\n" "\n" "namespace x {\n" "namespace y {\n" "void f() {\n" - " using na::CA;\n" - " CA ca;\n" + " using ::na::C_A;\n" + " C_A ca;\n" "}\n" "} // namespace y\n" "} // namespace x\n"; @@ -941,6 +941,149 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, UsingAliasDecl) { + std::string Code = + "namespace nx { namespace ny { class X {}; } }\n" + "namespace na {\n" + "namespace nb {\n" + "using Y = nx::ny::X;\n" + "void f() { Y y; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "using Y = nx::ny::X;\n" + "void f() { Y y; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +/* +TEST_F(ChangeNamespaceTest, ClassWithConstructors) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A {" + "public:\n" + " A() {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A {" + "public:\n" + " A() {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) { + std::string Code = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "namespace na {\n" + "namespace nb {\n" + "class A : public nx::ny::X {" + "public:\n" + " A() : nx::ny::X::X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : nx::ny::X::X(i) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A : public nx::ny::X {" + "public:\n" + " A() : nx::ny::X::X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : nx::ny::X::X(i) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndUsingDecl) { + std::string Code = + "namespace nx { class XYZ { public: XYZ(int i) {} }; }\n" + "namespace na {\n" + "namespace nb {\n" + "using nx::XYZ;\n" + "class A : public XYZ {" + "public:\n" + " A() : XYZ::XYZ(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : XYZ::XYZ(i) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { class XYZ { public: XYZ(int i) {} }; }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "using ::nx::XYZ;\n" + "class A : public XYZ {" + "public:\n" + " A() : XYZ::XYZ(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : XYZ::XYZ(i) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, ConstructorsAndUsingDeclInAnonymous) { + std::string Code = + "namespace nx { class XYZ { public: XYZ(int i) {} }; }\n" + "namespace na {\n" + "namespace nb {\n" + "using nx::XYZ;\n" + "namespace {\n" + "class A : public XYZ {" + "public:\n" + " A() : XYZ::XYZ(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : XYZ::XYZ(i) {}\n" + "} // namespace\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { class XYZ { public: XYZ(int i) {} }; }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "using ::nx::XYZ;\n" + "namespace {\n" + "class A : public XYZ {" + "public:\n" + " A() : XYZ::XYZ(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : XYZ::XYZ(i) {}\n" + "} // namespace\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} +*/ + } // anonymous namespace } // namespace change_namespace } // namespace clang