1 #include "ClangRenameTest.h"
2 
3 namespace clang {
4 namespace clang_rename {
5 namespace test {
6 namespace {
7 
8 class RenameEnumTest : public ClangRenameTest {
9 public:
RenameEnumTest()10   RenameEnumTest() {
11     AppendToHeader(R"(
12         #define MACRO(x) x
13         namespace a {
14         enum A1 { Red };
15         enum class A2 { Blue };
16         struct C {
17          enum NestedEnum { White };
18          enum class NestedScopedEnum { Black };
19         };
20         namespace d {
21         enum A3 { Orange };
22         } // namespace d
23         enum A4 { Pink };
24         } // namespace a
25         enum A5 { Green };)");
26   }
27 };
28 
29 INSTANTIATE_TEST_CASE_P(
30     RenameEnumTests, RenameEnumTest,
31     testing::ValuesIn(std::vector<Case>({
32         {"void f(a::A2 arg) { a::A2 t = a::A2::Blue; }",
33          "void f(b::B2 arg) { b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
34         {"void f() { a::A1* t1; }", "void f() { b::B1* t1; }", "a::A1",
35          "b::B1"},
36         {"void f() { a::A2* t1; }", "void f() { b::B2* t1; }", "a::A2",
37          "b::B2"},
38         {"void f() { enum a::A2 t = a::A2::Blue; }",
39          "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
40         {"void f() { enum a::A2 t = a::A2::Blue; }",
41          "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
42 
43         {"void f() { a::A1 t = a::Red; }", "void f() { b::B1 t = b::B1::Red; }",
44          "a::A1", "b::B1"},
45         {"void f() { a::A1 t = a::A1::Red; }",
46          "void f() { b::B1 t = b::B1::Red; }", "a::A1", "b::B1"},
47         {"void f() { auto t = a::Red; }", "void f() { auto t = b::B1::Red; }",
48          "a::A1", "b::B1"},
49         {"namespace b { void f() { a::A1 t = a::Red; } }",
50          "namespace b { void f() { B1 t = B1::Red; } }", "a::A1", "b::B1"},
51         {"void f() { a::d::A3 t = a::d::Orange; }",
52          "void f() { a::b::B3 t = a::b::B3::Orange; }", "a::d::A3", "a::b::B3"},
53         {"namespace a { void f() { a::d::A3 t = a::d::Orange; } }",
54          "namespace a { void f() { b::B3 t = b::B3::Orange; } }", "a::d::A3",
55          "a::b::B3"},
56         {"void f() { A5 t = Green; }", "void f() { B5 t = Green; }", "A5",
57          "B5"},
58         // FIXME: the new namespace qualifier should be added to the unscoped
59         // enum constant.
60         {"namespace a { void f() { auto t = Green; } }",
61          "namespace a { void f() { auto t = Green; } }", "a::A1", "b::B1"},
62 
63         // namespace qualifiers
64         {"namespace a { void f(A1 a1) {} }",
65          "namespace a { void f(b::B1 a1) {} }", "a::A1", "b::B1"},
66         {"namespace a { void f(A2 a2) {} }",
67          "namespace a { void f(b::B2 a2) {} }", "a::A2", "b::B2"},
68         {"namespace b { void f(a::A1 a1) {} }",
69          "namespace b { void f(B1 a1) {} }", "a::A1", "b::B1"},
70         {"namespace b { void f(a::A2 a2) {} }",
71          "namespace b { void f(B2 a2) {} }", "a::A2", "b::B2"},
72 
73         // nested enums
74         {"void f() { a::C::NestedEnum t = a::C::White; }",
75          "void f() { a::C::NewNestedEnum t = a::C::NewNestedEnum::White; }",
76          "a::C::NestedEnum", "a::C::NewNestedEnum"},
77         {"void f() { a::C::NestedScopedEnum t = a::C::NestedScopedEnum::Black; "
78          "}",
79          "void f() { a::C::NewNestedScopedEnum t = "
80          "a::C::NewNestedScopedEnum::Black; }",
81          "a::C::NestedScopedEnum", "a::C::NewNestedScopedEnum"},
82 
83         // macros
84         {"void f(MACRO(a::A1) a1) {}", "void f(MACRO(b::B1) a1) {}", "a::A1",
85          "b::B1"},
86         {"void f(MACRO(a::A2) a2) {}", "void f(MACRO(b::B2) a2) {}", "a::A2",
87          "b::B2"},
88         {"#define FOO(T, t) T t\nvoid f() { FOO(a::A1, a1); }",
89          "#define FOO(T, t) T t\nvoid f() { FOO(b::B1, a1); }", "a::A1",
90          "b::B1"},
91         {"#define FOO(T, t) T t\nvoid f() { FOO(a::A2, a2); }",
92          "#define FOO(T, t) T t\nvoid f() { FOO(b::B2, a2); }", "a::A2",
93          "b::B2"},
94         {"#define FOO(n) a::A1 n\nvoid f() { FOO(a1); FOO(a2); }",
95          "#define FOO(n) b::B1 n\nvoid f() { FOO(a1); FOO(a2); }", "a::A1",
96          "b::B1"},
97 
98         // using and type alias
99         {"using a::A1; A1 gA;", "using b::B1; b::B1 gA;", "a::A1", "b::B1"},
100         {"using a::A2; A2 gA;", "using b::B2; b::B2 gA;", "a::A2", "b::B2"},
101         {"struct S { using T = a::A1; T a_; };",
102          "struct S { using T = b::B1; T a_; };", "a::A1", "b::B1"},
103         {"using T = a::A1; T gA;", "using T = b::B1; T gA;", "a::A1", "b::B1"},
104         {"using T = a::A2; T gA;", "using T = b::B2; T gA;", "a::A2", "b::B2"},
105         {"typedef a::A1 T; T gA;", "typedef b::B1 T; T gA;", "a::A1", "b::B1"},
106         {"typedef a::A2 T; T gA;", "typedef b::B2 T; T gA;", "a::A2", "b::B2"},
107         {"typedef MACRO(a::A1) T; T gA;", "typedef MACRO(b::B1) T; T gA;",
108          "a::A1", "b::B1"},
109 
110         // templates
111         {"template<typename T> struct Foo { T t; }; void f() { Foo<a::A1> "
112          "foo1; }",
113          "template<typename T> struct Foo { T t; }; void f() { Foo<b::B1> "
114          "foo1; }",
115          "a::A1", "b::B1"},
116         {"template<typename T> struct Foo { T t; }; void f() { Foo<a::A2> "
117          "foo2; }",
118          "template<typename T> struct Foo { T t; }; void f() { Foo<b::B2> "
119          "foo2; }",
120          "a::A2", "b::B2"},
121         {"template<typename T> struct Foo { a::A1 a1; };",
122          "template<typename T> struct Foo { b::B1 a1; };", "a::A1", "b::B1"},
123         {"template<typename T> struct Foo { a::A2 a2; };",
124          "template<typename T> struct Foo { b::B2 a2; };", "a::A2", "b::B2"},
125         {"template<typename T> int f() { return 1; } template<> int f<a::A1>() "
126          "{ return 2; } int g() { return f<a::A1>(); }",
127          "template<typename T> int f() { return 1; } template<> int f<b::B1>() "
128          "{ return 2; } int g() { return f<b::B1>(); }",
129          "a::A1", "b::B1"},
130         {"template<typename T> int f() { return 1; } template<> int f<a::A2>() "
131          "{ return 2; } int g() { return f<a::A2>(); }",
132          "template<typename T> int f() { return 1; } template<> int f<b::B2>() "
133          "{ return 2; } int g() { return f<b::B2>(); }",
134          "a::A2", "b::B2"},
135         {"struct Foo { template <typename T> T foo(); }; void g() { Foo f;  "
136          "f.foo<a::A1>(); }",
137          "struct Foo { template <typename T> T foo(); }; void g() { Foo f;  "
138          "f.foo<b::B1>(); }",
139          "a::A1", "b::B1"},
140         {"struct Foo { template <typename T> T foo(); }; void g() { Foo f;  "
141          "f.foo<a::A2>(); }",
142          "struct Foo { template <typename T> T foo(); }; void g() { Foo f;  "
143          "f.foo<b::B2>(); }",
144          "a::A2", "b::B2"},
145     })), );
146 
TEST_P(RenameEnumTest,RenameEnums)147 TEST_P(RenameEnumTest, RenameEnums) {
148   auto Param = GetParam();
149   assert(!Param.OldName.empty());
150   assert(!Param.NewName.empty());
151   std::string Actual =
152       runClangRenameOnCode(Param.Before, Param.OldName, Param.NewName);
153   CompareSnippets(Param.After, Actual);
154 }
155 
TEST_F(RenameEnumTest,RenameEnumDecl)156 TEST_F(RenameEnumTest, RenameEnumDecl) {
157   std::string Before = R"(
158       namespace ns {
159       enum Old1 { Blue };
160       }
161   )";
162   std::string Expected = R"(
163       namespace ns {
164       enum New1 { Blue };
165       }
166   )";
167   std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1");
168   CompareSnippets(Expected, After);
169 }
170 
TEST_F(RenameEnumTest,RenameScopedEnumDecl)171 TEST_F(RenameEnumTest, RenameScopedEnumDecl) {
172   std::string Before = R"(
173       namespace ns {
174       enum class Old1 { Blue };
175       }
176   )";
177   std::string Expected = R"(
178       namespace ns {
179       enum class New1 { Blue };
180       }
181   )";
182   std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1");
183   CompareSnippets(Expected, After);
184 }
185 
186 } // anonymous namespace
187 } // namespace test
188 } // namespace clang_rename
189 } // namesdpace clang
190