diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -171,6 +171,7 @@ void applyEdit(WorkspaceEdit WE, llvm::json::Value Success, Callback Reply); + void bindMethods(); std::vector getFixes(StringRef File, const clangd::Diagnostic &D); /// Checks if completion request should be ignored. We need this due to the diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -162,15 +162,15 @@ log("<-- {0}", Method); if (Method == "exit") return false; - if (!Server.Server) { - elog("Notification {0} before initialization", Method); - } else if (Method == "$/cancelRequest") { + if (Method == "$/cancelRequest") { onCancel(std::move(Params)); } else if (auto Handler = Notifications.lookup(Method)) { Handler(std::move(Params)); Server.maybeExportMemoryProfile(); Server.maybeCleanupMemory(); - } else { + } else if (!Server.Server) { + elog("Notification {0} before initialization", Method); + } else if (Method == "$/cancelRequest") { log("unhandled notification {0}", Method); } return true; @@ -185,15 +185,16 @@ SPAN_ATTACH(Tracer, "Params", Params); ReplyOnce Reply(ID, Method, &Server, Tracer.Args); log("<-- {0}({1})", Method, ID); - if (!Server.Server && Method != "initialize") { + if (auto Handler = Calls.lookup(Method)) { + Handler(std::move(Params), std::move(Reply)); + } else if (!Server.Server) { elog("Call {0} before initialization.", Method); Reply(llvm::make_error("server not initialized", ErrorCode::ServerNotInitialized)); - } else if (auto Handler = Calls.lookup(Method)) - Handler(std::move(Params), std::move(Reply)); - else + } else { Reply(llvm::make_error("method not found", ErrorCode::MethodNotFound)); + } return true; } @@ -568,6 +569,8 @@ BackgroundIndexProgressState = BackgroundIndexProgress::Empty; BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation; + bindMethods(); + // Per LSP, renameProvider can be either boolean or RenameOptions. // RenameOptions will be specified if the client states it supports prepare. llvm::json::Value RenameProvider = @@ -1490,9 +1493,11 @@ this->Opts.ContextProvider = ClangdServer::createConfiguredContextProvider( Opts.ConfigProvider, this); } + MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize); +} +void ClangdLSPServer::bindMethods() { // clang-format off - MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize); MsgHandler->bind("initialized", &ClangdLSPServer::onInitialized); MsgHandler->bind("shutdown", &ClangdLSPServer::onShutdown); MsgHandler->bind("sync", &ClangdLSPServer::onSync);