1 //===---- UsingInserterTest.cpp - clang-tidy ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "../clang-tidy/utils/UsingInserter.h"
11 #include "ClangTidyTest.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/ASTMatchers/ASTMatchers.h"
14 #include "gtest/gtest.h"
20 // Replace all function calls with calls to foo::func. Inserts using
21 // declarations as necessary. This checker is for testing only. It
22 // can only run on one test case (e.g. wih one SourceManager).
23 class InsertUsingCheck
: public clang::tidy::ClangTidyCheck
{
25 InsertUsingCheck(StringRef Name
, ClangTidyContext
*Context
)
26 :ClangTidyCheck(Name
, Context
) {}
27 void registerMatchers(clang::ast_matchers::MatchFinder
*Finder
) override
{
28 Finder
->addMatcher(clang::ast_matchers::callExpr().bind("foo"), this);
31 check(const clang::ast_matchers::MatchFinder::MatchResult
&Result
) override
{
33 Inserter
.reset(new UsingInserter(*Result
.SourceManager
));
35 const auto *Call
= Result
.Nodes
.getNodeAs
<clang::CallExpr
>("foo");
36 assert(Call
!= nullptr && "Did not find node \"foo\"");
38 Inserter
->createUsingDeclaration(*Result
.Context
, *Call
, "::foo::func");
41 diag(Call
->getBeginLoc(), "Fix for testing") << *Hint
;
43 diag(Call
->getBeginLoc(), "insert call")
44 << clang::FixItHint::CreateReplacement(
45 Call
->getCallee()->getSourceRange(),
46 Inserter
->getShortName(*Result
.Context
, *Call
, "::foo::func"));
50 std::unique_ptr
<UsingInserter
> Inserter
;
53 template <typename Check
>
54 std::string
runChecker(StringRef Code
, unsigned ExpectedWarningCount
) {
55 std::map
<StringRef
, StringRef
> AdditionalFileContents
= {{"foo.h",
61 std::vector
<ClangTidyError
> errors
;
64 test::runCheckOnCode
<Check
>(Code
, &errors
, "foo.cc", std::nullopt
,
65 ClangTidyOptions(), AdditionalFileContents
);
67 EXPECT_EQ(ExpectedWarningCount
, errors
.size());
71 TEST(UsingInserterTest
, ReusesExisting
) {
72 EXPECT_EQ("#include \"foo.h\"\n"
74 "using ::foo::func;\n"
75 "void f() { func(); }"
77 runChecker
<InsertUsingCheck
>("#include \"foo.h\"\n"
79 "using ::foo::func;\n"
85 TEST(UsingInserterTest
, ReusesExistingGlobal
) {
86 EXPECT_EQ("#include \"foo.h\"\n"
87 "using ::foo::func;\n"
89 "void f() { func(); }"
91 runChecker
<InsertUsingCheck
>("#include \"foo.h\"\n"
92 "using ::foo::func;\n"
99 TEST(UsingInserterTest
, AvoidsConflict
) {
100 EXPECT_EQ("#include \"foo.h\"\n"
102 "void f() { int func; ::foo::func(); }"
104 runChecker
<InsertUsingCheck
>("#include \"foo.h\"\n"
106 "void f() { int func; f(); }"