mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Refactor Matcher to use pimpl and merge match.hh into utils.hh
This commit is contained in:
parent
a3e635fb09
commit
bf6fc50b54
@ -190,7 +190,6 @@ target_sources(ccls PRIVATE
|
|||||||
src/indexer.cc
|
src/indexer.cc
|
||||||
src/log.cc
|
src/log.cc
|
||||||
src/lsp.cc
|
src/lsp.cc
|
||||||
src/match.cc
|
|
||||||
src/message_handler.cc
|
src/message_handler.cc
|
||||||
src/pipeline.cc
|
src/pipeline.cc
|
||||||
src/platform_posix.cc
|
src/platform_posix.cc
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "clang_tu.hh"
|
#include "clang_tu.hh"
|
||||||
#include "filesystem.hh"
|
#include "filesystem.hh"
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
|
|
||||||
#include <clang/Lex/PreprocessorOptions.h>
|
#include <clang/Lex/PreprocessorOptions.h>
|
||||||
@ -574,7 +573,7 @@ void CompletionManager::DiagnosticsUpdate(const std::string &path,
|
|||||||
int debounce) {
|
int debounce) {
|
||||||
static GroupMatch match(g_config->diagnostics.whitelist,
|
static GroupMatch match(g_config->diagnostics.whitelist,
|
||||||
g_config->diagnostics.blacklist);
|
g_config->diagnostics.blacklist);
|
||||||
if (!match.IsMatch(path))
|
if (!match.Matches(path))
|
||||||
return;
|
return;
|
||||||
int64_t now = chrono::duration_cast<chrono::milliseconds>(
|
int64_t now = chrono::duration_cast<chrono::milliseconds>(
|
||||||
chrono::high_resolution_clock::now().time_since_epoch())
|
chrono::high_resolution_clock::now().time_since_epoch())
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "include_complete.hh"
|
#include "include_complete.hh"
|
||||||
|
|
||||||
#include "filesystem.hh"
|
#include "filesystem.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
|
|
||||||
@ -150,7 +149,7 @@ void IncludeComplete::AddFile(const std::string &path) {
|
|||||||
ok = true;
|
ok = true;
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
if (match_ && !match_->IsMatch(path))
|
if (match_ && !match_->Matches(path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string trimmed_path = path;
|
std::string trimmed_path = path;
|
||||||
@ -167,7 +166,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
|
|||||||
bool use_angle_brackets) {
|
bool use_angle_brackets) {
|
||||||
directory = NormalizePath(directory);
|
directory = NormalizePath(directory);
|
||||||
EnsureEndsInSlash(directory);
|
EnsureEndsInSlash(directory);
|
||||||
if (match_ && !match_->IsMatch(directory))
|
if (match_ && !match_->Matches(directory))
|
||||||
return;
|
return;
|
||||||
bool include_cpp = directory.find("include/c++") != std::string::npos;
|
bool include_cpp = directory.find("include/c++") != std::string::npos;
|
||||||
|
|
||||||
@ -181,7 +180,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
|
|||||||
ok = true;
|
ok = true;
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
if (match_ && !match_->IsMatch(directory + path))
|
if (match_ && !match_->Matches(directory + path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CompletionCandidate candidate;
|
CompletionCandidate candidate;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "clang_complete.hh"
|
#include "clang_complete.hh"
|
||||||
#include "clang_tu.hh"
|
#include "clang_tu.hh"
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "serializer.hh"
|
#include "serializer.hh"
|
||||||
@ -85,7 +84,7 @@ struct IndexParam {
|
|||||||
bool UseMultiVersion(const FileEntry &FE) {
|
bool UseMultiVersion(const FileEntry &FE) {
|
||||||
auto it = UID2multi.try_emplace(FE.getUniqueID());
|
auto it = UID2multi.try_emplace(FE.getUniqueID());
|
||||||
if (it.second)
|
if (it.second)
|
||||||
it.first->second = multiVersionMatcher->IsMatch(PathFromFileEntry(FE));
|
it.first->second = multiVersionMatcher->Matches(PathFromFileEntry(FE));
|
||||||
return it.first->second;
|
return it.first->second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
65
src/match.cc
65
src/match.cc
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2017-2018 ccls Authors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#include "match.hh"
|
|
||||||
|
|
||||||
#include "message_handler.hh"
|
|
||||||
#include "pipeline.hh"
|
|
||||||
|
|
||||||
namespace ccls {
|
|
||||||
std::optional<Matcher> Matcher::Create(const std::string &search) {
|
|
||||||
try {
|
|
||||||
Matcher m;
|
|
||||||
m.regex_string = search;
|
|
||||||
m.regex = std::regex(search, std::regex_constants::ECMAScript |
|
|
||||||
std::regex_constants::icase |
|
|
||||||
std::regex_constants::optimize
|
|
||||||
// std::regex_constants::nosubs
|
|
||||||
);
|
|
||||||
return m;
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
ShowMessageParam params;
|
|
||||||
params.type = MessageType::Error;
|
|
||||||
params.message =
|
|
||||||
"failed to parse EMCAScript regex " + search + " : " + e.what();
|
|
||||||
pipeline::Notify(window_showMessage, params);
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Matcher::IsMatch(const std::string &value) const {
|
|
||||||
// std::smatch match;
|
|
||||||
// return std::regex_match(value, match, regex);
|
|
||||||
return std::regex_search(value, regex, std::regex_constants::match_any);
|
|
||||||
}
|
|
||||||
|
|
||||||
GroupMatch::GroupMatch(const std::vector<std::string> &whitelist,
|
|
||||||
const std::vector<std::string> &blacklist) {
|
|
||||||
for (const std::string &entry : whitelist) {
|
|
||||||
std::optional<Matcher> m = Matcher::Create(entry);
|
|
||||||
if (m)
|
|
||||||
this->whitelist.push_back(*m);
|
|
||||||
}
|
|
||||||
for (const std::string &entry : blacklist) {
|
|
||||||
std::optional<Matcher> m = Matcher::Create(entry);
|
|
||||||
if (m)
|
|
||||||
this->blacklist.push_back(*m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GroupMatch::IsMatch(const std::string &value,
|
|
||||||
std::string *match_failure_reason) const {
|
|
||||||
for (const Matcher &m : whitelist)
|
|
||||||
if (m.IsMatch(value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (const Matcher &m : blacklist)
|
|
||||||
if (m.IsMatch(value)) {
|
|
||||||
if (match_failure_reason)
|
|
||||||
*match_failure_reason = "blacklist \"" + m.regex_string + "\"";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace ccls
|
|
33
src/match.hh
33
src/match.hh
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2017-2018 ccls Authors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace ccls {
|
|
||||||
struct Matcher {
|
|
||||||
static std::optional<Matcher> Create(const std::string &search);
|
|
||||||
|
|
||||||
bool IsMatch(const std::string &value) const;
|
|
||||||
|
|
||||||
std::string regex_string;
|
|
||||||
std::regex regex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check multiple |Matcher| instances at the same time.
|
|
||||||
struct GroupMatch {
|
|
||||||
GroupMatch(const std::vector<std::string> &whitelist,
|
|
||||||
const std::vector<std::string> &blacklist);
|
|
||||||
|
|
||||||
bool IsMatch(const std::string &value,
|
|
||||||
std::string *match_failure_reason = nullptr) const;
|
|
||||||
|
|
||||||
std::vector<Matcher> whitelist;
|
|
||||||
std::vector<Matcher> blacklist;
|
|
||||||
};
|
|
||||||
} // namespace ccls
|
|
@ -4,7 +4,6 @@
|
|||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
#include "query_utils.hh"
|
#include "query_utils.hh"
|
||||||
@ -263,7 +262,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) {
|
|||||||
g_config->highlight.blacklist);
|
g_config->highlight.blacklist);
|
||||||
assert(file.def);
|
assert(file.def);
|
||||||
if (wfile->buffer_content.size() > g_config->highlight.largeFileSize ||
|
if (wfile->buffer_content.size() > g_config->highlight.largeFileSize ||
|
||||||
!match.IsMatch(file.def->path))
|
!match.Matches(file.def->path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Group symbols together.
|
// Group symbols together.
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#include "clang_complete.hh"
|
#include "clang_complete.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "include_complete.hh"
|
#include "include_complete.hh"
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "lsp.hh"
|
#include "lsp.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
@ -187,7 +186,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matcher.IsMatch(request.path)) {
|
if (!matcher.Matches(request.path)) {
|
||||||
LOG_IF_S(INFO, loud) << "skip " << request.path;
|
LOG_IF_S(INFO, loud) << "skip " << request.path;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -309,7 +308,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
|
|||||||
|
|
||||||
for (std::unique_ptr<IndexFile> &curr : indexes) {
|
for (std::unique_ptr<IndexFile> &curr : indexes) {
|
||||||
std::string path = curr->path;
|
std::string path = curr->path;
|
||||||
if (!matcher.IsMatch(path)) {
|
if (!matcher.Matches(path)) {
|
||||||
LOG_IF_S(INFO, loud) << "skip index for " << path;
|
LOG_IF_S(INFO, loud) << "skip index for " << path;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "clang_tu.hh" // llvm::vfs
|
#include "clang_tu.hh" // llvm::vfs
|
||||||
#include "filesystem.hh"
|
#include "filesystem.hh"
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "match.hh"
|
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "serializers/json.hh"
|
#include "serializers/json.hh"
|
||||||
@ -485,8 +484,8 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (const Project::Entry &entry : folder.entries) {
|
for (const Project::Entry &entry : folder.entries) {
|
||||||
std::string reason;
|
std::string reason;
|
||||||
if (match.IsMatch(entry.filename, &reason) &&
|
if (match.Matches(entry.filename, &reason) &&
|
||||||
match_i.IsMatch(entry.filename, &reason)) {
|
match_i.Matches(entry.filename, &reason)) {
|
||||||
bool interactive =
|
bool interactive =
|
||||||
wfiles->GetFileByFilename(entry.filename) != nullptr;
|
wfiles->GetFileByFilename(entry.filename) != nullptr;
|
||||||
pipeline::Index(
|
pipeline::Index(
|
||||||
|
59
src/utils.cc
59
src/utils.cc
@ -4,6 +4,8 @@
|
|||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
|
#include "message_handler.hh"
|
||||||
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
|
|
||||||
#include <siphash.h>
|
#include <siphash.h>
|
||||||
@ -18,10 +20,67 @@ using namespace llvm;
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <regex>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
|
struct Matcher::Impl {
|
||||||
|
std::regex regex;
|
||||||
|
};
|
||||||
|
|
||||||
|
Matcher::Matcher(const std::string &pattern)
|
||||||
|
: impl(std::make_unique<Impl>()), pattern(pattern) {
|
||||||
|
impl->regex = std::regex(pattern, std::regex_constants::ECMAScript |
|
||||||
|
std::regex_constants::icase |
|
||||||
|
std::regex_constants::optimize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher::~Matcher() {}
|
||||||
|
|
||||||
|
bool Matcher::Matches(const std::string &text) const {
|
||||||
|
return std::regex_search(text, impl->regex, std::regex_constants::match_any);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupMatch::GroupMatch(const std::vector<std::string> &whitelist,
|
||||||
|
const std::vector<std::string> &blacklist) {
|
||||||
|
auto err = [](const std::string &pattern, const char *what) {
|
||||||
|
ShowMessageParam params;
|
||||||
|
params.type = MessageType::Error;
|
||||||
|
params.message =
|
||||||
|
"failed to parse EMCAScript regex " + pattern + " : " + what;
|
||||||
|
pipeline::Notify(window_showMessage, params);
|
||||||
|
};
|
||||||
|
for (const std::string &pattern : whitelist) {
|
||||||
|
try {
|
||||||
|
this->whitelist.emplace_back(pattern);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
err(pattern, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const std::string &pattern : blacklist) {
|
||||||
|
try {
|
||||||
|
this->blacklist.emplace_back(pattern);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
err(pattern, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GroupMatch::Matches(const std::string &text,
|
||||||
|
std::string *blacklist_pattern) const {
|
||||||
|
for (const Matcher &m : whitelist)
|
||||||
|
if (m.Matches(text))
|
||||||
|
return true;
|
||||||
|
for (const Matcher &m : blacklist)
|
||||||
|
if (m.Matches(text)) {
|
||||||
|
if (blacklist_pattern)
|
||||||
|
*blacklist_pattern = m.pattern;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t HashUsr(llvm::StringRef s) {
|
uint64_t HashUsr(llvm::StringRef s) {
|
||||||
union {
|
union {
|
||||||
uint64_t ret;
|
uint64_t ret;
|
||||||
|
21
src/utils.hh
21
src/utils.hh
@ -7,6 +7,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -15,6 +16,26 @@ class StringRef;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
|
struct Matcher {
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl;
|
||||||
|
std::string pattern;
|
||||||
|
|
||||||
|
Matcher(const std::string &pattern); // throw
|
||||||
|
Matcher(Matcher&&) = default;
|
||||||
|
~Matcher();
|
||||||
|
bool Matches(const std::string &text) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GroupMatch {
|
||||||
|
std::vector<Matcher> whitelist, blacklist;
|
||||||
|
|
||||||
|
GroupMatch(const std::vector<std::string> &whitelist,
|
||||||
|
const std::vector<std::string> &blacklist);
|
||||||
|
bool Matches(const std::string &text,
|
||||||
|
std::string *blacklist_pattern = nullptr) const;
|
||||||
|
};
|
||||||
|
|
||||||
uint64_t HashUsr(llvm::StringRef s);
|
uint64_t HashUsr(llvm::StringRef s);
|
||||||
|
|
||||||
std::string LowerPathIfInsensitive(const std::string &path);
|
std::string LowerPathIfInsensitive(const std::string &path);
|
||||||
|
Loading…
Reference in New Issue
Block a user