1 //===-- RemoveUsingNamespaceTest.cpp ----------------------------*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "TweakTesting.h" 10 #include "gmock/gmock-matchers.h" 11 #include "gmock/gmock.h" 12 #include "gtest/gtest.h" 13 14 namespace clang { 15 namespace clangd { 16 namespace { 17 18 TWEAK_TEST(RemoveUsingNamespace); 19 20 TEST_F(RemoveUsingNamespaceTest, All) { 21 std::pair<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> Cases[] = { 22 {// Remove all occurrences of ns. Qualify only unqualified. 23 R"cpp( 24 namespace ns1 { struct vector {}; } 25 namespace ns2 { struct map {}; } 26 using namespace n^s1; 27 using namespace ns2; 28 using namespace ns1; 29 int main() { 30 ns1::vector v1; 31 vector v2; 32 map m1; 33 } 34 )cpp", 35 R"cpp( 36 namespace ns1 { struct vector {}; } 37 namespace ns2 { struct map {}; } 38 39 using namespace ns2; 40 41 int main() { 42 ns1::vector v1; 43 ns1::vector v2; 44 map m1; 45 } 46 )cpp"}, 47 {// Ident to be qualified is a macro arg. 48 R"cpp( 49 #define DECLARE(x, y) x y 50 namespace ns { struct vector {}; } 51 using namespace n^s; 52 int main() { 53 DECLARE(ns::vector, v1); 54 DECLARE(vector, v2); 55 } 56 )cpp", 57 R"cpp( 58 #define DECLARE(x, y) x y 59 namespace ns { struct vector {}; } 60 61 int main() { 62 DECLARE(ns::vector, v1); 63 DECLARE(ns::vector, v2); 64 } 65 )cpp"}, 66 {// Nested namespace: Fully qualify ident from inner ns. 67 R"cpp( 68 namespace aa { namespace bb { struct map {}; }} 69 using namespace aa::b^b; 70 int main() { 71 map m; 72 } 73 )cpp", 74 R"cpp( 75 namespace aa { namespace bb { struct map {}; }} 76 77 int main() { 78 aa::bb::map m; 79 } 80 )cpp"}, 81 {// Nested namespace: Fully qualify ident from inner ns. 82 R"cpp( 83 namespace aa { namespace bb { struct map {}; }} 84 using namespace a^a; 85 int main() { 86 bb::map m; 87 } 88 )cpp", 89 R"cpp( 90 namespace aa { namespace bb { struct map {}; }} 91 92 int main() { 93 aa::bb::map m; 94 } 95 )cpp"}, 96 {// Typedef. 97 R"cpp( 98 namespace aa { namespace bb { struct map {}; }} 99 using namespace a^a; 100 typedef bb::map map; 101 int main() { map M; } 102 )cpp", 103 R"cpp( 104 namespace aa { namespace bb { struct map {}; }} 105 106 typedef aa::bb::map map; 107 int main() { map M; } 108 )cpp"}, 109 {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns. 110 R"cpp( 111 namespace aa { namespace bb { struct map {}; }} 112 using name[[space aa::b]]b; 113 using namespace aa; 114 int main() { 115 map m; 116 } 117 )cpp", 118 R"cpp( 119 namespace aa { namespace bb { struct map {}; }} 120 121 using namespace aa; 122 int main() { 123 aa::bb::map m; 124 } 125 )cpp"}, 126 {// Does not qualify ident from inner namespace. 127 R"cpp( 128 namespace aa { namespace bb { struct map {}; }} 129 using namespace aa::bb; 130 using namespace a^a; 131 int main() { 132 map m; 133 } 134 )cpp", 135 R"cpp( 136 namespace aa { namespace bb { struct map {}; }} 137 using namespace aa::bb; 138 139 int main() { 140 map m; 141 } 142 )cpp"}, 143 {// Available only for top level namespace decl. 144 R"cpp( 145 namespace aa { 146 namespace bb { struct map {}; } 147 using namespace b^b; 148 } 149 int main() { aa::map m; } 150 )cpp", 151 "unavailable"}, 152 {// FIXME: Unavailable for namespaces containing using-namespace decl. 153 R"cpp( 154 namespace aa { 155 namespace bb { struct map {}; } 156 using namespace bb; 157 } 158 using namespace a^a; 159 int main() { 160 map m; 161 } 162 )cpp", 163 "unavailable"}, 164 {R"cpp( 165 namespace a::b { struct Foo {}; } 166 using namespace a; 167 using namespace a::[[b]]; 168 using namespace b; 169 int main() { Foo F;} 170 )cpp", 171 R"cpp( 172 namespace a::b { struct Foo {}; } 173 using namespace a; 174 175 176 int main() { a::b::Foo F;} 177 )cpp"}, 178 {R"cpp( 179 namespace a::b { struct Foo {}; } 180 using namespace a; 181 using namespace a::b; 182 using namespace [[b]]; 183 int main() { Foo F;} 184 )cpp", 185 R"cpp( 186 namespace a::b { struct Foo {}; } 187 using namespace a; 188 189 190 int main() { b::Foo F;} 191 )cpp"}, 192 {// Enumerators. 193 R"cpp( 194 namespace tokens { 195 enum Token { 196 comma, identifier, numeric 197 }; 198 } 199 using namespace tok^ens; 200 int main() { 201 auto x = comma; 202 } 203 )cpp", 204 R"cpp( 205 namespace tokens { 206 enum Token { 207 comma, identifier, numeric 208 }; 209 } 210 211 int main() { 212 auto x = tokens::comma; 213 } 214 )cpp"}, 215 {// inline namespaces. 216 R"cpp( 217 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} 218 using namespace st^d; 219 int main() { 220 vector V; 221 } 222 )cpp", 223 R"cpp( 224 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} 225 226 int main() { 227 std::vector V; 228 } 229 )cpp"}, 230 {// Does not qualify operators declared in a non-class context 231 R"cpp( 232 namespace ns { 233 struct Foo {}; 234 void operator+(const Foo &, int) {} 235 } 236 using namespace n^s; 237 int main() { 238 Foo foo; 239 foo + 10; 240 } 241 )cpp", 242 R"cpp( 243 namespace ns { 244 struct Foo {}; 245 void operator+(const Foo &, int) {} 246 } 247 248 int main() { 249 ns::Foo foo; 250 foo + 10; 251 } 252 )cpp"}}; 253 for (auto C : Cases) 254 EXPECT_EQ(C.second, apply(C.first)) << C.first; 255 } 256 257 } // namespace 258 } // namespace clangd 259 } // namespace clang 260