[clang-tidy] Fix LLVM include order check policy
Clang-format LLVM style has a custom include category for gtest/ and gmock/ headers between regular includes and angled includes. Do the same here. Fixes https://github.com/llvm/llvm-project/issues/53525. Differential Revision: https://reviews.llvm.org/D118913
This commit is contained in:
parent
2349fb0312
commit
0447ec2fb0
|
@ -66,11 +66,15 @@ static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
|
|||
Filename.startswith("clang/") || Filename.startswith("clang-c/"))
|
||||
return 2;
|
||||
|
||||
// System headers are sorted to the end.
|
||||
if (IsAngled || Filename.startswith("gtest/") ||
|
||||
Filename.startswith("gmock/"))
|
||||
// Put these between system and llvm headers to be consistent with LLVM
|
||||
// clang-format style.
|
||||
if (Filename.startswith("gtest/") || Filename.startswith("gmock/"))
|
||||
return 3;
|
||||
|
||||
// System headers are sorted to the end.
|
||||
if (IsAngled)
|
||||
return 4;
|
||||
|
||||
// Other headers are inserted between the main module header and LLVM headers.
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "gmock/foo.h"
|
||||
#include "i.h"
|
||||
#include <s.h>
|
||||
#include <a.h>
|
||||
#include "llvm/a.h"
|
||||
#include "clang/b.h"
|
||||
#include "clang-c/c.h" // hi
|
||||
|
@ -19,6 +20,7 @@
|
|||
// CHECK-FIXES-NEXT: #include "llvm/a.h"
|
||||
// CHECK-FIXES-NEXT: #include "gmock/foo.h"
|
||||
// CHECK-FIXES-NEXT: #include "gtest/foo.h"
|
||||
// CHECK-FIXES-NEXT: #include <a.h>
|
||||
// CHECK-FIXES-NEXT: #include <s.h>
|
||||
|
||||
#include "b.h"
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "ClangTidyOptions.h"
|
||||
#include "ClangTidyTest.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/HeaderGuardCheck.h"
|
||||
#include "llvm/IncludeOrderCheck.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
@ -9,11 +12,15 @@ namespace clang {
|
|||
namespace tidy {
|
||||
namespace test {
|
||||
|
||||
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
|
||||
Optional<StringRef> ExpectedWarning) {
|
||||
template <typename T>
|
||||
static std::string runCheck(StringRef Code, const Twine &Filename,
|
||||
Optional<StringRef> ExpectedWarning,
|
||||
std::map<StringRef, StringRef> PathsToContent =
|
||||
std::map<StringRef, StringRef>()) {
|
||||
std::vector<ClangTidyError> Errors;
|
||||
std::string Result = test::runCheckOnCode<LLVMHeaderGuardCheck>(
|
||||
Code, &Errors, Filename, std::string("-xc++-header"));
|
||||
std::string Result = test::runCheckOnCode<T>(
|
||||
Code, &Errors, Filename, std::string("-xc++-header"), ClangTidyOptions{},
|
||||
std::move(PathsToContent));
|
||||
if (Errors.size() != (size_t)ExpectedWarning.hasValue())
|
||||
return "invalid error count";
|
||||
if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message)
|
||||
|
@ -22,27 +29,36 @@ static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
|
|||
return Result;
|
||||
}
|
||||
|
||||
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
|
||||
Optional<StringRef> ExpectedWarning) {
|
||||
return runCheck<LLVMHeaderGuardCheck>(Code, Filename,
|
||||
std::move(ExpectedWarning));
|
||||
}
|
||||
|
||||
static std::string
|
||||
runIncludeOrderCheck(StringRef Code, const Twine &Filename,
|
||||
Optional<StringRef> ExpectedWarning,
|
||||
llvm::ArrayRef<llvm::StringLiteral> Includes) {
|
||||
std::map<StringRef, StringRef> PathsToContent;
|
||||
for (auto Include : Includes)
|
||||
PathsToContent.emplace(Include, "");
|
||||
return runCheck<IncludeOrderCheck>(Code, Filename, std::move(ExpectedWarning),
|
||||
PathsToContent);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct WithEndifComment : public LLVMHeaderGuardCheck {
|
||||
WithEndifComment(StringRef Name, ClangTidyContext *Context)
|
||||
: LLVMHeaderGuardCheck(Name, Context) {}
|
||||
bool shouldSuggestEndifComment(StringRef Filename) override { return true; }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static std::string
|
||||
runHeaderGuardCheckWithEndif(StringRef Code, const Twine &Filename,
|
||||
Optional<StringRef> ExpectedWarning) {
|
||||
std::vector<ClangTidyError> Errors;
|
||||
std::string Result = test::runCheckOnCode<WithEndifComment>(
|
||||
Code, &Errors, Filename, std::string("-xc++-header"));
|
||||
if (Errors.size() != (size_t)ExpectedWarning.hasValue())
|
||||
return "invalid error count";
|
||||
if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message)
|
||||
return "expected: '" + ExpectedWarning->str() + "', saw: '" +
|
||||
Errors.back().Message.Message + "'";
|
||||
return Result;
|
||||
return runCheck<WithEndifComment>(Code, Filename, std::move(ExpectedWarning));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
|
||||
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
||||
|
@ -270,6 +286,23 @@ TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
|
|||
#endif
|
||||
}
|
||||
|
||||
TEST(IncludeOrderCheck, GTestHeaders) {
|
||||
EXPECT_EQ(
|
||||
R"cpp(
|
||||
#include "foo.h"
|
||||
#include "llvm/foo.h"
|
||||
#include "gtest/foo.h"
|
||||
#include <algorithm>)cpp",
|
||||
runIncludeOrderCheck(
|
||||
R"cpp(
|
||||
#include "foo.h"
|
||||
#include "llvm/foo.h"
|
||||
#include <algorithm>
|
||||
#include "gtest/foo.h")cpp",
|
||||
"foo.cc", StringRef("#includes are not sorted properly"),
|
||||
{"foo.h", "algorithm", "gtest/foo.h", "llvm/foo.h"}));
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
||||
|
|
Loading…
Reference in a new issue