completion: if preamble size changes, rebuild it

Fix #190

If a new header is added, the preamble size changes. Language clients may cache completion results, thus we rebuild preamble to avoid inaccurate results.
This commit is contained in:
Fangrui Song 2019-01-13 18:33:18 +08:00
parent 5a72ddda38
commit 118c5cea6a
2 changed files with 18 additions and 9 deletions

View File

@ -412,7 +412,9 @@ void *PreambleMain(void *manager_) {
BuildCompilerInvocation(task.path, session->file.args, FS))
BuildPreamble(*session, *CI, FS, task, std::move(stat_cache));
if (task.from_diag) {
if (task.comp_task) {
manager->comp_tasks.PushBack(std::move(task.comp_task));
} else if (task.from_diag) {
manager->ScheduleDiag(task.path, 0);
} else {
int debounce =
@ -463,12 +465,18 @@ void *CompletionMain(void *manager_) {
DiagnosticConsumer DC;
std::string content = manager->wfiles->GetContent(task->path);
auto Buf = llvm::MemoryBuffer::getMemBuffer(content);
PreambleBounds Bounds =
ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0);
bool in_preamble =
GetOffsetForPosition({task->position.line, task->position.character},
content) <
ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0).Size;
if (in_preamble)
content) < (int)Bounds.Size;
if (in_preamble) {
preamble.reset();
} else if (preamble && Bounds.Size != preamble->Preamble.getBounds().Size) {
manager->preamble_tasks.PushBack({task->path, std::move(task), false},
true);
continue;
}
auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC,
preamble.get(), task->path, Buf);
if (!Clang)
@ -545,7 +553,7 @@ void *DiagnosticMain(void *manager_) {
}
}
if (rebuild) {
manager->preamble_tasks.PushBack({task.path, true}, true);
manager->preamble_tasks.PushBack({task.path, nullptr, true}, true);
continue;
}
}

View File

@ -102,10 +102,6 @@ struct SemaManager {
std::function<void(clang::CodeCompleteConsumer *OptConsumer)>;
using OnDropped = std::function<void(RequestId request_id)>;
struct PreambleTask {
std::string path;
bool from_diag = false;
};
struct CompTask {
CompTask(const RequestId &id, const std::string &path,
const Position &position,
@ -126,6 +122,11 @@ struct SemaManager {
int64_t wait_until;
int64_t debounce;
};
struct PreambleTask {
std::string path;
std::unique_ptr<CompTask> comp_task;
bool from_diag = false;
};
SemaManager(Project *project, WorkingFiles *wfiles,
OnDiagnostic on_diagnostic, OnDropped on_dropped);