From d816e2618ad3c59c5e6754010c378dde355ff47f Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Fri, 26 May 2017 21:21:00 -0700 Subject: [PATCH] Some renames, promote view completion sessions to edit sessions --- src/{code_completion.h => clang_complete.h} | 6 +- ...{code_completion.cc => clange_complete.cc} | 39 +++++++---- src/command_line.cc | 65 +++++++++---------- ...lude_completion.cc => include_complete.cc} | 12 ++-- ...nclude_completion.h => include_complete.h} | 4 +- 5 files changed, 71 insertions(+), 55 deletions(-) rename src/{code_completion.h => clang_complete.h} (92%) rename src/{code_completion.cc => clange_complete.cc} (91%) rename src/{include_completion.cc => include_complete.cc} (94%) rename src/{include_completion.h => include_complete.h} (93%) diff --git a/src/code_completion.h b/src/clang_complete.h similarity index 92% rename from src/code_completion.h rename to src/clang_complete.h index e25f7ff3..5a53cca1 100644 --- a/src/code_completion.h +++ b/src/clang_complete.h @@ -42,11 +42,13 @@ struct LruSessionCache { // Fetches the entry for |filename| and updates it's usage so it is less // likely to be evicted. CompletionSession* TryGetEntry(const std::string& filename); + // TryGetEntry, except the return value captures ownership. + std::unique_ptr TryTakeEntry(const std::string& fiilename); // Inserts an entry. Evicts the oldest unused entry if there is no space. void InsertEntry(std::unique_ptr session); }; -struct CompletionManager { +struct ClangCompleteManager { using OnComplete = std::function results, NonElidedVector diagnostics)>; struct ParseRequest { @@ -60,7 +62,7 @@ struct CompletionManager { OnComplete on_complete; }; - CompletionManager(Config* config, Project* project, WorkingFiles* working_files); + ClangCompleteManager(Config* config, Project* project, WorkingFiles* working_files); // Start a code completion at the given location. |on_complete| will run when // completion results are available. |on_complete| may run on any thread. diff --git a/src/code_completion.cc b/src/clange_complete.cc similarity index 91% rename from src/code_completion.cc rename to src/clange_complete.cc index 87398d31..87d93a77 100644 --- a/src/code_completion.cc +++ b/src/clange_complete.cc @@ -1,4 +1,4 @@ -#include "code_completion.h" +#include "clang_complete.h" #include "clang_utils.h" #include "libclangmm/Utility.h" @@ -253,10 +253,10 @@ void EnsureDocumentParsed(CompletionSession* session, std::cerr << "[complete] Done creating active; did_fail=" << (*tu)->did_fail << std::endl; } -void CompletionParseMain(CompletionManager* completion_manager) { +void CompletionParseMain(ClangCompleteManager* completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. - CompletionManager::ParseRequest request = completion_manager->parse_requests_.Dequeue(); + ClangCompleteManager::ParseRequest request = completion_manager->parse_requests_.Dequeue(); // If we don't get a session then that means we don't care about the file // anymore - abandon the request. @@ -282,10 +282,10 @@ void CompletionParseMain(CompletionManager* completion_manager) { } } -void CompletionQueryMain(CompletionManager* completion_manager) { +void CompletionQueryMain(ClangCompleteManager* completion_manager) { while (true) { // Fetching the completion request blocks until we have a request. - std::unique_ptr request = completion_manager->completion_request_.Take(); + std::unique_ptr request = completion_manager->completion_request_.Take(); std::string path = request->location.textDocument.uri.GetPath(); CompletionSession* session = completion_manager->TryGetSession(path, true /*create_if_needed*/); @@ -392,16 +392,27 @@ CompletionSession* LruSessionCache::TryGetEntry(const std::string& filename) { return nullptr; } +std::unique_ptr LruSessionCache::TryTakeEntry(const std::string& filename) { + for (int i = 0; i < entries_.size(); ++i) { + if (entries_[i]->file.filename == filename) { + std::unique_ptr result = std::move(entries_[i]); + entries_.erase(entries_.begin() + i); + return result; + } + } + return nullptr; +} + void LruSessionCache::InsertEntry(std::unique_ptr session) { if (entries_.size() >= max_entries_) entries_.pop_back(); entries_.insert(entries_.begin(), std::move(session)); } -CompletionManager::ParseRequest::ParseRequest(const std::string& path) +ClangCompleteManager::ParseRequest::ParseRequest(const std::string& path) : path(path), request_time(std::chrono::high_resolution_clock::now()) {} -CompletionManager::CompletionManager(Config* config, Project* project, WorkingFiles* working_files) +ClangCompleteManager::ClangCompleteManager(Config* config, Project* project, WorkingFiles* working_files) : config_(config), project_(project), working_files_(working_files), view_sessions_(kMaxViewSessions), edit_sessions_(kMaxEditSessions) { new std::thread([&]() { @@ -415,7 +426,7 @@ CompletionManager::CompletionManager(Config* config, Project* project, WorkingFi }); } -void CompletionManager::CodeComplete(const lsTextDocumentPositionParams& completion_location, const OnComplete& on_complete) { +void ClangCompleteManager::CodeComplete(const lsTextDocumentPositionParams& completion_location, const OnComplete& on_complete) { // completion thread will create the CompletionSession if needed. auto request = MakeUnique(); @@ -424,7 +435,7 @@ void CompletionManager::CodeComplete(const lsTextDocumentPositionParams& complet completion_request_.Set(std::move(request)); } -void CompletionManager::NotifyView(const std::string& filename) { +void ClangCompleteManager::NotifyView(const std::string& filename) { // // On view, we reparse only if the file has not been parsed. The existence of // a CompletionSession instance implies the file is already parsed or will be @@ -442,7 +453,7 @@ void CompletionManager::NotifyView(const std::string& filename) { parse_requests_.Enqueue(ParseRequest(filename)); } -void CompletionManager::NotifyEdit(const std::string& filename) { +void ClangCompleteManager::NotifyEdit(const std::string& filename) { // // On edit, we reparse only if the file has not been parsed. The existence of // a CompletionSession instance implies the file is already parsed or will be @@ -454,13 +465,17 @@ void CompletionManager::NotifyEdit(const std::string& filename) { if (edit_sessions_.TryGetEntry(filename)) return; + if (std::unique_ptr session = view_sessions_.TryTakeEntry(filename)) { + edit_sessions_.InsertEntry(std::move(session)); + } + std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl; edit_sessions_.InsertEntry(MakeUnique( project_->FindCompilationEntryForFile(filename), working_files_)); parse_requests_.PriorityEnqueue(ParseRequest(filename)); } -void CompletionManager::NotifySave(const std::string& filename) { +void ClangCompleteManager::NotifySave(const std::string& filename) { // // On save, always reparse. // @@ -476,7 +491,7 @@ void CompletionManager::NotifySave(const std::string& filename) { parse_requests_.PriorityEnqueue(ParseRequest(filename)); } -CompletionSession* CompletionManager::TryGetSession(const std::string& filename, bool create_if_needed) { +CompletionSession* ClangCompleteManager::TryGetSession(const std::string& filename, bool create_if_needed) { std::lock_guard lock(sessions_lock_); CompletionSession* session = edit_sessions_.TryGetEntry(filename); diff --git a/src/command_line.cc b/src/command_line.cc index fba9002b..399bbc99 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -1,9 +1,9 @@ // TODO: cleanup includes #include "cache.h" -#include "code_completion.h" +#include "clang_complete.h" #include "file_consumer.h" #include "match.h" -#include "include_completion.h" +#include "include_complete.h" #include "ipc_manager.h" #include "indexer.h" #include "query.h" @@ -1525,8 +1525,8 @@ bool QueryDbMainLoop( Project* project, FileConsumer::SharedState* file_consumer_shared, WorkingFiles* working_files, - CompletionManager* completion_manager, - IncludeCompletion* include_completion, + ClangCompleteManager* clang_complete, + IncludeComplete* include_complete, CodeCompleteCache* global_code_complete_cache, CodeCompleteCache* non_global_code_complete_cache, CodeCompleteCache* signature_cache) { @@ -1606,7 +1606,7 @@ bool QueryDbMainLoop( time.ResetAndPrint("[perf] Loaded compilation entries (" + std::to_string(project->entries.size()) + " files)"); // Start scanning include directories before dispatching project files, because that takes a long time. - include_completion->Rescan(); + include_complete->Rescan(); time.Reset(); project->ForAllFilteredFiles(config, [&](int i, const Project::Entry& entry) { @@ -1884,8 +1884,8 @@ bool QueryDbMainLoop( time.ResetAndPrint("[querydb] Loading cached index file for DidOpen (blocks CodeLens)"); - include_completion->AddFile(working_file->filename); - completion_manager->NotifyView(path); + include_complete->AddFile(working_file->filename); + clang_complete->NotifyView(path); break; } @@ -1894,7 +1894,7 @@ bool QueryDbMainLoop( auto msg = static_cast(message.get()); std::string path = msg->params.textDocument.uri.GetPath(); working_files->OnChange(msg->params); - completion_manager->NotifyEdit(path); + clang_complete->NotifyEdit(path); break; } @@ -1933,7 +1933,7 @@ bool QueryDbMainLoop( queue_do_index->PriorityEnqueue(Index_DoIndex(index_type, project->FindCompilationEntryForFile(path), working_file->buffer_content, true /*is_interactive*/)); } - completion_manager->NotifySave(path); + clang_complete->NotifySave(path); break; } @@ -1966,14 +1966,13 @@ bool QueryDbMainLoop( case IpcId::TextDocumentCompletion: { auto msg = static_cast(message.get()); - lsTextDocumentPositionParams& params = msg->params; - std::string path = params.textDocument.uri.GetPath(); + std::string path = msg->params.textDocument.uri.GetPath(); WorkingFile* file = working_files->GetFileByFilename(path); // TODO: We should scan include directories to add any missing paths - std::string buffer_line = file->all_buffer_lines[params.position.line]; + std::string buffer_line = file->all_buffer_lines[msg->params.position.line]; if (ShouldRunIncludeCompletion(buffer_line)) { Out_TextDocumentComplete complete_response; @@ -1981,20 +1980,20 @@ bool QueryDbMainLoop( complete_response.result.isIncomplete = false; { - std::unique_lock lock(include_completion->completion_items_mutex, std::defer_lock); - if (include_completion->is_scanning) + std::unique_lock lock(include_complete->completion_items_mutex, std::defer_lock); + if (include_complete->is_scanning) lock.lock(); complete_response.result.items.assign( - include_completion->completion_items.begin(), - include_completion->completion_items.end()); + include_complete->completion_items.begin(), + include_complete->completion_items.end()); if (lock) lock.unlock(); // Update textEdit params. for (lsCompletionItem& item : complete_response.result.items) { - item.textEdit->range.start.line = params.position.line; + item.textEdit->range.start.line = msg->params.position.line; item.textEdit->range.start.character = 0; - item.textEdit->range.end.line = params.position.line; + item.textEdit->range.end.line = msg->params.position.line; item.textEdit->range.end.character = (int)buffer_line.size(); } } @@ -2005,9 +2004,9 @@ bool QueryDbMainLoop( else { bool is_global_completion = false; if (file) - params.position = file->FindStableCompletionSource(params.position, &is_global_completion); + msg->params.position = file->FindStableCompletionSource(msg->params.position, &is_global_completion); - CompletionManager::OnComplete callback = std::bind([working_files, global_code_complete_cache, non_global_code_complete_cache, is_global_completion](BaseIpcMessage* message, NonElidedVector results, NonElidedVector diagnostics) { + ClangCompleteManager::OnComplete callback = std::bind([working_files, global_code_complete_cache, non_global_code_complete_cache, is_global_completion](BaseIpcMessage* message, NonElidedVector results, NonElidedVector diagnostics) { auto msg = static_cast(message); auto ipc = IpcManager::instance(); @@ -2049,25 +2048,25 @@ bool QueryDbMainLoop( }, message.release(), std::placeholders::_1, std::placeholders::_2); if (is_global_completion && global_code_complete_cache->cached_path == path && !global_code_complete_cache->cached_results.empty()) { - std::cerr << "[complete] Early-returning cached global completion results at " << params.position.ToString() << std::endl; + std::cerr << "[complete] Early-returning cached global completion results at " << msg->params.position.ToString() << std::endl; - CompletionManager::OnComplete update_global = std::bind([global_code_complete_cache](NonElidedVector results, NonElidedVector diagnostics) { + ClangCompleteManager::OnComplete freshen_global = [global_code_complete_cache](NonElidedVector results, NonElidedVector diagnostics) { std::cerr << "[complete] Updated global completion cache" << std::endl; // note: path is updated in the normal completion handler. global_code_complete_cache->cached_results = results; global_code_complete_cache->cached_diagnostics = diagnostics; - }, std::placeholders::_1, std::placeholders::_2); - completion_manager->CodeComplete(params, std::move(update_global)); + }; + clang_complete->CodeComplete(msg->params, std::move(freshen_global)); // Note: callback will delete the message (ie, |params|) so we need to run completion_manager->CodeComplete before |callback|. callback(global_code_complete_cache->cached_results, global_code_complete_cache->cached_diagnostics); } - else if (non_global_code_complete_cache->IsCacheValid(params)) { - std::cerr << "[complete] Using cached completion results at " << params.position.ToString() << std::endl; + else if (non_global_code_complete_cache->IsCacheValid(msg->params)) { + std::cerr << "[complete] Using cached completion results at " << msg->params.position.ToString() << std::endl; callback(non_global_code_complete_cache->cached_results, non_global_code_complete_cache->cached_diagnostics); } else { - completion_manager->CodeComplete(params, std::move(callback)); + clang_complete->CodeComplete(msg->params, std::move(callback)); } } @@ -2089,7 +2088,7 @@ bool QueryDbMainLoop( if (search.empty()) break; - CompletionManager::OnComplete callback = std::bind([signature_cache](BaseIpcMessage* message, std::string search, int active_param, const NonElidedVector& results) { + ClangCompleteManager::OnComplete callback = std::bind([signature_cache](BaseIpcMessage* message, std::string search, int active_param, const NonElidedVector& results) { auto msg = static_cast(message); auto ipc = IpcManager::instance(); @@ -2142,7 +2141,7 @@ bool QueryDbMainLoop( callback(signature_cache->cached_results, signature_cache->cached_diagnostics); } else { - completion_manager->CodeComplete(params, std::move(callback)); + clang_complete->CodeComplete(params, std::move(callback)); } break; @@ -2449,7 +2448,7 @@ bool QueryDbMainLoop( lsDocumentUri file_as_uri = msg->params.textDocument.uri; std::string path = file_as_uri.GetPath(); - completion_manager->NotifyView(path); + clang_complete->NotifyView(path); QueryFile* file = FindFile(db, path); if (!file) { @@ -2669,8 +2668,8 @@ void QueryDbMain(Config* config, MultiQueueWaiter* waiter) { Project project; WorkingFiles working_files; - CompletionManager completion_manager(config, &project, &working_files); - IncludeCompletion include_completion(config, &project); + ClangCompleteManager clang_complete(config, &project, &working_files); + IncludeComplete include_complete(config, &project); CodeCompleteCache global_code_complete_cache; CodeCompleteCache non_global_code_complete_cache; CodeCompleteCache signature_cache; @@ -2683,7 +2682,7 @@ void QueryDbMain(Config* config, MultiQueueWaiter* waiter) { bool did_work = QueryDbMainLoop( config, &db, waiter, &queue_do_index, &queue_do_id_map, &queue_on_id_mapped, &queue_on_indexed, &project, &file_consumer_shared, &working_files, - &completion_manager, &include_completion, &global_code_complete_cache, &non_global_code_complete_cache, &signature_cache); + &clang_complete, &include_complete, &global_code_complete_cache, &non_global_code_complete_cache, &signature_cache); if (!did_work) { IpcManager* ipc = IpcManager::instance(); waiter->Wait({ diff --git a/src/include_completion.cc b/src/include_complete.cc similarity index 94% rename from src/include_completion.cc rename to src/include_complete.cc index 8360acd6..4f9117a5 100644 --- a/src/include_completion.cc +++ b/src/include_complete.cc @@ -1,4 +1,4 @@ -#include "include_completion.h" +#include "include_complete.h" #include "match.h" #include "platform.h" @@ -100,10 +100,10 @@ lsCompletionItem BuildCompletionItem(Config* config, const std::string& path, bo } // namespace -IncludeCompletion::IncludeCompletion(Config* config, Project* project) +IncludeComplete::IncludeComplete(Config* config, Project* project) : is_scanning(false), config_(config), project_(project) {} -void IncludeCompletion::Rescan() { +void IncludeComplete::Rescan() { if (is_scanning) return; @@ -130,7 +130,7 @@ void IncludeCompletion::Rescan() { }); } -void IncludeCompletion::AddFile(const std::string& absolute_path) { +void IncludeComplete::AddFile(const std::string& absolute_path) { if (!EndsWithAny(absolute_path, config_->includeCompletionWhitelistLiteralEnding)) return; if (match_ && !match_->IsMatch(absolute_path)) @@ -151,7 +151,7 @@ void IncludeCompletion::AddFile(const std::string& absolute_path) { } } -void IncludeCompletion::InsertIncludesFromDirectory( +void IncludeComplete::InsertIncludesFromDirectory( std::string directory, bool use_angle_brackets) { directory = NormalizePath(directory); @@ -177,7 +177,7 @@ void IncludeCompletion::InsertIncludesFromDirectory( } } -void IncludeCompletion::InsertStlIncludes() { +void IncludeComplete::InsertStlIncludes() { std::lock_guard lock(completion_items_mutex); for (const char* stl_header : kStandardLibraryIncludes) { completion_items.push_back(BuildCompletionItem(config_, stl_header, true /*use_angle_brackets*/, true /*is_stl*/)); diff --git a/src/include_completion.h b/src/include_complete.h similarity index 93% rename from src/include_completion.h rename to src/include_complete.h index 28796c78..e7ad6d7e 100644 --- a/src/include_completion.h +++ b/src/include_complete.h @@ -9,8 +9,8 @@ struct GroupMatch; struct Project; -struct IncludeCompletion { - IncludeCompletion(Config* config, Project* project); +struct IncludeComplete { + IncludeComplete(Config* config, Project* project); // Starts scanning directories. Clears existing cache. void Rescan();