286 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TweakTesting.h"10#include "gmock/gmock-matchers.h"11#include "gmock/gmock.h"12#include "gtest/gtest.h"13 14namespace clang {15namespace clangd {16namespace {17 18TWEAK_TEST(RemoveUsingNamespace);19 20TEST_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 y50 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 y59 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, numeric197 };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, numeric208 };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 context231 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 {// Does not qualify user-defined literals254 R"cpp(255 namespace ns {256 long double operator "" _w(long double);257 }258 using namespace n^s;259 int main() { 1.5_w; }260 )cpp",261 R"cpp(262 namespace ns {263 long double operator "" _w(long double);264 }265 266 int main() { 1.5_w; }267 )cpp"},268 {269 R"cpp(270 namespace a { inline namespace b { void foobar(); } }271 using namespace a::[[b]];272 int main() { foobar(); }273 )cpp",274 R"cpp(275 namespace a { inline namespace b { void foobar(); } }276 277 int main() { a::b::foobar(); }278 )cpp"}};279 for (auto C : Cases)280 EXPECT_EQ(C.second, apply(C.first)) << C.first;281}282 283} // namespace284} // namespace clangd285} // namespace clang286