1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "ClangRenameTest.h" |
10 | |
11 | namespace clang { |
12 | namespace clang_rename { |
13 | namespace test { |
14 | namespace { |
15 | |
16 | class RenameAliasTest : public ClangRenameTest { |
17 | public: |
18 | RenameAliasTest() { |
19 | AppendToHeader(R"( |
20 | #define MACRO(x) x |
21 | namespace some_ns { |
22 | class A { |
23 | public: |
24 | void foo() {} |
25 | struct Nested { |
26 | enum NestedEnum { |
27 | E1, E2, |
28 | }; |
29 | }; |
30 | }; |
31 | } // namespace some_ns |
32 | namespace a { |
33 | typedef some_ns::A TA; |
34 | using UA = some_ns::A; |
35 | } // namespace a |
36 | namespace b { |
37 | typedef some_ns::A TA; |
38 | using UA = some_ns::A; |
39 | } |
40 | template <typename T> class ptr {}; |
41 | template <typename T> |
42 | |
43 | using TPtr = ptr<int>; |
44 | )"); |
45 | } |
46 | }; |
47 | |
48 | INSTANTIATE_TEST_CASE_P( |
49 | RenameAliasTests, RenameAliasTest, |
50 | testing::ValuesIn(std::vector<Case>({ |
51 | |
52 | {"void f(a::TA a1) {}", "void f(b::TB a1) {}", "a::TA", "b::TB"}, |
53 | {"void f(a::UA a1) {}", "void f(b::UB a1) {}", "a::UA", "b::UB"}, |
54 | {"void f(a::TA* a1) {}", "void f(b::TB* a1) {}", "a::TA", "b::TB"}, |
55 | {"void f(a::TA** a1) {}", "void f(b::TB** a1) {}", "a::TA", "b::TB"}, |
56 | {"a::TA f() { return a::TA(); }", "b::TB f() { return b::TB(); }", |
57 | "a::TA", "b::TB"}, |
58 | {"a::TA f() { return a::UA(); }", "b::TB f() { return a::UA(); }", |
59 | "a::TA", "b::TB"}, |
60 | {"a::TA f() { return a::UA(); }", "a::TA f() { return b::UB(); }", |
61 | "a::UA", "b::UB"}, |
62 | {"void f() { a::TA a; }", "void f() { b::TB a; }", "a::TA", "b::TB"}, |
63 | {"void f(const a::TA& a1) {}", "void f(const b::TB& a1) {}", "a::TA", |
64 | "b::TB"}, |
65 | {"void f(const a::UA& a1) {}", "void f(const b::UB& a1) {}", "a::UA", |
66 | "b::UB"}, |
67 | {"void f(const a::TA* a1) {}", "void f(const b::TB* a1) {}", "a::TA", |
68 | "b::TB"}, |
69 | {"namespace a { void f(TA a1) {} }", |
70 | "namespace a { void f(b::TB a1) {} }", "a::TA", "b::TB"}, |
71 | {"void f(MACRO(a::TA) a1) {}", "void f(MACRO(b::TB) a1) {}", "a::TA", |
72 | "b::TB"}, |
73 | {"void f(MACRO(a::TA a1)) {}", "void f(MACRO(b::TB a1)) {}", "a::TA", |
74 | "b::TB"}, |
75 | |
76 | |
77 | {"namespace b { void f(a::UA a1) {} }", |
78 | "namespace b {void f(UB a1) {} }", "a::UA", "b::UB"}, |
79 | {"namespace a { void f(UA a1) {} }", |
80 | "namespace a {void f(b::UB a1) {} }", "a::UA", "b::UB"}, |
81 | |
82 | |
83 | {"struct S { using T = a::TA; T a_; };", |
84 | "struct S { using T = b::TB; T a_; };", "a::TA", "b::TB"}, |
85 | {"using T = a::TA; T gA;", "using T = b::TB; T gA;", "a::TA", "b::TB"}, |
86 | {"using T = a::UA; T gA;", "using T = b::UB; T gA;", "a::UA", "b::UB"}, |
87 | {"typedef a::TA T; T gA;", "typedef b::TB T; T gA;", "a::TA", "b::TB"}, |
88 | {"typedef a::UA T; T gA;", "typedef b::UB T; T gA;", "a::UA", "b::UB"}, |
89 | {"typedef MACRO(a::TA) T; T gA;", "typedef MACRO(b::TB) T; T gA;", |
90 | "a::TA", "b::TB"}, |
91 | |
92 | |
93 | {"using a::TA; TA gA;", "using b::TB; b::TB gA;", "a::TA", "b::TB"}, |
94 | {"using a::UA; UA gA;", "using b::UB; b::UB gA;", "a::UA", "b::UB"}, |
95 | |
96 | |
97 | {"struct S : public a::TA {};", "struct S : public b::TB {};", "a::TA", |
98 | "b::TB"}, |
99 | {"struct S : public a::UA {};", "struct S : public b::UB {};", "a::UA", |
100 | "b::UB"}, |
101 | {"struct F { void f(a::TA a1) {} };", |
102 | "struct F { void f(b::TB a1) {} };", "a::TA", "b::TB"}, |
103 | {"struct F { a::TA a_; };", "struct F { b::TB a_; };", "a::TA", |
104 | "b::TB"}, |
105 | {"struct F { ptr<a::TA> a_; };", "struct F { ptr<b::TB> a_; };", |
106 | "a::TA", "b::TB"}, |
107 | {"struct F { ptr<a::UA> a_; };", "struct F { ptr<b::UB> a_; };", |
108 | "a::UA", "b::UB"}, |
109 | |
110 | |
111 | {"void f() { a::TA::Nested ne; }", "void f() { b::TB::Nested ne; }", |
112 | "a::TA", "b::TB"}, |
113 | {"void f() { a::UA::Nested ne; }", "void f() { b::UB::Nested ne; }", |
114 | "a::UA", "b::UB"}, |
115 | {"void f() { a::TA::Nested::NestedEnum e; }", |
116 | "void f() { b::TB::Nested::NestedEnum e; }", "a::TA", "b::TB"}, |
117 | {"void f() { auto e = a::TA::Nested::NestedEnum::E1; }", |
118 | "void f() { auto e = b::TB::Nested::NestedEnum::E1; }", "a::TA", |
119 | "b::TB"}, |
120 | {"void f() { auto e = a::TA::Nested::E1; }", |
121 | "void f() { auto e = b::TB::Nested::E1; }", "a::TA", "b::TB"}, |
122 | |
123 | |
124 | {"template <typename T> struct Foo { T t; }; void f() { Foo<a::TA> " |
125 | "foo; }", |
126 | "template <typename T> struct Foo { T t; }; void f() { Foo<b::TB> " |
127 | "foo; }", |
128 | "a::TA", "b::TB"}, |
129 | {"template <typename T> struct Foo { a::TA a; };", |
130 | "template <typename T> struct Foo { b::TB a; };", "a::TA", "b::TB"}, |
131 | {"template <typename T> void f(T t) {} void g() { f<a::TA>(a::TA()); }", |
132 | "template <typename T> void f(T t) {} void g() { f<b::TB>(b::TB()); }", |
133 | "a::TA", "b::TB"}, |
134 | {"template <typename T> void f(T t) {} void g() { f<a::UA>(a::UA()); }", |
135 | "template <typename T> void f(T t) {} void g() { f<b::UB>(b::UB()); }", |
136 | "a::UA", "b::UB"}, |
137 | {"template <typename T> int f() { return 1; } template <> int " |
138 | "f<a::TA>() { return 2; } int g() { return f<a::TA>(); }", |
139 | "template <typename T> int f() { return 1; } template <> int " |
140 | "f<b::TB>() { return 2; } int g() { return f<b::TB>(); }", |
141 | "a::TA", "b::TB"}, |
142 | {"struct Foo { template <typename T> T foo(); }; void g() { Foo f; " |
143 | "auto a = f.template foo<a::TA>(); }", |
144 | "struct Foo { template <typename T> T foo(); }; void g() { Foo f; " |
145 | "auto a = f.template foo<b::TB>(); }", |
146 | "a::TA", "b::TB"}, |
147 | {"struct Foo { template <typename T> T foo(); }; void g() { Foo f; " |
148 | "auto a = f.template foo<a::UA>(); }", |
149 | "struct Foo { template <typename T> T foo(); }; void g() { Foo f; " |
150 | "auto a = f.template foo<b::UB>(); }", |
151 | "a::UA", "b::UB"}, |
152 | |
153 | |
154 | |
155 | {"template <typename T> struct outer { typedef T type; type Baz(); }; " |
156 | "outer<a::TA> g_A;", |
157 | "template <typename T> struct outer { typedef T type; type Baz(); }; " |
158 | "outer<b::TB> g_A;", |
159 | "a::TA", "b::TB"}, |
160 | {"template <typename T> struct nested { typedef T type; }; template " |
161 | "<typename T> struct outer { typename nested<T>::type Foo(); }; " |
162 | "outer<a::TA> g_A;", |
163 | "template <typename T> struct nested { typedef T type; }; template " |
164 | "<typename T> struct outer { typename nested<T>::type Foo(); }; " |
165 | "outer<b::TB> g_A;", |
166 | "a::TA", "b::TB"}, |
167 | |
168 | |
169 | {"#define FOO(T, t) T t\nvoid f() { FOO(a::TA, a1); FOO(a::TA, a2); }", |
170 | "#define FOO(T, t) T t\nvoid f() { FOO(b::TB, a1); FOO(b::TB, a2); }", |
171 | "a::TA", "b::TB"}, |
172 | {"#define FOO(n) a::TA n\nvoid f() { FOO(a1); FOO(a2); }", |
173 | "#define FOO(n) b::TB n\nvoid f() { FOO(a1); FOO(a2); }", "a::TA", |
174 | "b::TB"}, |
175 | {"#define FOO(n) a::UA n\nvoid f() { FOO(a1); FOO(a2); }", |
176 | "#define FOO(n) b::UB n\nvoid f() { FOO(a1); FOO(a2); }", "a::UA", |
177 | "b::UB"}, |
178 | |
179 | |
180 | {"auto gA = &a::TA::foo;", "auto gA = &b::TB::foo;", "a::TA", "b::TB"}, |
181 | {"using a::TA; auto gA = &TA::foo;", |
182 | "using b::TB; auto gA = &b::TB::foo;", "a::TA", "b::TB"}, |
183 | {"typedef a::TA T; auto gA = &T::foo;", |
184 | "typedef b::TB T; auto gA = &T::foo;", "a::TA", "b::TB"}, |
185 | {"auto gA = &MACRO(a::TA)::foo;", "auto gA = &MACRO(b::TB)::foo;", |
186 | "a::TA", "b::TB"}, |
187 | |
188 | |
189 | {"void f(TPtr<int> p) {}", "void f(NewTPtr<int> p) {}", "TPtr", |
190 | "NewTPtr"}, |
191 | {"void f(::TPtr<int> p) {}", "void f(::NewTPtr<int> p) {}", "TPtr", |
192 | "NewTPtr"}, |
193 | })), ); |
194 | |
195 | TEST_P(RenameAliasTest, RenameAlias) { |
196 | auto Param = GetParam(); |
197 | assert(!Param.OldName.empty()); |
198 | assert(!Param.NewName.empty()); |
199 | std::string Actual = |
200 | runClangRenameOnCode(Param.Before, Param.OldName, Param.NewName); |
201 | CompareSnippets(Param.After, Actual); |
202 | } |
203 | |
204 | TEST_F(RenameAliasTest, RenameTypedefDefinitions) { |
205 | std::string Before = R"( |
206 | class X {}; |
207 | typedef X TOld; |
208 | )"; |
209 | std::string Expected = R"( |
210 | class X {}; |
211 | typedef X TNew; |
212 | )"; |
213 | std::string After = runClangRenameOnCode(Before, "TOld", "TNew"); |
214 | CompareSnippets(Expected, After); |
215 | } |
216 | |
217 | TEST_F(RenameAliasTest, RenameUsingAliasDefinitions) { |
218 | std::string Before = R"( |
219 | class X {}; |
220 | using UOld = X; |
221 | )"; |
222 | std::string Expected = R"( |
223 | class X {}; |
224 | using UNew = X; |
225 | )"; |
226 | std::string After = runClangRenameOnCode(Before, "UOld", "UNew"); |
227 | CompareSnippets(Expected, After); |
228 | } |
229 | |
230 | TEST_F(RenameAliasTest, RenameTemplatedAliasDefinitions) { |
231 | std::string Before = R"( |
232 | template <typename T> |
233 | class X { T t; }; |
234 | |
235 | template <typename T> |
236 | using Old = X<T>; |
237 | )"; |
238 | std::string Expected = R"( |
239 | template <typename T> |
240 | class X { T t; }; |
241 | |
242 | template <typename T> |
243 | using New = X<T>; |
244 | )"; |
245 | std::string After = runClangRenameOnCode(Before, "Old", "New"); |
246 | CompareSnippets(Expected, After); |
247 | } |
248 | |
249 | TEST_F(RenameAliasTest, RenameAliasesInNamespaces) { |
250 | std::string Before = R"( |
251 | namespace x { class X {}; } |
252 | namespace ns { |
253 | using UOld = x::X; |
254 | } |
255 | )"; |
256 | std::string Expected = R"( |
257 | namespace x { class X {}; } |
258 | namespace ns { |
259 | using UNew = x::X; |
260 | } |
261 | )"; |
262 | std::string After = runClangRenameOnCode(Before, "ns::UOld", "ns::UNew"); |
263 | CompareSnippets(Expected, After); |
264 | } |
265 | |
266 | TEST_F(RenameAliasTest, AliasesInMacros) { |
267 | std::string Before = R"( |
268 | namespace x { class Old {}; } |
269 | namespace ns { |
270 | #define REF(alias) alias alias_var; |
271 | |
272 | #define ALIAS(old) \ |
273 | using old##Alias = x::old; \ |
274 | REF(old##Alias); |
275 | |
276 | ALIAS(Old); |
277 | |
278 | OldAlias old_alias; |
279 | } |
280 | )"; |
281 | std::string Expected = R"( |
282 | namespace x { class Old {}; } |
283 | namespace ns { |
284 | #define REF(alias) alias alias_var; |
285 | |
286 | #define ALIAS(old) \ |
287 | using old##Alias = x::old; \ |
288 | REF(old##Alias); |
289 | |
290 | ALIAS(Old); |
291 | |
292 | NewAlias old_alias; |
293 | } |
294 | )"; |
295 | std::string After = |
296 | runClangRenameOnCode(Before, "ns::OldAlias", "ns::NewAlias"); |
297 | CompareSnippets(Expected, After); |
298 | } |
299 | |
300 | } |
301 | } |
302 | } |
303 | } |
304 | |