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: |
10 | RenameEnumTest() { |
11 | AppendToHeader(Code: 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_SUITE_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 | |
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(Code: Param.Before, OldName: Param.OldName, NewName: Param.NewName); |
153 | CompareSnippets(Expected: Param.After, Actual); |
154 | } |
155 | |
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(Code: Before, OldName: "ns::Old1" , NewName: "ns::New1" ); |
168 | CompareSnippets(Expected, Actual: After); |
169 | } |
170 | |
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(Code: Before, OldName: "ns::Old1" , NewName: "ns::New1" ); |
183 | CompareSnippets(Expected, Actual: After); |
184 | } |
185 | |
186 | } // anonymous namespace |
187 | } // namespace test |
188 | } // namespace clang_rename |
189 | } // namesdpace clang |
190 | |