mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-24 00:25:07 +00:00
diagnostics; use custom DenseMapInfo
This commit is contained in:
parent
11890fc3b1
commit
709a2654a8
@ -188,17 +188,15 @@ bool Parse(CompilerInstance &Clang) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompletionPreloadMain(CompletionManager *completion_manager) {
|
void CompletionPreloadMain(CompletionManager *manager) {
|
||||||
while (true) {
|
while (true) {
|
||||||
// Fetching the completion request blocks until we have a request.
|
// Fetching the completion request blocks until we have a request.
|
||||||
auto request = completion_manager->preload_requests_.Dequeue();
|
auto request = manager->preload_requests_.Dequeue();
|
||||||
|
|
||||||
// If we don't get a session then that means we don't care about the file
|
// If we don't get a session then that means we don't care about the file
|
||||||
// anymore - abandon the request.
|
// anymore - abandon the request.
|
||||||
std::shared_ptr<CompletionSession> session =
|
std::shared_ptr<CompletionSession> session = manager->TryGetSession(
|
||||||
completion_manager->TryGetSession(request.path,
|
request.path, false /*mark_as_completion*/, false /*create_if_needed*/);
|
||||||
false /*mark_as_completion*/,
|
|
||||||
false /*create_if_needed*/);
|
|
||||||
if (!session)
|
if (!session)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -210,6 +208,11 @@ void CompletionPreloadMain(CompletionManager *completion_manager) {
|
|||||||
if (std::unique_ptr<CompilerInvocation> CI =
|
if (std::unique_ptr<CompilerInvocation> CI =
|
||||||
BuildCompilerInvocation(args, session->FS))
|
BuildCompilerInvocation(args, session->FS))
|
||||||
session->BuildPreamble(*CI);
|
session->BuildPreamble(*CI);
|
||||||
|
if (g_config->diagnostics.onSave) {
|
||||||
|
lsTextDocumentIdentifier document;
|
||||||
|
document.uri = lsDocumentUri::FromPath(request.path);
|
||||||
|
manager->diagnostic_request_.PushBack({document}, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +408,7 @@ void CompletionManager::DiagnosticsUpdate(
|
|||||||
void CompletionManager::NotifyView(const std::string &path) {
|
void CompletionManager::NotifyView(const std::string &path) {
|
||||||
// Only reparse the file if we create a new CompletionSession.
|
// Only reparse the file if we create a new CompletionSession.
|
||||||
if (EnsureCompletionOrCreatePreloadSession(path))
|
if (EnsureCompletionOrCreatePreloadSession(path))
|
||||||
preload_requests_.PushBack(PreloadRequest(path), true);
|
preload_requests_.PushBack(PreloadRequest{path}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompletionManager::NotifySave(const std::string &filename) {
|
void CompletionManager::NotifySave(const std::string &filename) {
|
||||||
@ -414,7 +417,7 @@ void CompletionManager::NotifySave(const std::string &filename) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
EnsureCompletionOrCreatePreloadSession(filename);
|
EnsureCompletionOrCreatePreloadSession(filename);
|
||||||
preload_requests_.PushBack(PreloadRequest(filename), true);
|
preload_requests_.PushBack(PreloadRequest{filename}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompletionManager::NotifyClose(const std::string &filename) {
|
void CompletionManager::NotifyClose(const std::string &filename) {
|
||||||
|
@ -74,10 +74,6 @@ struct CompletionManager {
|
|||||||
using OnDropped = std::function<void(lsRequestId request_id)>;
|
using OnDropped = std::function<void(lsRequestId request_id)>;
|
||||||
|
|
||||||
struct PreloadRequest {
|
struct PreloadRequest {
|
||||||
PreloadRequest(const std::string &path)
|
|
||||||
: request_time(std::chrono::high_resolution_clock::now()), path(path) {}
|
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> request_time;
|
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
struct CompletionRequest {
|
struct CompletionRequest {
|
||||||
|
@ -37,8 +37,6 @@ struct Handler_TextDocumentDidSave
|
|||||||
Project::Entry entry = project->FindCompilationEntryForFile(path);
|
Project::Entry entry = project->FindCompilationEntryForFile(path);
|
||||||
pipeline::Index(entry.filename, entry.args, IndexMode::Normal);
|
pipeline::Index(entry.filename, entry.args, IndexMode::Normal);
|
||||||
clang_complete->NotifySave(path);
|
clang_complete->NotifySave(path);
|
||||||
if (g_config->diagnostics.onSave)
|
|
||||||
clang_complete->DiagnosticsUpdate(params.textDocument);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave);
|
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave);
|
||||||
|
61
src/query.cc
61
src/query.cc
@ -238,36 +238,37 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
|
|||||||
.outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta;
|
.outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto UpdateUses = [&](Usr usr, SymbolKind kind,
|
auto UpdateUses =
|
||||||
llvm::DenseMap<WrappedUsr, int> &entity_usr,
|
[&](Usr usr, SymbolKind kind,
|
||||||
auto &entities, auto &p, bool hint_implicit) {
|
llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
|
||||||
auto R = entity_usr.try_emplace({usr}, entity_usr.size());
|
auto &entities, auto &p, bool hint_implicit) {
|
||||||
if (R.second)
|
auto R = entity_usr.try_emplace(usr, entity_usr.size());
|
||||||
vars.emplace_back().usr = usr;
|
if (R.second)
|
||||||
auto &entity = entities[R.first->second];
|
vars.emplace_back().usr = usr;
|
||||||
for (Use &use : p.first) {
|
auto &entity = entities[R.first->second];
|
||||||
if (hint_implicit && use.role & Role::Implicit) {
|
for (Use &use : p.first) {
|
||||||
// Make ranges of implicit function calls larger (spanning one more
|
if (hint_implicit && use.role & Role::Implicit) {
|
||||||
// column to the left/right). This is hacky but useful. e.g.
|
// Make ranges of implicit function calls larger (spanning one more
|
||||||
// textDocument/definition on the space/semicolon in `A a;` or ` 42;`
|
// column to the left/right). This is hacky but useful. e.g.
|
||||||
// will take you to the constructor.
|
// textDocument/definition on the space/semicolon in `A a;` or `
|
||||||
if (use.range.start.column > 0)
|
// 42;` will take you to the constructor.
|
||||||
use.range.start.column--;
|
if (use.range.start.column > 0)
|
||||||
use.range.end.column++;
|
use.range.start.column--;
|
||||||
}
|
use.range.end.column++;
|
||||||
Ref(prev_lid2file_id, usr, kind, use, -1);
|
}
|
||||||
}
|
Ref(prev_lid2file_id, usr, kind, use, -1);
|
||||||
RemoveRange(entity.uses, p.first);
|
}
|
||||||
for (Use &use : p.second) {
|
RemoveRange(entity.uses, p.first);
|
||||||
if (hint_implicit && use.role & Role::Implicit) {
|
for (Use &use : p.second) {
|
||||||
if (use.range.start.column > 0)
|
if (hint_implicit && use.role & Role::Implicit) {
|
||||||
use.range.start.column--;
|
if (use.range.start.column > 0)
|
||||||
use.range.end.column++;
|
use.range.start.column--;
|
||||||
}
|
use.range.end.column++;
|
||||||
Ref(lid2file_id, usr, kind, use, 1);
|
}
|
||||||
}
|
Ref(lid2file_id, usr, kind, use, 1);
|
||||||
AddRange(entity.uses, p.second);
|
}
|
||||||
};
|
AddRange(entity.uses, p.second);
|
||||||
|
};
|
||||||
|
|
||||||
if (u->files_removed)
|
if (u->files_removed)
|
||||||
files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def =
|
files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def =
|
||||||
|
27
src/query.h
27
src/query.h
@ -136,14 +136,11 @@ struct IndexUpdate {
|
|||||||
UseUpdate vars_uses;
|
UseUpdate vars_uses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WrappedUsr {
|
struct DenseMapInfoForUsr {
|
||||||
Usr usr;
|
static inline Usr getEmptyKey() { return 0; }
|
||||||
};
|
static inline Usr getTombstoneKey() { return ~0ULL; }
|
||||||
template <> struct llvm::DenseMapInfo<WrappedUsr> {
|
static unsigned getHashValue(Usr w) { return w; }
|
||||||
static inline WrappedUsr getEmptyKey() { return {0}; }
|
static bool isEqual(Usr l, Usr r) { return l == r; }
|
||||||
static inline WrappedUsr getTombstoneKey() { return {~0ULL}; }
|
|
||||||
static unsigned getHashValue(WrappedUsr w) { return w.usr; }
|
|
||||||
static bool isEqual(WrappedUsr l, WrappedUsr r) { return l.usr == r.usr; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using Lid2file_id = std::unordered_map<int, int>;
|
using Lid2file_id = std::unordered_map<int, int>;
|
||||||
@ -153,7 +150,7 @@ using Lid2file_id = std::unordered_map<int, int>;
|
|||||||
struct DB {
|
struct DB {
|
||||||
std::vector<QueryFile> files;
|
std::vector<QueryFile> files;
|
||||||
llvm::StringMap<int> name2file_id;
|
llvm::StringMap<int> name2file_id;
|
||||||
llvm::DenseMap<WrappedUsr, int> func_usr, type_usr, var_usr;
|
llvm::DenseMap<Usr, int, DenseMapInfoForUsr> func_usr, type_usr, var_usr;
|
||||||
std::vector<QueryFunc> funcs;
|
std::vector<QueryFunc> funcs;
|
||||||
std::vector<QueryType> types;
|
std::vector<QueryType> types;
|
||||||
std::vector<QueryVar> vars;
|
std::vector<QueryVar> vars;
|
||||||
@ -173,13 +170,13 @@ struct DB {
|
|||||||
std::vector<std::pair<Usr, QueryVar::Def>> &&us);
|
std::vector<std::pair<Usr, QueryVar::Def>> &&us);
|
||||||
std::string_view GetSymbolName(SymbolIdx sym, bool qualified);
|
std::string_view GetSymbolName(SymbolIdx sym, bool qualified);
|
||||||
|
|
||||||
bool HasFunc(Usr usr) const { return func_usr.count({usr}); }
|
bool HasFunc(Usr usr) const { return func_usr.count(usr); }
|
||||||
bool HasType(Usr usr) const { return type_usr.count({usr}); }
|
bool HasType(Usr usr) const { return type_usr.count(usr); }
|
||||||
bool HasVar(Usr usr) const { return var_usr.count({usr}); }
|
bool HasVar(Usr usr) const { return var_usr.count(usr); }
|
||||||
|
|
||||||
QueryFunc &Func(Usr usr) { return funcs[func_usr[{usr}]]; }
|
QueryFunc &Func(Usr usr) { return funcs[func_usr[usr]]; }
|
||||||
QueryType &Type(Usr usr) { return types[type_usr[{usr}]]; }
|
QueryType &Type(Usr usr) { return types[type_usr[usr]]; }
|
||||||
QueryVar &Var(Usr usr) { return vars[var_usr[{usr}]]; }
|
QueryVar &Var(Usr usr) { return vars[var_usr[usr]]; }
|
||||||
|
|
||||||
QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; }
|
QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; }
|
||||||
QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); }
|
QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); }
|
||||||
|
@ -18,9 +18,9 @@ int ComputeRangeSize(const Range &range) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Q>
|
template <typename Q>
|
||||||
std::vector<Use> GetDeclarations(llvm::DenseMap<WrappedUsr, int> &entity_usr,
|
std::vector<Use>
|
||||||
std::vector<Q> &entities,
|
GetDeclarations(llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
|
||||||
const std::vector<Usr> &usrs) {
|
std::vector<Q> &entities, const std::vector<Usr> &usrs) {
|
||||||
std::vector<Use> ret;
|
std::vector<Use> ret;
|
||||||
ret.reserve(usrs.size());
|
ret.reserve(usrs.size());
|
||||||
for (Usr usr : usrs) {
|
for (Usr usr : usrs) {
|
||||||
|
Loading…
Reference in New Issue
Block a user