diff --git a/src/clang_tu.cc b/src/clang_tu.cc index e6fe3ef9..4092372b 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -98,7 +98,8 @@ BuildCompilerInvocation(std::vector args, std::string save = "-resource-dir=" + g_config->clang.resourceDir; args.push_back(save.c_str()); IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); + CompilerInstance::createDiagnostics(new DiagnosticOptions, + new IgnoringDiagConsumer, true)); std::unique_ptr CI = createInvocationFromCommandLine(args, Diags, VFS); if (CI) { diff --git a/src/message_handler.cc b/src/message_handler.cc index 2f51e326..e7f25d2c 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -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 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; } diff --git a/src/message_handler.hh b/src/message_handler.hh index 14e64eaf..d60e44b0 100644 --- a/src/message_handler.hh +++ b/src/message_handler.hh @@ -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 &)); diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 68acc942..f1e07b74 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -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; diff --git a/src/messages/ccls_info.cc b/src/messages/ccls_info.cc index 9560f2d9..c48dd519 100644 --- a/src/messages/ccls_info.cc +++ b/src/messages/ccls_info.cc @@ -54,7 +54,7 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) { } void MessageHandler::ccls_fileInfo(TextDocumentParam ¶m, ReplyOnce &reply) { - QueryFile *file = FindFile(reply, param.textDocument.uri.GetPath()); + QueryFile *file = FindFile(param.textDocument.uri.GetPath()); if (!file) return; diff --git a/src/messages/ccls_inheritance.cc b/src/messages/ccls_inheritance.cc index 5352a43a..6be44fe4 100644 --- a/src/messages/ccls_inheritance.cc +++ b/src/messages/ccls_inheritance.cc @@ -146,7 +146,7 @@ void Inheritance(MessageHandler *m, Param ¶m, 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); diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index b204584d..cae89c86 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -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: diff --git a/src/messages/ccls_navigate.cc b/src/messages/ccls_navigate.cc index 991823f6..d097aa96 100644 --- a/src/messages/ccls_navigate.cc +++ b/src/messages/ccls_navigate.cc @@ -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 = diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 560a07e2..bf0cbbf9 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -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 result; for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) { diff --git a/src/messages/textDocument_code.cc b/src/messages/textDocument_code.cc index aa45e134..b96db1ae 100644 --- a/src/messages/textDocument_code.cc +++ b/src/messages/textDocument_code.cc @@ -34,8 +34,10 @@ MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit); void MessageHandler::textDocument_codeAction(CodeActionParam ¶m, ReplyOnce &reply) { WorkingFile *wf = wfiles->GetFile(param.textDocument.uri.GetPath()); - if (!wf) + if (!wf) { + reply.NotReady(true); return; + } std::vector result; std::vector diagnostics; wfiles->WithLock([&]() { diagnostics = wf->diagnostics; }); @@ -92,15 +94,14 @@ struct CommonCodeLensParams { void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m, ReplyOnce &reply) { - std::vector 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 result; auto Add = [&](const char *singular, Cmd_xref show, Range range, int num, bool force_display = false) { if (!num && !force_display) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index a371c753..4691189f 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -449,13 +449,15 @@ public: void MessageHandler::textDocument_completion(CompletionParam ¶m, ReplyOnce &reply) { static CompleteConsumerCache> 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; diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 93fbd514..62927547 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -48,10 +48,12 @@ std::vector GetNonDefDeclarationTargets(DB *db, SymbolRef sym) { void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, 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 result; Maybe on_def; @@ -169,10 +171,12 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m, void MessageHandler::textDocument_typeDefinition( TextDocumentPositionParam ¶m, 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 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(); diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index 3677bba8..2dc91629 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -44,8 +44,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { 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); diff --git a/src/messages/textDocument_document.cc b/src/messages/textDocument_document.cc index 5ad1b26b..e65a6c77 100644 --- a/src/messages/textDocument_document.cc +++ b/src/messages/textDocument_document.cc @@ -44,10 +44,12 @@ MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role); void MessageHandler::textDocument_documentHighlight( TextDocumentPositionParam ¶m, 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 result; std::vector syms = @@ -88,10 +90,10 @@ MAKE_REFLECT_STRUCT(DocumentLink, range, target); void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m, 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 result; diff --git a/src/messages/textDocument_foldingRange.cc b/src/messages/textDocument_foldingRange.cc index bf1c1ffc..9f07b7a7 100644 --- a/src/messages/textDocument_foldingRange.cc +++ b/src/messages/textDocument_foldingRange.cc @@ -31,19 +31,19 @@ MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m, 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 result; std::optional 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; diff --git a/src/messages/textDocument_formatting.cc b/src/messages/textDocument_formatting.cc index 4d86898e..37bd7c46 100644 --- a/src/messages/textDocument_formatting.cc +++ b/src/messages/textDocument_formatting.cc @@ -80,19 +80,23 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) { void MessageHandler::textDocument_formatting(DocumentFormattingParam ¶m, 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 ¶m, 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 ¶m, 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); diff --git a/src/messages/textDocument_hover.cc b/src/messages/textDocument_hover.cc index 89ecd9b3..eec1edfb 100644 --- a/src/messages/textDocument_hover.cc +++ b/src/messages/textDocument_hover.cc @@ -93,12 +93,14 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) { void MessageHandler::textDocument_hover(TextDocumentPositionParam ¶m, 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 ls_range = GetLsRange(wfiles->GetFile(file->def->path), sym.range); diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index db026eb0..e8f8eeb4 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -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 file_set = db->GetFileSet(param.folders); diff --git a/src/messages/textDocument_rename.cc b/src/messages/textDocument_rename.cc index e6ea5b96..05028263 100644 --- a/src/messages/textDocument_rename.cc +++ b/src/messages/textDocument_rename.cc @@ -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 ¶m, 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)) {