Clang Project

clang_source_code/unittests/Rename/RenameEnumTest.cpp
1#include "ClangRenameTest.h"
2
3namespace clang {
4namespace clang_rename {
5namespace test {
6namespace {
7
8class RenameEnumTest : public ClangRenameTest {
9public:
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
29INSTANTIATE_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
147TEST_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
156TEST_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(ExpectedAfter);
169}
170
171TEST_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(ExpectedAfter);
184}
185
186// anonymous namespace
187// namespace test
188// namespace clang_rename
189// namesdpace clang
190