Some renames, promote view completion sessions to edit sessions

This commit is contained in:
Jacob Dufault 2017-05-26 21:21:00 -07:00
parent 7840b7a015
commit d816e2618a
5 changed files with 71 additions and 55 deletions

View File

@ -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<CompletionSession> TryTakeEntry(const std::string& fiilename);
// Inserts an entry. Evicts the oldest unused entry if there is no space.
void InsertEntry(std::unique_ptr<CompletionSession> session);
};
struct CompletionManager {
struct ClangCompleteManager {
using OnComplete = std::function<void(NonElidedVector<lsCompletionItem> results, NonElidedVector<lsDiagnostic> 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.

View File

@ -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<CompletionManager::CompletionRequest> request = completion_manager->completion_request_.Take();
std::unique_ptr<ClangCompleteManager::CompletionRequest> 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<CompletionSession> LruSessionCache::TryTakeEntry(const std::string& filename) {
for (int i = 0; i < entries_.size(); ++i) {
if (entries_[i]->file.filename == filename) {
std::unique_ptr<CompletionSession> result = std::move(entries_[i]);
entries_.erase(entries_.begin() + i);
return result;
}
}
return nullptr;
}
void LruSessionCache::InsertEntry(std::unique_ptr<CompletionSession> 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<CompletionRequest>();
@ -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<CompletionSession> 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<CompletionSession>(
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<std::mutex> lock(sessions_lock_);
CompletionSession* session = edit_sessions_.TryGetEntry(filename);

View File

@ -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<Ipc_TextDocumentDidChange*>(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<Ipc_TextDocumentComplete*>(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<std::mutex> lock(include_completion->completion_items_mutex, std::defer_lock);
if (include_completion->is_scanning)
std::unique_lock<std::mutex> 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<lsCompletionItem> results, NonElidedVector<lsDiagnostic> diagnostics) {
ClangCompleteManager::OnComplete callback = std::bind([working_files, global_code_complete_cache, non_global_code_complete_cache, is_global_completion](BaseIpcMessage* message, NonElidedVector<lsCompletionItem> results, NonElidedVector<lsDiagnostic> diagnostics) {
auto msg = static_cast<Ipc_TextDocumentComplete*>(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<lsCompletionItem> results, NonElidedVector<lsDiagnostic> diagnostics) {
ClangCompleteManager::OnComplete freshen_global = [global_code_complete_cache](NonElidedVector<lsCompletionItem> results, NonElidedVector<lsDiagnostic> 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<lsCompletionItem>& results) {
ClangCompleteManager::OnComplete callback = std::bind([signature_cache](BaseIpcMessage* message, std::string search, int active_param, const NonElidedVector<lsCompletionItem>& results) {
auto msg = static_cast<Ipc_TextDocumentSignatureHelp*>(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({

View File

@ -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<std::mutex> 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*/));

View File

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