1 //===-- ClangMemberTests.cpp - unit tests for renaming class members ------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "ClangRenameTest.h"
12 namespace clang_rename
{
16 class RenameMemberTest
: public ClangRenameTest
{
24 static void SNotFoo();
31 static void SNotFoo();
39 template <typename T> struct TA {
45 template <typename T> struct TB : public TA<T> {};
47 template <typename T> struct TA {
54 template <typename T> struct TB : public TA<T> {};
59 static void SNotFoo();
61 struct B : public A {};
64 void SFoo(const T& t) {}
72 INSTANTIATE_TEST_SUITE_P(
73 DISABLED_RenameTemplatedClassStaticVariableTest
, RenameMemberTest
,
74 testing::ValuesIn(std::vector
<Case
>({
75 // FIXME: support renaming static variables for template classes.
76 {"void f() { ns::TA<int>::SMoo; }",
77 "void f() { ns::TA<int>::SMeh; }", "ns::TA::SMoo", "ns::TA::SMeh"},
80 INSTANTIATE_TEST_SUITE_P(
81 RenameMemberTest
, RenameMemberTest
,
82 testing::ValuesIn(std::vector
<Case
>({
83 // Normal methods and fields.
84 {"void f() { A a; a.Foo(); }", "void f() { A a; a.Bar(); }", "A::Foo",
86 {"void f() { ns::A a; a.Foo(); }", "void f() { ns::A a; a.Bar(); }",
87 "ns::A::Foo", "ns::A::Bar"},
88 {"void f() { A a; int x = a.Moo; }", "void f() { A a; int x = a.Meh; }",
90 {"void f() { B b; b.Foo(); }", "void f() { B b; b.Bar(); }", "B::Foo",
92 {"void f() { ns::B b; b.Foo(); }", "void f() { ns::B b; b.Bar(); }",
93 "ns::A::Foo", "ns::A::Bar"},
94 {"void f() { B b; int x = b.Moo; }", "void f() { B b; int x = b.Meh; }",
98 {"void f() { A::SFoo(); }", "void f() { A::SBar(); }", "A::SFoo",
100 {"void f() { ns::A::SFoo(); }", "void f() { ns::A::SBar(); }",
101 "ns::A::SFoo", "ns::A::SBar"},
102 {"void f() { TA<int>::SFoo(); }", "void f() { TA<int>::SBar(); }",
103 "TA::SFoo", "TA::SBar"},
104 {"void f() { ns::TA<int>::SFoo(); }",
105 "void f() { ns::TA<int>::SBar(); }", "ns::TA::SFoo", "ns::TA::SBar"},
108 {"void f() { A::SMoo; }",
109 "void f() { A::SMeh; }", "A::SMoo", "A::SMeh"},
111 // Templated methods.
112 {"void f() { TA<int> a; a.Foo(); }", "void f() { TA<int> a; a.Bar(); }",
113 "TA::Foo", "TA::Bar"},
114 {"void f() { ns::TA<int> a; a.Foo(); }",
115 "void f() { ns::TA<int> a; a.Bar(); }", "ns::TA::Foo", "ns::TA::Bar"},
116 {"void f() { TB<int> b; b.Foo(); }", "void f() { TB<int> b; b.Bar(); }",
117 "TA::Foo", "TA::Bar"},
118 {"void f() { ns::TB<int> b; b.Foo(); }",
119 "void f() { ns::TB<int> b; b.Bar(); }", "ns::TA::Foo", "ns::TA::Bar"},
120 {"void f() { ns::C c; int x; c.SFoo(x); }",
121 "void f() { ns::C c; int x; c.SBar(x); }", "ns::C::SFoo",
123 {"void f() { ns::C c; c.Foo<int>(); }",
124 "void f() { ns::C c; c.Bar<int>(); }", "ns::C::Foo", "ns::C::Bar"},
126 // Pointers to methods.
127 {"void f() { auto p = &A::Foo; }", "void f() { auto p = &A::Bar; }",
129 {"void f() { auto p = &A::SFoo; }", "void f() { auto p = &A::SBar; }",
130 "A::SFoo", "A::SBar"},
131 {"void f() { auto p = &B::Foo; }", "void f() { auto p = &B::Bar; }",
133 {"void f() { auto p = &ns::A::Foo; }",
134 "void f() { auto p = &ns::A::Bar; }", "ns::A::Foo", "ns::A::Bar"},
135 {"void f() { auto p = &ns::A::SFoo; }",
136 "void f() { auto p = &ns::A::SBar; }", "ns::A::SFoo", "ns::A::SBar"},
137 {"void f() { auto p = &ns::C::SFoo<int>; }",
138 "void f() { auto p = &ns::C::SBar<int>; }", "ns::C::SFoo",
141 // These methods are not declared or overridden in the subclass B, we
142 // have to use the qualified name with parent class A to identify them.
143 {"void f() { auto p = &ns::B::Foo; }",
144 "void f() { auto p = &ns::B::Bar; }", "ns::A::Foo", "ns::B::Bar"},
145 {"void f() { B::SFoo(); }", "void f() { B::SBar(); }", "A::SFoo",
147 {"void f() { ns::B::SFoo(); }", "void f() { ns::B::SBar(); }",
148 "ns::A::SFoo", "ns::B::SBar"},
149 {"void f() { auto p = &B::SFoo; }", "void f() { auto p = &B::SBar; }",
150 "A::SFoo", "B::SBar"},
151 {"void f() { auto p = &ns::B::SFoo; }",
152 "void f() { auto p = &ns::B::SBar; }", "ns::A::SFoo", "ns::B::SBar"},
153 {"void f() { TB<int>::SFoo(); }", "void f() { TB<int>::SBar(); }",
154 "TA::SFoo", "TB::SBar"},
155 {"void f() { ns::TB<int>::SFoo(); }",
156 "void f() { ns::TB<int>::SBar(); }", "ns::TA::SFoo", "ns::TB::SBar"},
159 TEST_P(RenameMemberTest
, RenameMembers
) {
160 auto Param
= GetParam();
161 assert(!Param
.OldName
.empty());
162 assert(!Param
.NewName
.empty());
164 runClangRenameOnCode(Param
.Before
, Param
.OldName
, Param
.NewName
);
165 CompareSnippets(Param
.After
, Actual
);
168 TEST_F(RenameMemberTest
, RenameMemberInsideClassMethods
) {
169 std::string Before
= R
"(
172 void Baz() { Moo = 1; }
174 std::string Expected
= R
"(
177 void Baz() { Meh = 1; }
179 std::string After
= runClangRenameOnCode(Before
, "X::Moo", "Y::Meh");
180 CompareSnippets(Expected
, After
);
183 TEST_F(RenameMemberTest
, RenameMethodInsideClassMethods
) {
184 std::string Before
= R
"(
187 void Baz() { Foo(); }
189 std::string Expected
= R
"(
192 void Baz() { Bar(); }
194 std::string After
= runClangRenameOnCode(Before
, "X::Foo", "X::Bar");
195 CompareSnippets(Expected
, After
);
198 TEST_F(RenameMemberTest
, RenameCtorInitializer
) {
199 std::string Before
= R
"(
210 std::string Expected
= R
"(
221 std::string After
= runClangRenameOnCode(Before
, "X::a", "X::bar");
222 CompareSnippets(Expected
, After
);
225 } // anonymous namespace
227 } // namespace clang_rename
228 } // namesdpace clang