Add ReplyOnce::NotReady and error if didOpen is not seen

Use IgnoringDiagConsumer to override default TextDiagnosticPrinter
This commit is contained in:
Fangrui Song 2018-12-01 16:55:51 -08:00
parent ab48663ca0
commit 872d7c5de9
19 changed files with 95 additions and 75 deletions

View File

@ -98,7 +98,8 @@ BuildCompilerInvocation(std::vector<const char *> args,
std::string save = "-resource-dir=" + g_config->clang.resourceDir;
args.push_back(save.c_str());
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(new DiagnosticOptions));
CompilerInstance::createDiagnostics(new DiagnosticOptions,
new IgnoringDiagConsumer, true));
std::unique_ptr<CompilerInvocation> CI =
createInvocationFromCommandLine(args, Diags, VFS);
if (CI) {

View File

@ -107,6 +107,13 @@ struct ScanLineEvent {
};
} // namespace
void ReplyOnce::NotReady(bool file) {
if (file)
Error(ErrorCode::InvalidRequest, "not opened");
else
Error(ErrorCode::InternalError, "not indexed");
}
void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Reader &)) {
method2notification[method] = [this, handler](Reader &reader) {
(this->*handler)(reader);
@ -220,14 +227,14 @@ void MessageHandler::Run(InMessage &msg) {
try {
it->second(reader);
} catch (...) {
LOG_S(ERROR) << "failed to process " << msg.method;
ShowMessageParam param{MessageType::Error,
std::string("failed to process ") + msg.method};
pipeline::Notify(window_showMessage, param);
}
}
}
QueryFile *MessageHandler::FindFile(ReplyOnce &reply,
const std::string &path,
int *out_file_id) {
QueryFile *MessageHandler::FindFile(const std::string &path, int *out_file_id) {
QueryFile *ret = nullptr;
auto it = db->name2file_id.find(LowerPathIfInsensitive(path));
if (it != db->name2file_id.end()) {
@ -239,24 +246,8 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply,
return ret;
}
}
if (out_file_id)
*out_file_id = -1;
if (reply.id.Valid()) {
bool has_entry = false;
{
std::lock_guard<std::mutex> lock(project->mutex_);
for (auto &[root, folder] : project->root2folder)
has_entry |= folder.path2entry_index.count(path);
}
ResponseError err;
if (has_entry)
reply.Error(ErrorCode::ServerNotInitialized, path + " is being indexed");
else
reply.Error(ErrorCode::InternalError, "unable to find " + path);
}
return ret;
}

View File

@ -202,6 +202,7 @@ struct ReplyOnce {
if (id.Valid())
pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); });
}
void NotReady(bool file);
};
struct MessageHandler {
@ -217,8 +218,7 @@ struct MessageHandler {
MessageHandler();
void Run(InMessage &msg);
QueryFile *FindFile(ReplyOnce &reply, const std::string &path,
int *out_file_id = nullptr);
QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr);
private:
void Bind(const char *method, void (MessageHandler::*handler)(Reader &));

View File

@ -200,7 +200,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) {
Expand(this, &*result, param.callee, param.callType, param.qualified,
param.levels);
} else {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
return;

View File

@ -54,7 +54,7 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
}
void MessageHandler::ccls_fileInfo(TextDocumentParam &param, ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
if (!file)
return;

View File

@ -146,7 +146,7 @@ void Inheritance(MessageHandler *m, Param &param, ReplyOnce &reply) {
Expand(m, &*result, param.derived, param.qualified, param.levels)))
result.reset();
} else {
QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = m->FindFile(param.textDocument.uri.GetPath());
if (!file)
return;
WorkingFile *wf = m->wfiles->GetFile(file->def->path);

View File

@ -281,10 +281,12 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) {
param.levels, param.kind)))
result.reset();
} else {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {
switch (sym.kind) {
case Kind::Func:

View File

@ -42,10 +42,12 @@ void MessageHandler::ccls_navigate(Reader &reader,
ReplyOnce &reply) {
Param param;
Reflect(reader, param);
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
Position ls_pos = param.position;
if (wf->index_lines.size())
if (auto line =

View File

@ -31,10 +31,12 @@ MAKE_REFLECT_STRUCT(Param, textDocument, position, kind);
void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) {
Param param;
Reflect(reader, param);
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
std::vector<Location> result;
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {

View File

@ -34,8 +34,10 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit);
void MessageHandler::textDocument_codeAction(CodeActionParam &param,
ReplyOnce &reply) {
WorkingFile *wf = wfiles->GetFile(param.textDocument.uri.GetPath());
if (!wf)
if (!wf) {
reply.NotReady(true);
return;
}
std::vector<CodeAction> result;
std::vector<Diagnostic> diagnostics;
wfiles->WithLock([&]() { diagnostics = wf->diagnostics; });
@ -92,15 +94,14 @@ struct CommonCodeLensParams {
void MessageHandler::textDocument_codeLens(TextDocumentParam &param,
ReplyOnce &reply) {
std::vector<CodeLens> result;
std::string path = param.textDocument.uri.GetPath();
QueryFile *file = FindFile(reply, path);
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf) {
reply.NotReady(file);
return;
}
std::vector<CodeLens> result;
auto Add = [&](const char *singular, Cmd_xref show, Range range, int num,
bool force_display = false) {
if (!num && !force_display)

View File

@ -449,13 +449,15 @@ public:
void MessageHandler::textDocument_completion(CompletionParam &param,
ReplyOnce &reply) {
static CompleteConsumerCache<std::vector<CompletionItem>> cache;
CompletionList result;
std::string path = param.textDocument.uri.GetPath();
WorkingFile *file = wfiles->GetFile(path);
if (!file) {
reply.NotReady(true);
return;
}
CompletionList result;
// It shouldn't be possible, but sometimes vscode will send queries out
// of order, ie, we get completion request before buffer content update.
std::string buffer_line;

View File

@ -48,10 +48,12 @@ std::vector<DeclRef> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
ReplyOnce &reply) {
int file_id;
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id);
QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id);
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
std::vector<Location> result;
Maybe<Use> on_def;
@ -169,10 +171,12 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
void MessageHandler::textDocument_typeDefinition(
TextDocumentPositionParam &param, ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
if (!file)
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!file) {
reply.NotReady(file);
return;
WorkingFile *working_file = wfiles->GetFile(file->def->path);
}
std::vector<Location> result;
auto Add = [&](const QueryType &type) {
@ -186,8 +190,7 @@ void MessageHandler::textDocument_typeDefinition(
if (auto ls_loc = GetLsLocation(db, wfiles, dr))
result.push_back(*ls_loc);
};
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, param.position)) {
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {
switch (sym.kind) {
case Kind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();

View File

@ -44,8 +44,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam &param) {
pipeline::LoadIndexedContent(path))
wf->SetIndexContent(*cached_file_contents);
ReplyOnce reply;
QueryFile *file = FindFile(reply, path);
QueryFile *file = FindFile(path);
if (file) {
EmitSkippedRanges(wf, *file);
EmitSemanticHighlight(db, wf, *file);

View File

@ -44,10 +44,12 @@ MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role);
void MessageHandler::textDocument_documentHighlight(
TextDocumentPositionParam &param, ReplyOnce &reply) {
int file_id;
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id);
QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id);
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
std::vector<DocumentHighlight> result;
std::vector<SymbolRef> syms =
@ -88,10 +90,10 @@ MAKE_REFLECT_STRUCT(DocumentLink, range, target);
void MessageHandler::textDocument_documentLink(TextDocumentParam &param,
ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf) {
reply.Error(ErrorCode::InternalError, "not opened");
reply.NotReady(file);
return;
}
@ -163,10 +165,12 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
Reflect(reader, param);
int file_id;
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath(), &file_id);
QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id);
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
if (param.startLine >= 0) {
std::vector<lsRange> result;

View File

@ -31,19 +31,19 @@ MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine,
void MessageHandler::textDocument_foldingRange(TextDocumentParam &param,
ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
if (!file)
return;
WorkingFile *wfile = wfiles->GetFile(file->def->path);
if (!wfile)
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf) {
reply.NotReady(file);
return;
}
std::vector<FoldingRange> result;
std::optional<lsRange> ls_range;
for (auto [sym, refcnt] : file->symbol2refcnt)
if (refcnt > 0 && sym.extent.Valid() &&
(sym.kind == Kind::Func || sym.kind == Kind::Type) &&
(ls_range = GetLsRange(wfile, sym.extent))) {
(ls_range = GetLsRange(wf, sym.extent))) {
FoldingRange &fold = result.emplace_back();
fold.startLine = ls_range->start.line;
fold.startCharacter = ls_range->start.character;

View File

@ -80,19 +80,23 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) {
void MessageHandler::textDocument_formatting(DocumentFormattingParam &param,
ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
Format(reply, wf, {0, (unsigned)wf->buffer_content.size()});
}
void MessageHandler::textDocument_onTypeFormatting(
DocumentOnTypeFormattingParam &param, ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
std::string_view code = wf->buffer_content;
int pos = GetOffsetForPosition(param.position, code);
auto lbrace = code.find_last_of('{', pos);
@ -103,10 +107,12 @@ void MessageHandler::textDocument_onTypeFormatting(
void MessageHandler::textDocument_rangeFormatting(
DocumentRangeFormattingParam &param, ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
std::string_view code = wf->buffer_content;
int begin = GetOffsetForPosition(param.range.start, code),
end = GetOffsetForPosition(param.range.end, code);

View File

@ -93,12 +93,14 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) {
void MessageHandler::textDocument_hover(TextDocumentPositionParam &param,
ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
Hover result;
}
Hover result;
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {
std::optional<lsRange> ls_range =
GetLsRange(wfiles->GetFile(file->def->path), sym.range);

View File

@ -44,10 +44,13 @@ MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders,
void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
ReferenceParam param;
Reflect(reader, param);
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
for (auto &folder : param.folders)
EnsureEndsInSlash(folder);
std::vector<uint8_t> file_set = db->GetFileSet(param.folders);

View File

@ -38,9 +38,9 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
const std::string &path = file.def->path;
path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path);
WorkingFile *working_file = wfiles->GetFile(path);
if (working_file)
path_to_edit[file_id].textDocument.version = working_file->version;
WorkingFile *wf = wfiles->GetFile(path);
if (wf)
path_to_edit[file_id].textDocument.version = wf->version;
}
TextEdit &edit = path_to_edit[file_id].edits.emplace_back();
@ -56,10 +56,12 @@ WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
} // namespace
void MessageHandler::textDocument_rename(RenameParam &param, ReplyOnce &reply) {
QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath());
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
if (!wf)
if (!wf) {
reply.NotReady(file);
return;
}
WorkspaceEdit result;
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {