Completion changes (maybe fix some crashes)

This commit is contained in:
Jacob Dufault 2017-06-28 19:50:30 -07:00
parent 0876886c60
commit 706479aded
3 changed files with 92 additions and 45 deletions

View File

@ -8,7 +8,41 @@
#include <algorithm> #include <algorithm>
#include <thread> #include <thread>
/*
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
*/
namespace { namespace {
constexpr int kBacktraceBufferSize = 300;
#if false
void EmitBacktrace() {
void* buffer[kBacktraceBufferSize];
int nptrs = backtrace(buffer, kBacktraceBufferSize);
fprintf(stderr, "backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
char** strings = backtrace_symbols(buffer, nptrs);
if (!strings) {
perror("Failed to emit backtrace");
exit(EXIT_FAILURE);
}
for (int j = 0; j < nptrs; j++)
fprintf(stderr, "%s\n", strings[j]);
free(strings);
}
#endif
unsigned Flags() { unsigned Flags() {
// TODO: use clang_defaultEditingTranslationUnitOptions()? // TODO: use clang_defaultEditingTranslationUnitOptions()?
return return
@ -333,6 +367,7 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
timer.ResetAndPrint("[complete] clangCodeCompleteAt"); timer.ResetAndPrint("[complete] clangCodeCompleteAt");
std::cerr << "[complete] Got " << cx_results->NumResults << " results" << std::endl; std::cerr << "[complete] Got " << cx_results->NumResults << " results" << std::endl;
{
NonElidedVector<lsCompletionItem> ls_result; NonElidedVector<lsCompletionItem> ls_result;
ls_result.reserve(cx_results->NumResults); ls_result.reserve(cx_results->NumResults);
@ -368,11 +403,14 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
} }
timer.ResetAndPrint("[complete] Building " + std::to_string(ls_result.size()) + " completion results"); timer.ResetAndPrint("[complete] Building " + std::to_string(ls_result.size()) + " completion results");
request->on_complete(ls_result);
timer.ResetAndPrint("[complete] Running user-given completion func");
}
// Make sure |ls_results| is destroyed before clearing |cx_results|.
clang_disposeCodeCompleteResults(cx_results); clang_disposeCodeCompleteResults(cx_results);
timer.ResetAndPrint("[complete] clang_disposeCodeCompleteResults"); timer.ResetAndPrint("[complete] clang_disposeCodeCompleteResults");
request->on_complete(ls_result);
continue; continue;
} }
} }
@ -386,6 +424,7 @@ CompletionSession::CompletionSession(const Project::Entry& file, WorkingFiles* w
CompletionSession::~CompletionSession() { CompletionSession::~CompletionSession() {
std::cerr << "[complete] CompletionSession::~CompletionSession() for " << file.filename << std::endl; std::cerr << "[complete] CompletionSession::~CompletionSession() for " << file.filename << std::endl;
// EmitBacktrace();
} }
LruSessionCache::LruSessionCache(int max_entries) : max_entries_(max_entries) {} LruSessionCache::LruSessionCache(int max_entries) : max_entries_(max_entries) {}
@ -401,7 +440,7 @@ std::shared_ptr<CompletionSession> LruSessionCache::TryGetEntry(const std::strin
std::shared_ptr<CompletionSession> LruSessionCache::TryTakeEntry(const std::string& filename) { std::shared_ptr<CompletionSession> LruSessionCache::TryTakeEntry(const std::string& filename) {
for (int i = 0; i < entries_.size(); ++i) { for (int i = 0; i < entries_.size(); ++i) {
if (entries_[i]->file.filename == filename) { if (entries_[i]->file.filename == filename) {
std::shared_ptr<CompletionSession> result = std::move(entries_[i]); std::shared_ptr<CompletionSession> result = entries_[i];
entries_.erase(entries_.begin() + i); entries_.erase(entries_.begin() + i);
return result; return result;
} }
@ -410,9 +449,9 @@ std::shared_ptr<CompletionSession> LruSessionCache::TryTakeEntry(const std::stri
} }
void LruSessionCache::InsertEntry(std::shared_ptr<CompletionSession> session) { void LruSessionCache::InsertEntry(std::shared_ptr<CompletionSession> session) {
if (entries_.size() >= max_entries_) if (entries_.size() && entries_.size() >= max_entries_)
entries_.pop_back(); entries_.pop_back();
entries_.insert(entries_.begin(), std::move(session)); entries_.insert(entries_.begin(), session);
} }
ClangCompleteManager::ParseRequest::ParseRequest(const std::string& path) ClangCompleteManager::ParseRequest::ParseRequest(const std::string& path)
@ -432,6 +471,8 @@ ClangCompleteManager::ClangCompleteManager(Config* config, Project* project, Wor
}); });
} }
ClangCompleteManager::~ClangCompleteManager() {}
void ClangCompleteManager::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. // completion thread will create the CompletionSession if needed.
@ -454,7 +495,7 @@ void ClangCompleteManager::NotifyView(const std::string& filename) {
return; return;
std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl; std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl;
view_sessions_.InsertEntry(MakeUnique<CompletionSession>( view_sessions_.InsertEntry(std::make_shared<CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_)); project_->FindCompilationEntryForFile(filename), working_files_));
parse_requests_.Enqueue(ParseRequest(filename)); parse_requests_.Enqueue(ParseRequest(filename));
} }
@ -471,14 +512,16 @@ void ClangCompleteManager::NotifyEdit(const std::string& filename) {
if (edit_sessions_.TryGetEntry(filename)) if (edit_sessions_.TryGetEntry(filename))
return; return;
if (std::shared_ptr<CompletionSession> session = view_sessions_.TryTakeEntry(filename)) { std::shared_ptr<CompletionSession> session = view_sessions_.TryTakeEntry(filename);
edit_sessions_.InsertEntry(std::move(session)); if (session) {
edit_sessions_.InsertEntry(session);
} }
else {
std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl; std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl;
edit_sessions_.InsertEntry(MakeUnique<CompletionSession>( edit_sessions_.InsertEntry(std::make_shared<CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_)); project_->FindCompilationEntryForFile(filename), working_files_));
parse_requests_.PriorityEnqueue(ParseRequest(filename)); parse_requests_.PriorityEnqueue(ParseRequest(filename));
}
} }
void ClangCompleteManager::NotifySave(const std::string& filename) { void ClangCompleteManager::NotifySave(const std::string& filename) {
@ -490,7 +533,7 @@ void ClangCompleteManager::NotifySave(const std::string& filename) {
if (!edit_sessions_.TryGetEntry(filename)) { if (!edit_sessions_.TryGetEntry(filename)) {
std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl; std::cerr << "[complete] Creating new edit code completion session for " << filename << std::endl;
edit_sessions_.InsertEntry(MakeUnique<CompletionSession>( edit_sessions_.InsertEntry(std::make_shared<CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_)); project_->FindCompilationEntryForFile(filename), working_files_));
} }
@ -508,7 +551,7 @@ std::shared_ptr<CompletionSession> ClangCompleteManager::TryGetSession(const std
if (!session && create_if_needed) { if (!session && create_if_needed) {
// Create new session. Default to edited_sessions_ since invoking code // Create new session. Default to edited_sessions_ since invoking code
// completion almost certainly implies an edit. // completion almost certainly implies an edit.
edit_sessions_.InsertEntry(MakeUnique<CompletionSession>( edit_sessions_.InsertEntry(std::make_shared<CompletionSession>(
project_->FindCompilationEntryForFile(filename), working_files_)); project_->FindCompilationEntryForFile(filename), working_files_));
session = edit_sessions_.TryGetEntry(filename); session = edit_sessions_.TryGetEntry(filename);
} }

View File

@ -62,6 +62,7 @@ struct ClangCompleteManager {
}; };
ClangCompleteManager(Config* config, Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic); ClangCompleteManager(Config* config, Project* project, WorkingFiles* working_files, OnDiagnostic on_diagnostic);
~ClangCompleteManager();
// Start a code completion at the given location. |on_complete| will run when // Start a code completion at the given location. |on_complete| will run when
// completion results are available. |on_complete| may run on any thread. // completion results are available. |on_complete| may run on any thread.

View File

@ -1672,10 +1672,13 @@ bool QueryDbMainLoop(
// note: path is updated in the normal completion handler. // note: path is updated in the normal completion handler.
global_code_complete_cache->cached_results = results; global_code_complete_cache->cached_results = results;
}; };
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|. // Note: |callback| will delete the message (ie, |params|) so we
// need to run completion_manager->CodeComplete before |callback|.
lsTextDocumentPositionParams params = msg->params;
callback(global_code_complete_cache->cached_results); callback(global_code_complete_cache->cached_results);
clang_complete->CodeComplete(params, std::move(freshen_global));
} }
else if (non_global_code_complete_cache->IsCacheValid(msg->params)) { else if (non_global_code_complete_cache->IsCacheValid(msg->params)) {
std::cerr << "[complete] Using cached completion results at " << msg->params.position.ToString() << std::endl; std::cerr << "[complete] Using cached completion results at " << msg->params.position.ToString() << std::endl;