From 4db732a7db8a0b69cc8086c899d0c03d1f1597e8 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Sat, 30 Sep 2017 10:08:52 +0000 Subject: [PATCH] [clangd] simplify ClangdLSPServer by private-inheriting callback interfaces. NFC Summary: There doesn't seem to be any real separation between the current three objects. Feel free to reject this if you find the current style valuable, though. (Mostly I'm just looking around for cleanups to help me understand the code). Reviewers: ilya-biryukov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D38414 llvm-svn: 314587 --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 146 +++++++++------------------ clang-tools-extra/clangd/ClangdLSPServer.h | 45 ++++++--- 2 files changed, 79 insertions(+), 112 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index d1890ed..135cbf4 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -9,7 +9,6 @@ #include "ClangdLSPServer.h" #include "JSONRPCDispatcher.h" -#include "ProtocolHandlers.h" using namespace clang::clangd; using namespace clang; @@ -38,50 +37,8 @@ replacementsToEdits(StringRef Code, } // namespace -ClangdLSPServer::LSPDiagnosticsConsumer::LSPDiagnosticsConsumer( - ClangdLSPServer &Server) - : Server(Server) {} - -void ClangdLSPServer::LSPDiagnosticsConsumer::onDiagnosticsReady( - PathRef File, Tagged> Diagnostics) { - Server.consumeDiagnostics(File, Diagnostics.Value); -} - -class ClangdLSPServer::LSPProtocolCallbacks : public ProtocolCallbacks { -public: - LSPProtocolCallbacks(ClangdLSPServer &LangServer) : LangServer(LangServer) {} - - void onInitialize(StringRef ID, InitializeParams IP, - JSONOutput &Out) override; - void onShutdown(JSONOutput &Out) override; - void onDocumentDidOpen(DidOpenTextDocumentParams Params, - JSONOutput &Out) override; - void onDocumentDidChange(DidChangeTextDocumentParams Params, - JSONOutput &Out) override; - void onDocumentDidClose(DidCloseTextDocumentParams Params, - JSONOutput &Out) override; - void onDocumentOnTypeFormatting(DocumentOnTypeFormattingParams Params, - StringRef ID, JSONOutput &Out) override; - void onDocumentRangeFormatting(DocumentRangeFormattingParams Params, - StringRef ID, JSONOutput &Out) override; - void onDocumentFormatting(DocumentFormattingParams Params, StringRef ID, - JSONOutput &Out) override; - void onCodeAction(CodeActionParams Params, StringRef ID, - JSONOutput &Out) override; - void onCompletion(TextDocumentPositionParams Params, StringRef ID, - JSONOutput &Out) override; - void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID, - JSONOutput &Out) override; - void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID, - JSONOutput &Out) override; - -private: - ClangdLSPServer &LangServer; -}; - -void ClangdLSPServer::LSPProtocolCallbacks::onInitialize(StringRef ID, - InitializeParams IP, - JSONOutput &Out) { +void ClangdLSPServer::onInitialize(StringRef ID, InitializeParams IP, + JSONOutput &Out) { Out.writeMessage( R"({"jsonrpc":"2.0","id":)" + ID + R"(,"result":{"capabilities":{ @@ -94,79 +51,74 @@ void ClangdLSPServer::LSPProtocolCallbacks::onInitialize(StringRef ID, "definitionProvider": true }}})"); if (IP.rootUri && !IP.rootUri->file.empty()) - LangServer.Server.setRootPath(IP.rootUri->file); + Server.setRootPath(IP.rootUri->file); else if (IP.rootPath && !IP.rootPath->empty()) - LangServer.Server.setRootPath(*IP.rootPath); + Server.setRootPath(*IP.rootPath); } -void ClangdLSPServer::LSPProtocolCallbacks::onShutdown(JSONOutput &Out) { - LangServer.IsDone = true; -} +void ClangdLSPServer::onShutdown(JSONOutput &Out) { IsDone = true; } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentDidOpen( - DidOpenTextDocumentParams Params, JSONOutput &Out) { +void ClangdLSPServer::onDocumentDidOpen(DidOpenTextDocumentParams Params, + JSONOutput &Out) { if (Params.metadata && !Params.metadata->extraFlags.empty()) - LangServer.CDB.setExtraFlagsForFile(Params.textDocument.uri.file, - std::move(Params.metadata->extraFlags)); - LangServer.Server.addDocument(Params.textDocument.uri.file, - Params.textDocument.text); + CDB.setExtraFlagsForFile(Params.textDocument.uri.file, + std::move(Params.metadata->extraFlags)); + Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text); } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentDidChange( - DidChangeTextDocumentParams Params, JSONOutput &Out) { +void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams Params, + JSONOutput &Out) { // We only support full syncing right now. - LangServer.Server.addDocument(Params.textDocument.uri.file, - Params.contentChanges[0].text); + Server.addDocument(Params.textDocument.uri.file, + Params.contentChanges[0].text); } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentDidClose( - DidCloseTextDocumentParams Params, JSONOutput &Out) { - LangServer.Server.removeDocument(Params.textDocument.uri.file); +void ClangdLSPServer::onDocumentDidClose(DidCloseTextDocumentParams Params, + JSONOutput &Out) { + Server.removeDocument(Params.textDocument.uri.file); } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentOnTypeFormatting( +void ClangdLSPServer::onDocumentOnTypeFormatting( DocumentOnTypeFormattingParams Params, StringRef ID, JSONOutput &Out) { auto File = Params.textDocument.uri.file; - std::string Code = LangServer.Server.getDocument(File); - std::string Edits = replacementsToEdits( - Code, LangServer.Server.formatOnType(File, Params.position)); + std::string Code = Server.getDocument(File); + std::string Edits = + replacementsToEdits(Code, Server.formatOnType(File, Params.position)); Out.writeMessage(R"({"jsonrpc":"2.0","id":)" + ID.str() + R"(,"result":[)" + Edits + R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentRangeFormatting( +void ClangdLSPServer::onDocumentRangeFormatting( DocumentRangeFormattingParams Params, StringRef ID, JSONOutput &Out) { auto File = Params.textDocument.uri.file; - std::string Code = LangServer.Server.getDocument(File); - std::string Edits = replacementsToEdits( - Code, LangServer.Server.formatRange(File, Params.range)); + std::string Code = Server.getDocument(File); + std::string Edits = + replacementsToEdits(Code, Server.formatRange(File, Params.range)); Out.writeMessage(R"({"jsonrpc":"2.0","id":)" + ID.str() + R"(,"result":[)" + Edits + R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onDocumentFormatting( - DocumentFormattingParams Params, StringRef ID, JSONOutput &Out) { +void ClangdLSPServer::onDocumentFormatting(DocumentFormattingParams Params, + StringRef ID, JSONOutput &Out) { auto File = Params.textDocument.uri.file; - std::string Code = LangServer.Server.getDocument(File); - std::string Edits = - replacementsToEdits(Code, LangServer.Server.formatFile(File)); + std::string Code = Server.getDocument(File); + std::string Edits = replacementsToEdits(Code, Server.formatFile(File)); Out.writeMessage(R"({"jsonrpc":"2.0","id":)" + ID.str() + R"(,"result":[)" + Edits + R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onCodeAction( - CodeActionParams Params, StringRef ID, JSONOutput &Out) { +void ClangdLSPServer::onCodeAction(CodeActionParams Params, StringRef ID, + JSONOutput &Out) { // We provide a code action for each diagnostic at the requested location // which has FixIts available. - std::string Code = - LangServer.Server.getDocument(Params.textDocument.uri.file); + std::string Code = Server.getDocument(Params.textDocument.uri.file); std::string Commands; for (Diagnostic &D : Params.context.diagnostics) { std::vector Fixes = - LangServer.getFixIts(Params.textDocument.uri.file, D); + getFixIts(Params.textDocument.uri.file, D); std::string Edits = replacementsToEdits(Code, Fixes); if (!Edits.empty()) @@ -186,10 +138,10 @@ void ClangdLSPServer::LSPProtocolCallbacks::onCodeAction( R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onCompletion( - TextDocumentPositionParams Params, StringRef ID, JSONOutput &Out) { +void ClangdLSPServer::onCompletion(TextDocumentPositionParams Params, + StringRef ID, JSONOutput &Out) { - auto Items = LangServer.Server + auto Items = Server .codeComplete(Params.textDocument.uri.file, Position{Params.position.line, Params.position.character}) @@ -207,10 +159,10 @@ void ClangdLSPServer::LSPProtocolCallbacks::onCompletion( R"(,"result":[)" + Completions + R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onGoToDefinition( - TextDocumentPositionParams Params, StringRef ID, JSONOutput &Out) { +void ClangdLSPServer::onGoToDefinition(TextDocumentPositionParams Params, + StringRef ID, JSONOutput &Out) { - auto Items = LangServer.Server + auto Items = Server .findDefinitions(Params.textDocument.uri.file, Position{Params.position.line, Params.position.character}) @@ -228,10 +180,9 @@ void ClangdLSPServer::LSPProtocolCallbacks::onGoToDefinition( R"(,"result":[)" + Locations + R"(]})"); } -void ClangdLSPServer::LSPProtocolCallbacks::onSwitchSourceHeader( - TextDocumentIdentifier Params, StringRef ID, JSONOutput &Out) { - llvm::Optional Result = - LangServer.Server.switchSourceHeader(Params.uri.file); +void ClangdLSPServer::onSwitchSourceHeader(TextDocumentIdentifier Params, + StringRef ID, JSONOutput &Out) { + llvm::Optional Result = Server.switchSourceHeader(Params.uri.file); std::string ResultUri; if (Result) ResultUri = URI::unparse(URI::fromFile(*Result)); @@ -246,17 +197,16 @@ void ClangdLSPServer::LSPProtocolCallbacks::onSwitchSourceHeader( ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, bool SnippetCompletions, llvm::Optional ResourceDir) - : Out(Out), CDB(/*Logger=*/Out), DiagConsumer(*this), - Server(CDB, DiagConsumer, FSProvider, AsyncThreadsCount, + : Out(Out), CDB(/*Logger=*/Out), + Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount, SnippetCompletions, /*Logger=*/Out, ResourceDir) {} void ClangdLSPServer::run(std::istream &In) { assert(!IsDone && "Run was called before"); // Set up JSONRPCDispatcher. - LSPProtocolCallbacks Callbacks(*this); JSONRPCDispatcher Dispatcher(llvm::make_unique(Out)); - registerCallbackHandlers(Dispatcher, Out, Callbacks); + registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this); // Run the Language Server loop. runLanguageServerLoop(In, Out, Dispatcher, IsDone); @@ -281,12 +231,12 @@ ClangdLSPServer::getFixIts(StringRef File, const clangd::Diagnostic &D) { return FixItsIter->second; } -void ClangdLSPServer::consumeDiagnostics( - PathRef File, std::vector Diagnostics) { +void ClangdLSPServer::onDiagnosticsReady( + PathRef File, Tagged> Diagnostics) { std::string DiagnosticsJSON; DiagnosticToReplacementMap LocalFixIts; // Temporary storage - for (auto &DiagWithFixes : Diagnostics) { + for (auto &DiagWithFixes : Diagnostics.Value) { auto Diag = DiagWithFixes.Diag; DiagnosticsJSON += R"({"range":)" + Range::unparse(Diag.range) + diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 41964e7..ff0b907 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -14,6 +14,7 @@ #include "GlobalCompilationDatabase.h" #include "Path.h" #include "Protocol.h" +#include "ProtocolHandlers.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/Optional.h" @@ -24,7 +25,7 @@ class JSONOutput; /// This class provides implementation of an LSP server, glueing the JSON /// dispatch and ClangdServer together. -class ClangdLSPServer { +class ClangdLSPServer : private DiagnosticsConsumer, private ProtocolCallbacks { public: ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, bool SnippetCompletions, @@ -37,18 +38,35 @@ public: void run(std::istream &In); private: - class LSPProtocolCallbacks; - class LSPDiagnosticsConsumer : public DiagnosticsConsumer { - public: - LSPDiagnosticsConsumer(ClangdLSPServer &Server); - - virtual void - onDiagnosticsReady(PathRef File, - Tagged> Diagnostics); - - private: - ClangdLSPServer &Server; - }; + // Implement DiagnosticsConsumer. + virtual void + onDiagnosticsReady(PathRef File, + Tagged> Diagnostics) override; + + // Implement ProtocolCallbacks. + void onInitialize(StringRef ID, InitializeParams IP, + JSONOutput &Out) override; + void onShutdown(JSONOutput &Out) override; + void onDocumentDidOpen(DidOpenTextDocumentParams Params, + JSONOutput &Out) override; + void onDocumentDidChange(DidChangeTextDocumentParams Params, + JSONOutput &Out) override; + void onDocumentDidClose(DidCloseTextDocumentParams Params, + JSONOutput &Out) override; + void onDocumentOnTypeFormatting(DocumentOnTypeFormattingParams Params, + StringRef ID, JSONOutput &Out) override; + void onDocumentRangeFormatting(DocumentRangeFormattingParams Params, + StringRef ID, JSONOutput &Out) override; + void onDocumentFormatting(DocumentFormattingParams Params, StringRef ID, + JSONOutput &Out) override; + void onCodeAction(CodeActionParams Params, StringRef ID, + JSONOutput &Out) override; + void onCompletion(TextDocumentPositionParams Params, StringRef ID, + JSONOutput &Out) override; + void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID, + JSONOutput &Out) override; + void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID, + JSONOutput &Out) override; std::vector getFixIts(StringRef File, const clangd::Diagnostic &D); @@ -74,7 +92,6 @@ private: // Various ClangdServer parameters go here. It's important they're created // before ClangdServer. DirectoryBasedGlobalCompilationDatabase CDB; - LSPDiagnosticsConsumer DiagConsumer; RealFileSystemProvider FSProvider; // Server must be the last member of the class to allow its destructor to exit -- 2.7.4