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