From 9429dff63aceceabac1a7ae8a477790c0b453414 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Sun, 22 Oct 2017 21:49:17 -0700 Subject: [PATCH] Try to only ever have one completion session per file. --- src/clang_complete.cc | 61 +++++++++++++++++++++++++++---------------- src/clang_complete.h | 7 +++-- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 48d5aacd..a6a8a0ff 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -313,9 +313,8 @@ void EnsureDocumentParsed(ClangCompleteManager* manager, if (manager->config_->diagnosticsOnParse && !(*tu)->did_fail) { // If we're emitting diagnostics, do an immedaite reparse, otherwise we will // emit stale/bad diagnostics. - clang_reparseTranslationUnit( - (*tu)->cx_tu, unsaved.size(), unsaved.data(), - clang_defaultReparseOptions((*tu)->cx_tu)); + clang_reparseTranslationUnit((*tu)->cx_tu, unsaved.size(), unsaved.data(), + clang_defaultReparseOptions((*tu)->cx_tu)); NonElidedVector ls_diagnostics; unsigned num_diagnostics = clang_getNumDiagnostics((*tu)->cx_tu); @@ -338,8 +337,8 @@ void CompletionParseMain(ClangCompleteManager* completion_manager) { // 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 /*create_if_needed*/); + completion_manager->TryGetEditSession(request.path, + false /*create_if_needed*/); if (!session) continue; @@ -371,7 +370,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { std::string path = request->document.uri.GetPath(); std::shared_ptr session = - completion_manager->TryGetSession(path, true /*create_if_needed*/); + completion_manager->TryGetEditSession(path, true /*create_if_needed*/); std::lock_guard lock(session->tu_lock); Timer timer; @@ -595,9 +594,11 @@ void ClangCompleteManager::NotifyView(const std::string& filename) { std::lock_guard lock(sessions_lock_); - // Already a view session, do nothing. - if (view_sessions_.TryGetEntry(filename)) + // Already a view or edit session, do nothing. + if (view_sessions_.TryGetEntry(filename) || + edit_sessions_.TryGetEntry(filename)) { return; + } // Create new view session. view_sessions_.InsertEntry(std::make_shared( @@ -638,6 +639,15 @@ void ClangCompleteManager::NotifySave(const std::string& filename) { std::lock_guard lock(sessions_lock_); + // If for whatever reason we have a view session and not an edit session, + // move the session from view to edit. + std::shared_ptr view_session = + view_sessions_.TryTakeEntry(filename); + if (view_session) { + edit_sessions_.InsertEntry(view_session); + } + + // If no edit session create one. if (!edit_sessions_.TryGetEntry(filename)) { edit_sessions_.InsertEntry(std::make_shared( project_->FindCompilationEntryForFile(filename), working_files_)); @@ -661,26 +671,33 @@ void ClangCompleteManager::NotifyClose(const std::string& filename) { auto edit_ptr = edit_sessions_.TryTakeEntry(filename); LOG_IF_S(INFO, !!edit_ptr) << "Dropped edit-based code completion session for " << filename; + + // We should never have both a view and edit session. + assert((view_ptr && edit_ptr) == false); } -std::shared_ptr ClangCompleteManager::TryGetSession( +std::shared_ptr ClangCompleteManager::TryGetEditSession( const std::string& filename, bool create_if_needed) { std::lock_guard lock(sessions_lock_); - std::shared_ptr session = - edit_sessions_.TryGetEntry(filename); - - if (!session) - session = view_sessions_.TryGetEntry(filename); - - if (!session && create_if_needed) { - // Create new session. Default to edited_sessions_ since invoking code - // completion almost certainly implies an edit. - edit_sessions_.InsertEntry(std::make_shared( - project_->FindCompilationEntryForFile(filename), working_files_)); - session = edit_sessions_.TryGetEntry(filename); + // Try to find a view session. If found move it to |edit_sessions_|. + std::shared_ptr view_session = + view_sessions_.TryTakeEntry(filename); + if (view_session) { + assert(!edit_sessions_.TryGetEntry(filename)); + edit_sessions_.InsertEntry(view_session); + return view_session; } - return session; + // Try to find an edit session. If none create if requested. + std::shared_ptr edit_session = + edit_sessions_.TryTakeEntry(filename); + if (!edit_session && create_if_needed) { + edit_session = std::make_shared( + project_->FindCompilationEntryForFile(filename), working_files_); + edit_sessions_.InsertEntry(edit_session); + } + + return edit_session; } diff --git a/src/clang_complete.h b/src/clang_complete.h index 17c26f9c..a6141c31 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -99,8 +99,11 @@ struct ClangCompleteManager { // completion session will be dropped. void NotifyClose(const std::string& filename); - std::shared_ptr TryGetSession(const std::string& filename, - bool create_if_needed); + // Tries to find an edit session for |filename|. This will move the session + // from view to edit. + std::shared_ptr TryGetEditSession( + const std::string& filename, + bool create_if_needed); // TODO: make these configurable. const int kMaxViewSessions = 10;