diagnostics; use custom DenseMapInfo

This commit is contained in:
Fangrui Song 2018-09-11 16:42:04 -07:00
parent 11890fc3b1
commit 709a2654a8
6 changed files with 57 additions and 62 deletions

View File

@ -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) {

View File

@ -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 {

View File

@ -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);

View File

@ -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 =

View File

@ -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); }

View File

@ -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) {