Moved GlobList into a separate header file

Summary:
It is a separate abstraction that is used in more contexts than just
a helper for ClangTidyDiagnosticConsumer.

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66747

llvm-svn: 369918
This commit is contained in:
Dmitri Gribenko 2019-08-26 15:44:32 +00:00
parent 3aeed0fd5a
commit a6fed93f0d
10 changed files with 173 additions and 125 deletions

View File

@ -10,6 +10,7 @@ add_clang_library(clangTidy
ClangTidyOptions.cpp ClangTidyOptions.cpp
ClangTidyProfiling.cpp ClangTidyProfiling.cpp
ExpandModularHeadersPPCallbacks.cpp ExpandModularHeadersPPCallbacks.cpp
GlobList.cpp
DEPENDS DEPENDS
ClangSACheckers ClangSACheckers

View File

@ -17,6 +17,7 @@
#include "ClangTidyDiagnosticConsumer.h" #include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyOptions.h" #include "ClangTidyOptions.h"
#include "GlobList.h"
#include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTDiagnostic.h"
#include "clang/Basic/Diagnostic.h" #include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/DiagnosticOptions.h"
@ -118,47 +119,6 @@ ClangTidyError::ClangTidyError(StringRef CheckName,
: tooling::Diagnostic(CheckName, DiagLevel, BuildDirectory), : tooling::Diagnostic(CheckName, DiagLevel, BuildDirectory),
IsWarningAsError(IsWarningAsError) {} IsWarningAsError(IsWarningAsError) {}
// Returns true if GlobList starts with the negative indicator ('-'), removes it
// from the GlobList.
static bool ConsumeNegativeIndicator(StringRef &GlobList) {
GlobList = GlobList.trim(" \r\n");
if (GlobList.startswith("-")) {
GlobList = GlobList.substr(1);
return true;
}
return false;
}
// Converts first glob from the comma-separated list of globs to Regex and
// removes it and the trailing comma from the GlobList.
static llvm::Regex ConsumeGlob(StringRef &GlobList) {
StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find(','));
StringRef Glob = UntrimmedGlob.trim(' ');
GlobList = GlobList.substr(UntrimmedGlob.size() + 1);
SmallString<128> RegexText("^");
StringRef MetaChars("()^$|*+?.[]\\{}");
for (char C : Glob) {
if (C == '*')
RegexText.push_back('.');
else if (MetaChars.find(C) != StringRef::npos)
RegexText.push_back('\\');
RegexText.push_back(C);
}
RegexText.push_back('$');
return llvm::Regex(RegexText);
}
GlobList::GlobList(StringRef Globs)
: Positive(!ConsumeNegativeIndicator(Globs)), Regex(ConsumeGlob(Globs)),
NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
bool GlobList::contains(StringRef S, bool Contains) {
if (Regex.match(S))
Contains = Positive;
if (NextGlob)
Contains = NextGlob->contains(S, Contains);
return Contains;
}
class ClangTidyContext::CachedGlobList { class ClangTidyContext::CachedGlobList {
public: public:

View File

@ -17,7 +17,6 @@
#include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/Timer.h" #include "llvm/Support/Timer.h"
namespace clang { namespace clang {
@ -47,27 +46,6 @@ struct ClangTidyError : tooling::Diagnostic {
bool IsWarningAsError; bool IsWarningAsError;
}; };
/// Read-only set of strings represented as a list of positive and
/// negative globs. Positive globs add all matched strings to the set, negative
/// globs remove them in the order of appearance in the list.
class GlobList {
public:
/// \p GlobList is a comma-separated list of globs (only '*'
/// metacharacter is supported) with optional '-' prefix to denote exclusion.
GlobList(StringRef Globs);
/// Returns \c true if the pattern matches \p S. The result is the last
/// matching glob's Positive flag.
bool contains(StringRef S) { return contains(S, false); }
private:
bool contains(StringRef S, bool Contains);
bool Positive;
llvm::Regex Regex;
std::unique_ptr<GlobList> NextGlob;
};
/// Contains displayed and ignored diagnostic counters for a ClangTidy /// Contains displayed and ignored diagnostic counters for a ClangTidy
/// run. /// run.
struct ClangTidyStats { struct ClangTidyStats {

View File

@ -0,0 +1,56 @@
//===--- tools/extra/clang-tidy/GlobList.cpp ------------------------------===//
//
// 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 "GlobList.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;
using namespace tidy;
// Returns true if GlobList starts with the negative indicator ('-'), removes it
// from the GlobList.
static bool ConsumeNegativeIndicator(StringRef &GlobList) {
GlobList = GlobList.trim(" \r\n");
if (GlobList.startswith("-")) {
GlobList = GlobList.substr(1);
return true;
}
return false;
}
// Converts first glob from the comma-separated list of globs to Regex and
// removes it and the trailing comma from the GlobList.
static llvm::Regex ConsumeGlob(StringRef &GlobList) {
StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find(','));
StringRef Glob = UntrimmedGlob.trim(' ');
GlobList = GlobList.substr(UntrimmedGlob.size() + 1);
SmallString<128> RegexText("^");
StringRef MetaChars("()^$|*+?.[]\\{}");
for (char C : Glob) {
if (C == '*')
RegexText.push_back('.');
else if (MetaChars.find(C) != StringRef::npos)
RegexText.push_back('\\');
RegexText.push_back(C);
}
RegexText.push_back('$');
return llvm::Regex(RegexText);
}
GlobList::GlobList(StringRef Globs)
: Positive(!ConsumeNegativeIndicator(Globs)), Regex(ConsumeGlob(Globs)),
NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
bool GlobList::contains(StringRef S, bool Contains) {
if (Regex.match(S))
Contains = Positive;
if (NextGlob)
Contains = NextGlob->contains(S, Contains);
return Contains;
}

View File

@ -0,0 +1,44 @@
//===--- GlobList.h ---------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GLOBLIST_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GLOBLIST_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Regex.h"
#include <memory>
namespace clang {
namespace tidy {
/// Read-only set of strings represented as a list of positive and
/// negative globs. Positive globs add all matched strings to the set, negative
/// globs remove them in the order of appearance in the list.
class GlobList {
public:
/// \p GlobList is a comma-separated list of globs (only '*'
/// metacharacter is supported) with optional '-' prefix to denote exclusion.
GlobList(StringRef Globs);
/// Returns \c true if the pattern matches \p S. The result is the last
/// matching glob's Positive flag.
bool contains(StringRef S) { return contains(S, false); }
private:
bool contains(StringRef S, bool Contains);
bool Positive;
llvm::Regex Regex;
std::unique_ptr<GlobList> NextGlob;
};
} // end namespace tidy
} // end namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GLOBLIST_H

View File

@ -10,8 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_RESTRICTINCLUDESSCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_RESTRICTINCLUDESSCHECK_H
#include "../ClangTidyCheck.h" #include "../ClangTidyCheck.h"
#include "../ClangTidyDiagnosticConsumer.h" #include "../GlobList.h"
#include "../utils/OptionsUtils.h"
namespace clang { namespace clang {
namespace tidy { namespace tidy {

View File

@ -16,6 +16,7 @@
#include "../ClangTidy.h" #include "../ClangTidy.h"
#include "../ClangTidyForceLinker.h" #include "../ClangTidyForceLinker.h"
#include "../GlobList.h"
#include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/CommonOptionsParser.h"
#include "llvm/Support/Process.h" #include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h" #include "llvm/Support/Signals.h"

View File

@ -10,6 +10,7 @@ add_extra_unittest(ClangTidyTests
ClangTidyDiagnosticConsumerTest.cpp ClangTidyDiagnosticConsumerTest.cpp
ClangTidyOptionsTest.cpp ClangTidyOptionsTest.cpp
IncludeInserterTest.cpp IncludeInserterTest.cpp
GlobListTest.cpp
GoogleModuleTest.cpp GoogleModuleTest.cpp
LLVMModuleTest.cpp LLVMModuleTest.cpp
NamespaceAliaserTest.cpp NamespaceAliaserTest.cpp

View File

@ -29,66 +29,6 @@ TEST(ClangTidyDiagnosticConsumer, SortsErrors) {
EXPECT_EQ("variable", Errors[1].Message.Message); EXPECT_EQ("variable", Errors[1].Message.Message);
} }
TEST(GlobList, Empty) {
GlobList Filter("");
EXPECT_TRUE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aaa"));
}
TEST(GlobList, Nothing) {
GlobList Filter("-*");
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("a"));
EXPECT_FALSE(Filter.contains("-*"));
EXPECT_FALSE(Filter.contains("-"));
EXPECT_FALSE(Filter.contains("*"));
}
TEST(GlobList, Everything) {
GlobList Filter("*");
EXPECT_TRUE(Filter.contains(""));
EXPECT_TRUE(Filter.contains("aaaa"));
EXPECT_TRUE(Filter.contains("-*"));
EXPECT_TRUE(Filter.contains("-"));
EXPECT_TRUE(Filter.contains("*"));
}
TEST(GlobList, Simple) {
GlobList Filter("aaa");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aa"));
EXPECT_FALSE(Filter.contains("aaaa"));
EXPECT_FALSE(Filter.contains("bbb"));
}
TEST(GlobList, WhitespacesAtBegin) {
GlobList Filter("-*, a.b.*");
EXPECT_TRUE(Filter.contains("a.b.c"));
EXPECT_FALSE(Filter.contains("b.c"));
}
TEST(GlobList, Complex) {
GlobList Filter("*,-a.*, -b.*, \r \n a.1.* ,-a.1.A.*,-..,-...,-..+,-*$, -*qwe* ");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_TRUE(Filter.contains("qqq"));
EXPECT_FALSE(Filter.contains("a."));
EXPECT_FALSE(Filter.contains("a.b"));
EXPECT_FALSE(Filter.contains("b."));
EXPECT_FALSE(Filter.contains("b.b"));
EXPECT_TRUE(Filter.contains("a.1.b"));
EXPECT_FALSE(Filter.contains("a.1.A.a"));
EXPECT_FALSE(Filter.contains("qwe"));
EXPECT_FALSE(Filter.contains("asdfqweasdf"));
EXPECT_TRUE(Filter.contains("asdfqwEasdf"));
}
} // namespace test } // namespace test
} // namespace tidy } // namespace tidy
} // namespace clang } // namespace clang

View File

@ -0,0 +1,68 @@
#include "GlobList.h"
#include "gtest/gtest.h"
namespace clang {
namespace tidy {
TEST(GlobList, Empty) {
GlobList Filter("");
EXPECT_TRUE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aaa"));
}
TEST(GlobList, Nothing) {
GlobList Filter("-*");
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("a"));
EXPECT_FALSE(Filter.contains("-*"));
EXPECT_FALSE(Filter.contains("-"));
EXPECT_FALSE(Filter.contains("*"));
}
TEST(GlobList, Everything) {
GlobList Filter("*");
EXPECT_TRUE(Filter.contains(""));
EXPECT_TRUE(Filter.contains("aaaa"));
EXPECT_TRUE(Filter.contains("-*"));
EXPECT_TRUE(Filter.contains("-"));
EXPECT_TRUE(Filter.contains("*"));
}
TEST(GlobList, Simple) {
GlobList Filter("aaa");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aa"));
EXPECT_FALSE(Filter.contains("aaaa"));
EXPECT_FALSE(Filter.contains("bbb"));
}
TEST(GlobList, WhitespacesAtBegin) {
GlobList Filter("-*, a.b.*");
EXPECT_TRUE(Filter.contains("a.b.c"));
EXPECT_FALSE(Filter.contains("b.c"));
}
TEST(GlobList, Complex) {
GlobList Filter("*,-a.*, -b.*, \r \n a.1.* ,-a.1.A.*,-..,-...,-..+,-*$, -*qwe* ");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_TRUE(Filter.contains("qqq"));
EXPECT_FALSE(Filter.contains("a."));
EXPECT_FALSE(Filter.contains("a.b"));
EXPECT_FALSE(Filter.contains("b."));
EXPECT_FALSE(Filter.contains("b.b"));
EXPECT_TRUE(Filter.contains("a.1.b"));
EXPECT_FALSE(Filter.contains("a.1.A.a"));
EXPECT_FALSE(Filter.contains("qwe"));
EXPECT_FALSE(Filter.contains("asdfqweasdf"));
EXPECT_TRUE(Filter.contains("asdfqwEasdf"));
}
} // namespace tidy
} // namespace clang