blob: 3a15f05041ad76136ae6c9d8325fd686332ba3ad [file] [log] [blame]
//===-- 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<llvm::StringRef /*Input*/, llvm::StringRef /*Expected*/> 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