diff options
| author | Sam McCall <sam.mccall@gmail.com> | 2018-10-17 07:32:05 +0000 |
|---|---|---|
| committer | Sam McCall <sam.mccall@gmail.com> | 2018-10-17 07:32:05 +0000 |
| commit | dc8f3cf8b0061e34ddda9f90d1db176b4a7c2d93 (patch) | |
| tree | 29b91bb8a92a1374027e64a4f560b1afa2001edd /clang-tools-extra/clangd/ClangdLSPServer.cpp | |
| parent | ff3ab33ec89042ed93bc8488b6c6971a1b4a9cf1 (diff) | |
| download | bcm5719-llvm-dc8f3cf8b0061e34ddda9f90d1db176b4a7c2d93.tar.gz bcm5719-llvm-dc8f3cf8b0061e34ddda9f90d1db176b4a7c2d93.zip | |
[clangd] Refactor JSON-over-stdin/stdout code into Transport abstraction. (re-land r344620)
Summary:
This paves the way for alternative transports (mac XPC, maybe messagepack?),
and also generally improves layering: testing ClangdLSPServer becomes less of
a pipe dream, we split up the JSONOutput monolith, etc.
This isn't a final state, much of what remains in JSONRPCDispatcher can go away,
handlers can call reply() on the transport directly, JSONOutput can be renamed
to StreamLogger and removed, etc. But this patch is sprawling already.
The main observable change (see tests) is that hitting EOF on input is now an
error: the client should send the 'exit' notification.
This is defensible: the protocol doesn't spell this case out. Reproducing the
current behavior for all combinations of shutdown/exit/EOF clutters interfaces.
We can iterate on this if desired.
Reviewers: jkorous, ioeric, hokein
Subscribers: mgorny, ilya-biryukov, MaskRay, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53286
llvm-svn: 344672
Diffstat (limited to 'clang-tools-extra/clangd/ClangdLSPServer.cpp')
| -rw-r--r-- | clang-tools-extra/clangd/ClangdLSPServer.cpp | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index b1863062d39..1585fbf61f7 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -162,7 +162,10 @@ void ClangdLSPServer::onShutdown(ShutdownParams &Params) { reply(nullptr); } -void ClangdLSPServer::onExit(ExitParams &Params) { IsDone = true; } +void ClangdLSPServer::onExit(ExitParams &Params) { + // No work to do. + // JSONRPCDispatcher shuts down the transport after this notification. +} void ClangdLSPServer::onDocumentDidOpen(DidOpenTextDocumentParams &Params) { PathRef File = Params.textDocument.uri.file(); @@ -497,39 +500,41 @@ void ClangdLSPServer::onReference(ReferenceParams &Params) { }); } -ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, +ClangdLSPServer::ClangdLSPServer(class Transport &Transp, const clangd::CodeCompleteOptions &CCOpts, llvm::Optional<Path> CompileCommandsDir, bool ShouldUseInMemoryCDB, const ClangdServer::Options &Opts) - : Out(Out), CDB(ShouldUseInMemoryCDB ? CompilationDB::makeInMemory() - : CompilationDB::makeDirectoryBased( - std::move(CompileCommandsDir))), + : Transp(Transp), + CDB(ShouldUseInMemoryCDB ? CompilationDB::makeInMemory() + : CompilationDB::makeDirectoryBased( + std::move(CompileCommandsDir))), CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()), SupportedCompletionItemKinds(defaultCompletionItemKinds()), Server(new ClangdServer(CDB.getCDB(), FSProvider, /*DiagConsumer=*/*this, Opts)) {} -bool ClangdLSPServer::run(std::FILE *In, JSONStreamStyle InputStyle) { - assert(!IsDone && "Run was called before"); +bool ClangdLSPServer::run() { assert(Server); // Set up JSONRPCDispatcher. JSONRPCDispatcher Dispatcher([](const json::Value &Params) { replyError(ErrorCode::MethodNotFound, "method not found"); + return true; }); registerCallbackHandlers(Dispatcher, /*Callbacks=*/*this); // Run the Language Server loop. - runLanguageServerLoop(In, Out, InputStyle, Dispatcher, IsDone); + bool CleanExit = true; + if (auto Err = Dispatcher.runLanguageServerLoop(Transp)) { + elog("Transport error: {0}", std::move(Err)); + CleanExit = false; + } - // Make sure IsDone is set to true after this method exits to ensure assertion - // at the start of the method fires if it's ever executed again. - IsDone = true; // Destroy ClangdServer to ensure all worker threads finish. Server.reset(); - return ShutdownRequestReceived; + return CleanExit && ShutdownRequestReceived; } std::vector<Fix> ClangdLSPServer::getFixes(StringRef File, @@ -589,15 +594,11 @@ void ClangdLSPServer::onDiagnosticsReady(PathRef File, } // Publish diagnostics. - Out.writeMessage(json::Object{ - {"jsonrpc", "2.0"}, - {"method", "textDocument/publishDiagnostics"}, - {"params", - json::Object{ - {"uri", URIForFile{File}}, - {"diagnostics", std::move(DiagnosticsJSON)}, - }}, - }); + Transp.notify("textDocument/publishDiagnostics", + json::Object{ + {"uri", URIForFile{File}}, + {"diagnostics", std::move(DiagnosticsJSON)}, + }); } void ClangdLSPServer::reparseOpenedFiles() { |

