//===-- RemoveUsingNamespaceTest.cpp ----------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "TestTU.h" #include "TweakTesting.h" #include "gmock/gmock-matchers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace clang { namespace clangd { namespace { TWEAK_TEST(RemoveUsingNamespace); TEST_F(RemoveUsingNamespaceTest, All) { std::pair Cases[] = { {// Remove all occurrences of ns. Qualify only unqualified. R"cpp( namespace ns1 { struct vector {}; } namespace ns2 { struct map {}; } using namespace n^s1; using namespace ns2; using namespace ns1; int main() { ns1::vector v1; vector v2; map m1; } )cpp", R"cpp( namespace ns1 { struct vector {}; } namespace ns2 { struct map {}; } using namespace ns2; int main() { ns1::vector v1; ns1::vector v2; map m1; } )cpp"}, {// Ident to be qualified is a macro arg. R"cpp( #define DECLARE(x, y) x y namespace ns { struct vector {}; } using namespace n^s; int main() { DECLARE(ns::vector, v1); DECLARE(vector, v2); } )cpp", R"cpp( #define DECLARE(x, y) x y namespace ns { struct vector {}; } int main() { DECLARE(ns::vector, v1); DECLARE(ns::vector, v2); } )cpp"}, {// Nested namespace: Fully qualify ident from inner ns. R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace aa::b^b; int main() { map m; } )cpp", R"cpp( namespace aa { namespace bb { struct map {}; }} int main() { aa::bb::map m; } )cpp"}, {// Nested namespace: Fully qualify ident from inner ns. R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace a^a; int main() { bb::map m; } )cpp", R"cpp( namespace aa { namespace bb { struct map {}; }} int main() { aa::bb::map m; } )cpp"}, {// Typedef. R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace a^a; typedef bb::map map; int main() { map M; } )cpp", R"cpp( namespace aa { namespace bb { struct map {}; }} typedef aa::bb::map map; int main() { map M; } )cpp"}, {// FIXME: Nested namespaces: Not aware of using ns decl of outer ns. R"cpp( namespace aa { namespace bb { struct map {}; }} using name[[space aa::b]]b; using namespace aa; int main() { map m; } )cpp", R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace aa; int main() { aa::bb::map m; } )cpp"}, {// Does not qualify ident from inner namespace. R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace aa::bb; using namespace a^a; int main() { map m; } )cpp", R"cpp( namespace aa { namespace bb { struct map {}; }} using namespace aa::bb; int main() { map m; } )cpp"}, {// Available only for top level namespace decl. R"cpp( namespace aa { namespace bb { struct map {}; } using namespace b^b; } int main() { aa::map m; } )cpp", "unavailable"}, {// FIXME: Unavailable for namespaces containing using-namespace decl. R"cpp( namespace aa { namespace bb { struct map {}; } using namespace bb; } using namespace a^a; int main() { map m; } )cpp", "unavailable"}, {R"cpp( namespace a::b { struct Foo {}; } using namespace a; using namespace a::[[b]]; using namespace b; int main() { Foo F;} )cpp", R"cpp( namespace a::b { struct Foo {}; } using namespace a; int main() { a::b::Foo F;} )cpp"}, {R"cpp( namespace a::b { struct Foo {}; } using namespace a; using namespace a::b; using namespace [[b]]; int main() { Foo F;} )cpp", R"cpp( namespace a::b { struct Foo {}; } using namespace a; int main() { b::Foo F;} )cpp"}, {// Enumerators. R"cpp( namespace tokens { enum Token { comma, identifier, numeric }; } using namespace tok^ens; int main() { auto x = comma; } )cpp", R"cpp( namespace tokens { enum Token { comma, identifier, numeric }; } int main() { auto x = tokens::comma; } )cpp"}, {// inline namespaces. R"cpp( namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} using namespace st^d; int main() { vector V; } )cpp", R"cpp( namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} int main() { std::vector V; } )cpp"}}; for (auto C : Cases) EXPECT_EQ(C.second, apply(C.first)) << C.first; } } // namespace } // namespace clangd } // namespace clang