[NFC][SpecialCaseList] Replace callback with return value (#165943)
This commit introduces `SpecialCaseList::Match`, a small struct to hold the matched rule and its line number. This simplifies the `match` methods by allowing them to return a single value instead of using a callback. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
0767c64043
commit
a1934ee500
@ -126,15 +126,16 @@ protected:
|
||||
SpecialCaseList &operator=(SpecialCaseList const &) = delete;
|
||||
|
||||
private:
|
||||
using Match = std::pair<StringRef, unsigned>;
|
||||
static constexpr Match NotMatched = {"", 0};
|
||||
|
||||
// Lagacy v1 matcher.
|
||||
class RegexMatcher {
|
||||
public:
|
||||
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
|
||||
LLVM_ABI void preprocess(bool BySize);
|
||||
|
||||
LLVM_ABI void
|
||||
match(StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
|
||||
LLVM_ABI Match match(StringRef Query) const;
|
||||
|
||||
struct Reg {
|
||||
Reg(StringRef Name, unsigned LineNo, Regex &&Rg)
|
||||
@ -152,9 +153,7 @@ private:
|
||||
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
|
||||
LLVM_ABI void preprocess(bool BySize);
|
||||
|
||||
LLVM_ABI void
|
||||
match(StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
|
||||
LLVM_ABI Match match(StringRef Query) const;
|
||||
|
||||
struct Glob {
|
||||
Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern)
|
||||
@ -168,11 +167,10 @@ private:
|
||||
|
||||
RadixTree<iterator_range<StringRef::const_iterator>,
|
||||
RadixTree<iterator_range<StringRef::const_reverse_iterator>,
|
||||
SmallVector<const GlobMatcher::Glob *, 1>>>
|
||||
SmallVector<int, 1>>>
|
||||
PrefixSuffixToGlob;
|
||||
|
||||
RadixTree<iterator_range<StringRef::const_iterator>,
|
||||
SmallVector<const GlobMatcher::Glob *, 1>>
|
||||
RadixTree<iterator_range<StringRef::const_iterator>, SmallVector<int, 1>>
|
||||
SubstrToGlob;
|
||||
};
|
||||
|
||||
@ -184,14 +182,10 @@ private:
|
||||
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
|
||||
LLVM_ABI void preprocess(bool BySize);
|
||||
|
||||
LLVM_ABI void
|
||||
match(StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
|
||||
LLVM_ABI Match match(StringRef Query) const;
|
||||
|
||||
LLVM_ABI bool matchAny(StringRef Query) const {
|
||||
bool R = false;
|
||||
match(Query, [&](StringRef, unsigned) { R = true; });
|
||||
return R;
|
||||
return match(Query) != NotMatched;
|
||||
}
|
||||
|
||||
std::variant<RegexMatcher, GlobMatcher> M;
|
||||
|
||||
@ -15,11 +15,13 @@
|
||||
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/LineIterator.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
@ -63,12 +65,12 @@ void SpecialCaseList::RegexMatcher::preprocess(bool BySize) {
|
||||
}
|
||||
}
|
||||
|
||||
void SpecialCaseList::RegexMatcher::match(
|
||||
StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
|
||||
SpecialCaseList::Match
|
||||
SpecialCaseList::RegexMatcher::match(StringRef Query) const {
|
||||
for (const auto &R : reverse(RegExes))
|
||||
if (R.Rg.match(Query))
|
||||
return Cb(R.Name, R.LineNo);
|
||||
return {R.Name, R.LineNo};
|
||||
return NotMatched;
|
||||
}
|
||||
|
||||
Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
|
||||
@ -90,7 +92,7 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
|
||||
});
|
||||
}
|
||||
|
||||
for (const auto &G : reverse(Globs)) {
|
||||
for (const auto &[Idx, G] : enumerate(Globs)) {
|
||||
StringRef Prefix = G.Pattern.prefix();
|
||||
StringRef Suffix = G.Pattern.suffix();
|
||||
|
||||
@ -102,26 +104,29 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
|
||||
// But only if substring is not empty. Searching this tree is more
|
||||
// expensive.
|
||||
auto &V = SubstrToGlob.emplace(Substr).first->second;
|
||||
V.emplace_back(&G);
|
||||
V.emplace_back(Idx);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto &SToGlob = PrefixSuffixToGlob.emplace(Prefix).first->second;
|
||||
auto &V = SToGlob.emplace(reverse(Suffix)).first->second;
|
||||
V.emplace_back(&G);
|
||||
V.emplace_back(Idx);
|
||||
}
|
||||
}
|
||||
|
||||
void SpecialCaseList::GlobMatcher::match(
|
||||
StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
|
||||
SpecialCaseList::Match
|
||||
SpecialCaseList::GlobMatcher::match(StringRef Query) const {
|
||||
int Best = -1;
|
||||
if (!PrefixSuffixToGlob.empty()) {
|
||||
for (const auto &[_, SToGlob] : PrefixSuffixToGlob.find_prefixes(Query)) {
|
||||
for (const auto &[_, V] : SToGlob.find_prefixes(reverse(Query))) {
|
||||
for (const auto *G : V) {
|
||||
if (G->Pattern.match(Query)) {
|
||||
Cb(G->Name, G->LineNo);
|
||||
for (int Idx : reverse(V)) {
|
||||
if (Best > Idx)
|
||||
break;
|
||||
const GlobMatcher::Glob &G = Globs[Idx];
|
||||
if (G.Pattern.match(Query)) {
|
||||
Best = Idx;
|
||||
// As soon as we find a match in the vector, we can break for this
|
||||
// vector, since the globs are already sorted by priority within the
|
||||
// prefix group. However, we continue searching other prefix groups
|
||||
@ -138,9 +143,12 @@ void SpecialCaseList::GlobMatcher::match(
|
||||
// possibilities. In most cases search will fail on first characters.
|
||||
for (StringRef Q = Query; !Q.empty(); Q = Q.drop_front()) {
|
||||
for (const auto &[_, V] : SubstrToGlob.find_prefixes(Q)) {
|
||||
for (const auto *G : V) {
|
||||
if (G->Pattern.match(Query)) {
|
||||
Cb(G->Name, G->LineNo);
|
||||
for (int Idx : reverse(V)) {
|
||||
if (Best > Idx)
|
||||
break;
|
||||
const GlobMatcher::Glob &G = Globs[Idx];
|
||||
if (G.Pattern.match(Query)) {
|
||||
Best = Idx;
|
||||
// As soon as we find a match in the vector, we can break for this
|
||||
// vector, since the globs are already sorted by priority within the
|
||||
// prefix group. However, we continue searching other prefix groups
|
||||
@ -151,6 +159,9 @@ void SpecialCaseList::GlobMatcher::match(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Best < 0)
|
||||
return NotMatched;
|
||||
return {Globs[Best].Name, Globs[Best].LineNo};
|
||||
}
|
||||
|
||||
SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
|
||||
@ -169,12 +180,11 @@ void SpecialCaseList::Matcher::preprocess(bool BySize) {
|
||||
return std::visit([&](auto &V) { return V.preprocess(BySize); }, M);
|
||||
}
|
||||
|
||||
void SpecialCaseList::Matcher::match(
|
||||
StringRef Query,
|
||||
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
|
||||
SpecialCaseList::Match SpecialCaseList::Matcher::match(StringRef Query) const {
|
||||
if (RemoveDotSlash)
|
||||
Query = llvm::sys::path::remove_leading_dotslash(Query);
|
||||
return std::visit([&](auto &V) { return V.match(Query, Cb); }, M);
|
||||
return std::visit(
|
||||
[&](auto &V) -> SpecialCaseList::Match { return V.match(Query); }, M);
|
||||
}
|
||||
|
||||
// TODO: Refactor this to return Expected<...>
|
||||
@ -375,26 +385,17 @@ LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) {
|
||||
unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix,
|
||||
StringRef Query,
|
||||
StringRef Category) const {
|
||||
unsigned LastLine = 0;
|
||||
if (const Matcher *M = findMatcher(Prefix, Category)) {
|
||||
M->match(Query, [&](StringRef, unsigned LineNo) {
|
||||
LastLine = std::max(LastLine, LineNo);
|
||||
});
|
||||
}
|
||||
return LastLine;
|
||||
if (const Matcher *M = findMatcher(Prefix, Category))
|
||||
return M->match(Query).second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
StringRef SpecialCaseList::Section::getLongestMatch(StringRef Prefix,
|
||||
StringRef Query,
|
||||
StringRef Category) const {
|
||||
StringRef LongestRule;
|
||||
if (const Matcher *M = findMatcher(Prefix, Category)) {
|
||||
M->match(Query, [&](StringRef Rule, unsigned) {
|
||||
if (LongestRule.size() < Rule.size())
|
||||
LongestRule = Rule;
|
||||
});
|
||||
}
|
||||
return LongestRule;
|
||||
if (const Matcher *M = findMatcher(Prefix, Category))
|
||||
return M->match(Query).first;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool SpecialCaseList::Section::hasPrefix(StringRef Prefix) const {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user