#include "ClangRenameTest.h" namespace clang { namespace clang_rename { namespace test { namespace { class RenameEnumTest : public ClangRenameTest { public: RenameEnumTest() { AppendToHeader(R"( #define MACRO(x) x namespace a { enum A1 { Red }; enum class A2 { Blue }; struct C { enum NestedEnum { White }; enum class NestedScopedEnum { Black }; }; namespace d { enum A3 { Orange }; } // namespace d enum A4 { Pink }; } // namespace a enum A5 { Green };)"); } }; INSTANTIATE_TEST_CASE_P( RenameEnumTests, RenameEnumTest, testing::ValuesIn(std::vector({ {"void f(a::A2 arg) { a::A2 t = a::A2::Blue; }", "void f(b::B2 arg) { b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"}, {"void f() { a::A1* t1; }", "void f() { b::B1* t1; }", "a::A1", "b::B1"}, {"void f() { a::A2* t1; }", "void f() { b::B2* t1; }", "a::A2", "b::B2"}, {"void f() { enum a::A2 t = a::A2::Blue; }", "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"}, {"void f() { enum a::A2 t = a::A2::Blue; }", "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"}, {"void f() { a::A1 t = a::Red; }", "void f() { b::B1 t = b::B1::Red; }", "a::A1", "b::B1"}, {"void f() { a::A1 t = a::A1::Red; }", "void f() { b::B1 t = b::B1::Red; }", "a::A1", "b::B1"}, {"void f() { auto t = a::Red; }", "void f() { auto t = b::B1::Red; }", "a::A1", "b::B1"}, {"namespace b { void f() { a::A1 t = a::Red; } }", "namespace b { void f() { B1 t = B1::Red; } }", "a::A1", "b::B1"}, {"void f() { a::d::A3 t = a::d::Orange; }", "void f() { a::b::B3 t = a::b::B3::Orange; }", "a::d::A3", "a::b::B3"}, {"namespace a { void f() { a::d::A3 t = a::d::Orange; } }", "namespace a { void f() { b::B3 t = b::B3::Orange; } }", "a::d::A3", "a::b::B3"}, {"void f() { A5 t = Green; }", "void f() { B5 t = Green; }", "A5", "B5"}, // FIXME: the new namespace qualifier should be added to the unscoped // enum constant. {"namespace a { void f() { auto t = Green; } }", "namespace a { void f() { auto t = Green; } }", "a::A1", "b::B1"}, // namespace qualifiers {"namespace a { void f(A1 a1) {} }", "namespace a { void f(b::B1 a1) {} }", "a::A1", "b::B1"}, {"namespace a { void f(A2 a2) {} }", "namespace a { void f(b::B2 a2) {} }", "a::A2", "b::B2"}, {"namespace b { void f(a::A1 a1) {} }", "namespace b { void f(B1 a1) {} }", "a::A1", "b::B1"}, {"namespace b { void f(a::A2 a2) {} }", "namespace b { void f(B2 a2) {} }", "a::A2", "b::B2"}, // nested enums {"void f() { a::C::NestedEnum t = a::C::White; }", "void f() { a::C::NewNestedEnum t = a::C::NewNestedEnum::White; }", "a::C::NestedEnum", "a::C::NewNestedEnum"}, {"void f() { a::C::NestedScopedEnum t = a::C::NestedScopedEnum::Black; " "}", "void f() { a::C::NewNestedScopedEnum t = " "a::C::NewNestedScopedEnum::Black; }", "a::C::NestedScopedEnum", "a::C::NewNestedScopedEnum"}, // macros {"void f(MACRO(a::A1) a1) {}", "void f(MACRO(b::B1) a1) {}", "a::A1", "b::B1"}, {"void f(MACRO(a::A2) a2) {}", "void f(MACRO(b::B2) a2) {}", "a::A2", "b::B2"}, {"#define FOO(T, t) T t\nvoid f() { FOO(a::A1, a1); }", "#define FOO(T, t) T t\nvoid f() { FOO(b::B1, a1); }", "a::A1", "b::B1"}, {"#define FOO(T, t) T t\nvoid f() { FOO(a::A2, a2); }", "#define FOO(T, t) T t\nvoid f() { FOO(b::B2, a2); }", "a::A2", "b::B2"}, {"#define FOO(n) a::A1 n\nvoid f() { FOO(a1); FOO(a2); }", "#define FOO(n) b::B1 n\nvoid f() { FOO(a1); FOO(a2); }", "a::A1", "b::B1"}, // using and type alias {"using a::A1; A1 gA;", "using b::B1; b::B1 gA;", "a::A1", "b::B1"}, {"using a::A2; A2 gA;", "using b::B2; b::B2 gA;", "a::A2", "b::B2"}, {"struct S { using T = a::A1; T a_; };", "struct S { using T = b::B1; T a_; };", "a::A1", "b::B1"}, {"using T = a::A1; T gA;", "using T = b::B1; T gA;", "a::A1", "b::B1"}, {"using T = a::A2; T gA;", "using T = b::B2; T gA;", "a::A2", "b::B2"}, {"typedef a::A1 T; T gA;", "typedef b::B1 T; T gA;", "a::A1", "b::B1"}, {"typedef a::A2 T; T gA;", "typedef b::B2 T; T gA;", "a::A2", "b::B2"}, {"typedef MACRO(a::A1) T; T gA;", "typedef MACRO(b::B1) T; T gA;", "a::A1", "b::B1"}, // templates {"template struct Foo { T t; }; void f() { Foo " "foo1; }", "template struct Foo { T t; }; void f() { Foo " "foo1; }", "a::A1", "b::B1"}, {"template struct Foo { T t; }; void f() { Foo " "foo2; }", "template struct Foo { T t; }; void f() { Foo " "foo2; }", "a::A2", "b::B2"}, {"template struct Foo { a::A1 a1; };", "template struct Foo { b::B1 a1; };", "a::A1", "b::B1"}, {"template struct Foo { a::A2 a2; };", "template struct Foo { b::B2 a2; };", "a::A2", "b::B2"}, {"template int f() { return 1; } template<> int f() " "{ return 2; } int g() { return f(); }", "template int f() { return 1; } template<> int f() " "{ return 2; } int g() { return f(); }", "a::A1", "b::B1"}, {"template int f() { return 1; } template<> int f() " "{ return 2; } int g() { return f(); }", "template int f() { return 1; } template<> int f() " "{ return 2; } int g() { return f(); }", "a::A2", "b::B2"}, {"struct Foo { template T foo(); }; void g() { Foo f; " "f.foo(); }", "struct Foo { template T foo(); }; void g() { Foo f; " "f.foo(); }", "a::A1", "b::B1"}, {"struct Foo { template T foo(); }; void g() { Foo f; " "f.foo(); }", "struct Foo { template T foo(); }; void g() { Foo f; " "f.foo(); }", "a::A2", "b::B2"}, })), ); TEST_P(RenameEnumTest, RenameEnums) { auto Param = GetParam(); assert(!Param.OldName.empty()); assert(!Param.NewName.empty()); std::string Actual = runClangRenameOnCode(Param.Before, Param.OldName, Param.NewName); CompareSnippets(Param.After, Actual); } TEST_F(RenameEnumTest, RenameEnumDecl) { std::string Before = R"( namespace ns { enum Old1 { Blue }; } )"; std::string Expected = R"( namespace ns { enum New1 { Blue }; } )"; std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1"); CompareSnippets(Expected, After); } TEST_F(RenameEnumTest, RenameScopedEnumDecl) { std::string Before = R"( namespace ns { enum class Old1 { Blue }; } )"; std::string Expected = R"( namespace ns { enum class New1 { Blue }; } )"; std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1"); CompareSnippets(Expected, After); } } // anonymous namespace } // namespace test } // namespace clang_rename } // namesdpace clang