diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 0dbf9979..ee8d954b 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -188,17 +188,15 @@ bool Parse(CompilerInstance &Clang) { return true; } -void CompletionPreloadMain(CompletionManager *completion_manager) { +void CompletionPreloadMain(CompletionManager *manager) { while (true) { // 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 // anymore - abandon the request. - std::shared_ptr session = - completion_manager->TryGetSession(request.path, - false /*mark_as_completion*/, - false /*create_if_needed*/); + std::shared_ptr session = manager->TryGetSession( + request.path, false /*mark_as_completion*/, false /*create_if_needed*/); if (!session) continue; @@ -210,6 +208,11 @@ void CompletionPreloadMain(CompletionManager *completion_manager) { if (std::unique_ptr CI = BuildCompilerInvocation(args, session->FS)) 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) { // Only reparse the file if we create a new CompletionSession. if (EnsureCompletionOrCreatePreloadSession(path)) - preload_requests_.PushBack(PreloadRequest(path), true); + preload_requests_.PushBack(PreloadRequest{path}, true); } void CompletionManager::NotifySave(const std::string &filename) { @@ -414,7 +417,7 @@ void CompletionManager::NotifySave(const std::string &filename) { // EnsureCompletionOrCreatePreloadSession(filename); - preload_requests_.PushBack(PreloadRequest(filename), true); + preload_requests_.PushBack(PreloadRequest{filename}, true); } void CompletionManager::NotifyClose(const std::string &filename) { diff --git a/src/clang_complete.hh b/src/clang_complete.hh index 5c2b2df2..f22dd849 100644 --- a/src/clang_complete.hh +++ b/src/clang_complete.hh @@ -74,10 +74,6 @@ struct CompletionManager { using OnDropped = std::function; struct PreloadRequest { - PreloadRequest(const std::string &path) - : request_time(std::chrono::high_resolution_clock::now()), path(path) {} - - std::chrono::time_point request_time; std::string path; }; struct CompletionRequest { diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index 9d9b7101..25c8bc81 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -37,8 +37,6 @@ struct Handler_TextDocumentDidSave Project::Entry entry = project->FindCompilationEntryForFile(path); pipeline::Index(entry.filename, entry.args, IndexMode::Normal); clang_complete->NotifySave(path); - if (g_config->diagnostics.onSave) - clang_complete->DiagnosticsUpdate(params.textDocument); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidSave); diff --git a/src/query.cc b/src/query.cc index 3b114be4..6d15965a 100644 --- a/src/query.cc +++ b/src/query.cc @@ -238,36 +238,37 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) { .outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta; }; - auto UpdateUses = [&](Usr usr, SymbolKind kind, - llvm::DenseMap &entity_usr, - auto &entities, auto &p, bool hint_implicit) { - auto R = entity_usr.try_emplace({usr}, entity_usr.size()); - if (R.second) - vars.emplace_back().usr = usr; - auto &entity = entities[R.first->second]; - for (Use &use : p.first) { - if (hint_implicit && use.role & Role::Implicit) { - // Make ranges of implicit function calls larger (spanning one more - // column to the left/right). This is hacky but useful. e.g. - // textDocument/definition on the space/semicolon in `A a;` or ` 42;` - // will take you to the constructor. - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; - } - Ref(prev_lid2file_id, usr, kind, use, -1); - } - RemoveRange(entity.uses, p.first); - for (Use &use : p.second) { - if (hint_implicit && use.role & Role::Implicit) { - if (use.range.start.column > 0) - use.range.start.column--; - use.range.end.column++; - } - Ref(lid2file_id, usr, kind, use, 1); - } - AddRange(entity.uses, p.second); - }; + auto UpdateUses = + [&](Usr usr, SymbolKind kind, + llvm::DenseMap &entity_usr, + auto &entities, auto &p, bool hint_implicit) { + auto R = entity_usr.try_emplace(usr, entity_usr.size()); + if (R.second) + vars.emplace_back().usr = usr; + auto &entity = entities[R.first->second]; + for (Use &use : p.first) { + if (hint_implicit && use.role & Role::Implicit) { + // Make ranges of implicit function calls larger (spanning one more + // column to the left/right). This is hacky but useful. e.g. + // textDocument/definition on the space/semicolon in `A a;` or ` + // 42;` will take you to the constructor. + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; + } + Ref(prev_lid2file_id, usr, kind, use, -1); + } + RemoveRange(entity.uses, p.first); + for (Use &use : p.second) { + if (hint_implicit && use.role & Role::Implicit) { + if (use.range.start.column > 0) + use.range.start.column--; + use.range.end.column++; + } + Ref(lid2file_id, usr, kind, use, 1); + } + AddRange(entity.uses, p.second); + }; if (u->files_removed) files[name2file_id[LowerPathIfInsensitive(*u->files_removed)]].def = diff --git a/src/query.h b/src/query.h index aa597e6c..1eaa6499 100644 --- a/src/query.h +++ b/src/query.h @@ -136,14 +136,11 @@ struct IndexUpdate { UseUpdate vars_uses; }; -struct WrappedUsr { - Usr usr; -}; -template <> struct llvm::DenseMapInfo { - static inline WrappedUsr getEmptyKey() { return {0}; } - 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; } +struct DenseMapInfoForUsr { + static inline Usr getEmptyKey() { return 0; } + static inline Usr getTombstoneKey() { return ~0ULL; } + static unsigned getHashValue(Usr w) { return w; } + static bool isEqual(Usr l, Usr r) { return l == r; } }; using Lid2file_id = std::unordered_map; @@ -153,7 +150,7 @@ using Lid2file_id = std::unordered_map; struct DB { std::vector files; llvm::StringMap name2file_id; - llvm::DenseMap func_usr, type_usr, var_usr; + llvm::DenseMap func_usr, type_usr, var_usr; std::vector funcs; std::vector types; std::vector vars; @@ -173,13 +170,13 @@ struct DB { std::vector> &&us); std::string_view GetSymbolName(SymbolIdx sym, bool qualified); - bool HasFunc(Usr usr) const { return func_usr.count({usr}); } - bool HasType(Usr usr) const { return type_usr.count({usr}); } - bool HasVar(Usr usr) const { return var_usr.count({usr}); } + bool HasFunc(Usr usr) const { return func_usr.count(usr); } + bool HasType(Usr usr) const { return type_usr.count(usr); } + bool HasVar(Usr usr) const { return var_usr.count(usr); } - QueryFunc &Func(Usr usr) { return funcs[func_usr[{usr}]]; } - QueryType &Type(Usr usr) { return types[type_usr[{usr}]]; } - QueryVar &Var(Usr usr) { return vars[var_usr[{usr}]]; } + QueryFunc &Func(Usr usr) { return funcs[func_usr[usr]]; } + QueryType &Type(Usr usr) { return types[type_usr[usr]]; } + QueryVar &Var(Usr usr) { return vars[var_usr[usr]]; } QueryFile &GetFile(SymbolIdx ref) { return files[ref.usr]; } QueryFunc &GetFunc(SymbolIdx ref) { return Func(ref.usr); } diff --git a/src/query_utils.cc b/src/query_utils.cc index d07dccc6..963166a5 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -18,9 +18,9 @@ int ComputeRangeSize(const Range &range) { } template -std::vector GetDeclarations(llvm::DenseMap &entity_usr, - std::vector &entities, - const std::vector &usrs) { +std::vector +GetDeclarations(llvm::DenseMap &entity_usr, + std::vector &entities, const std::vector &usrs) { std::vector ret; ret.reserve(usrs.size()); for (Usr usr : usrs) {