1 //===---- NamespaceAliaserTest.cpp - clang-tidy
2 //----------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #include "../clang-tidy/utils/NamespaceAliaser.h"
12 #include "ClangTidyTest.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "clang/ASTMatchers/ASTMatchers.h"
15 #include "gtest/gtest.h"
20 // This checker is for testing only. It can only run on one test case
21 // (e.g. with one SourceManager).
22 class InsertAliasCheck
: public ClangTidyCheck
{
24 InsertAliasCheck(StringRef Name
, ClangTidyContext
*Context
)
25 :ClangTidyCheck(Name
, Context
) {}
26 void registerMatchers(ast_matchers::MatchFinder
*Finder
) override
{
27 Finder
->addMatcher(ast_matchers::callExpr().bind("foo"), this);
29 void check(const ast_matchers::MatchFinder::MatchResult
&Result
) override
{
31 Aliaser
.reset(new NamespaceAliaser(*Result
.SourceManager
));
33 const auto *Call
= Result
.Nodes
.getNodeAs
<CallExpr
>("foo");
34 assert(Call
!= nullptr && "Did not find node \"foo\"");
35 auto Hint
= Aliaser
->createAlias(*Result
.Context
, *Call
, "::foo::bar",
38 diag(Call
->getBeginLoc(), "Fix for testing") << *Hint
;
40 diag(Call
->getBeginLoc(), "insert call") << FixItHint::CreateInsertion(
42 Aliaser
->getNamespaceName(*Result
.Context
, *Call
, "::foo::bar") + "::");
46 std::unique_ptr
<NamespaceAliaser
> Aliaser
;
49 template <typename Check
>
50 std::string
runChecker(StringRef Code
, unsigned ExpectedWarningCount
) {
51 std::map
<StringRef
, StringRef
> AdditionalFileContents
= {{"foo.h",
57 std::vector
<ClangTidyError
> errors
;
60 test::runCheckOnCode
<Check
>(Code
, &errors
, "foo.cc", std::nullopt
,
61 ClangTidyOptions(), AdditionalFileContents
);
63 EXPECT_EQ(ExpectedWarningCount
, errors
.size());
67 TEST(NamespaceAliaserTest
, AddNewAlias
) {
68 EXPECT_EQ("#include \"foo.h\"\n"
70 "namespace b = ::foo::bar;"
72 runChecker
<InsertAliasCheck
>("#include \"foo.h\"\n"
77 TEST(NamespaceAliaserTest
, ReuseAlias
) {
79 "#include \"foo.h\"\n"
80 "void f() { namespace x = foo::bar; x::f(); }",
81 runChecker
<InsertAliasCheck
>("#include \"foo.h\"\n"
82 "void f() { namespace x = foo::bar; f(); }",
86 TEST(NamespaceAliaserTest
, AddsOnlyOneAlias
) {
87 EXPECT_EQ("#include \"foo.h\"\n"
89 "namespace b = ::foo::bar;"
91 runChecker
<InsertAliasCheck
>("#include \"foo.h\"\n"
92 "void f() { f(); f(); }",
96 TEST(NamespaceAliaserTest
, LocalConflict
) {
97 EXPECT_EQ("#include \"foo.h\"\n"
99 "namespace some_alias = ::foo::bar;"
100 " namespace b = foo; some_alias::f(); }",
101 runChecker
<InsertAliasCheck
>("#include \"foo.h\"\n"
102 "void f() { namespace b = foo; f(); }",
106 TEST(NamespaceAliaserTest
, GlobalConflict
) {
107 EXPECT_EQ("#include \"foo.h\"\n"
108 "namespace b = foo;\n"
110 "namespace some_alias = ::foo::bar;"
111 " some_alias::f(); }",
112 runChecker
<InsertAliasCheck
>("#include \"foo.h\"\n"
113 "namespace b = foo;\n"