rwols updated this revision to Diff 121524. rwols added a comment. Use llvm::Error for beautiful handling of errors.
It's perhaps an idea to write a `replyExpected(llvm::Expected<T>)`, that will transparently handle `llvm::Error`s. I'll write a unit test for these changes next. It's probably best to wait for https://reviews.llvm.org/D39435 to land, and then rebase. https://reviews.llvm.org/D39430 Files: clangd/ClangdLSPServer.cpp clangd/ClangdServer.cpp clangd/ClangdServer.h clangd/JSONRPCDispatcher.cpp clangd/JSONRPCDispatcher.h test/clangd/formatting.test
Index: test/clangd/formatting.test =================================================================== --- test/clangd/formatting.test +++ test/clangd/formatting.test @@ -1,4 +1,4 @@ -# RUN: clangd < %s | FileCheck %s +# RUN: clangd -run-synchronously < %s | FileCheck %s # It is absolutely vital that this file has CRLF line endings. # Content-Length: 125 Index: clangd/JSONRPCDispatcher.h =================================================================== --- clangd/JSONRPCDispatcher.h +++ clangd/JSONRPCDispatcher.h @@ -15,6 +15,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/YAMLParser.h" +#include "llvm/Support/Error.h" #include <iosfwd> #include <mutex> @@ -58,6 +59,8 @@ void reply(const Twine &Result); /// Sends an error response to the client, and logs it. void replyError(int code, const llvm::StringRef &Message); + /// Send all error messages contained in Err to the client, and log them. + void replyError(llvm::Error Err); private: JSONOutput &Out; Index: clangd/JSONRPCDispatcher.cpp =================================================================== --- clangd/JSONRPCDispatcher.cpp +++ clangd/JSONRPCDispatcher.cpp @@ -64,6 +64,11 @@ } } +void RequestContext::replyError(llvm::Error Err) { + const auto Message = llvm::toString(std::move(Err)); + replyError(/*UnknownErrorCode*/ -32001, Message); +} + void JSONRPCDispatcher::registerHandler(StringRef Method, Handler H) { assert(!Handlers.count(Method) && "Handler already registered!"); Handlers[Method] = std::move(H); Index: clangd/ClangdServer.h =================================================================== --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -285,11 +285,15 @@ llvm::Optional<Path> switchSourceHeader(PathRef Path); /// Run formatting for \p Rng inside \p File. - std::vector<tooling::Replacement> formatRange(PathRef File, Range Rng); + llvm::Expected<std::vector<tooling::Replacement>> formatRange(PathRef File, + Range Rng); + /// Run formatting for the whole \p File. - std::vector<tooling::Replacement> formatFile(PathRef File); + llvm::Expected<std::vector<tooling::Replacement>> formatFile(PathRef File); + /// Run formatting after a character was typed at \p Pos in \p File. - std::vector<tooling::Replacement> formatOnType(PathRef File, Position Pos); + llvm::Expected<std::vector<tooling::Replacement>> formatOnType(PathRef File, + Position Pos); /// Gets current document contents for \p File. \p File must point to a /// currently tracked file. Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -34,13 +34,14 @@ std::promise<void> &Promise; }; -std::vector<tooling::Replacement> formatCode(StringRef Code, StringRef Filename, - ArrayRef<tooling::Range> Ranges) { +llvm::Expected<std::vector<tooling::Replacement>> +formatCode(StringRef Code, StringRef Filename, + ArrayRef<tooling::Range> Ranges) { // Call clang-format. - // FIXME: Don't ignore style. - format::FormatStyle Style = format::getLLVMStyle(); - auto Result = format::reformat(Style, Code, Ranges, Filename); - + auto StyleOrError = format::getStyle("file", Filename, "LLVM", Code); + if (!StyleOrError) + return StyleOrError.takeError(); + auto Result = format::reformat(StyleOrError.get(), Code, Ranges, Filename); return std::vector<tooling::Replacement>(Result.begin(), Result.end()); } @@ -301,23 +302,24 @@ return make_tagged(std::move(Result), TaggedFS.Tag); } -std::vector<tooling::Replacement> ClangdServer::formatRange(PathRef File, - Range Rng) { +llvm::Expected<std::vector<tooling::Replacement>> +ClangdServer::formatRange(PathRef File, Range Rng) { std::string Code = getDocument(File); size_t Begin = positionToOffset(Code, Rng.start); size_t Len = positionToOffset(Code, Rng.end) - Begin; return formatCode(Code, File, {tooling::Range(Begin, Len)}); } -std::vector<tooling::Replacement> ClangdServer::formatFile(PathRef File) { +llvm::Expected<std::vector<tooling::Replacement>> +ClangdServer::formatFile(PathRef File) { // Format everything. std::string Code = getDocument(File); return formatCode(Code, File, {tooling::Range(0, Code.size())}); } -std::vector<tooling::Replacement> ClangdServer::formatOnType(PathRef File, - Position Pos) { +llvm::Expected<std::vector<tooling::Replacement>> +ClangdServer::formatOnType(PathRef File, Position Pos) { // Look for the previous opening brace from the character position and // format starting from there. std::string Code = getDocument(File); Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -9,6 +9,7 @@ #include "ClangdLSPServer.h" #include "JSONRPCDispatcher.h" +#include <llvm/Support/Error.h> using namespace clang::clangd; using namespace clang; @@ -91,28 +92,32 @@ void ClangdLSPServer::onDocumentOnTypeFormatting( Ctx C, DocumentOnTypeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; - std::string Code = Server.getDocument(File); - std::string Edits = - replacementsToEdits(Code, Server.formatOnType(File, Params.position)); - C.reply("[" + Edits + "]"); + const auto File = Params.textDocument.uri.file; + auto Edits = Server.formatOnType(File, Params.position); + if (Edits) + C.reply("[" + replacementsToEdits(Server.getDocument(File), *Edits) + "]"); + else + C.replyError(Edits.takeError()); } void ClangdLSPServer::onDocumentRangeFormatting( Ctx C, DocumentRangeFormattingParams &Params) { - auto File = Params.textDocument.uri.file; - std::string Code = Server.getDocument(File); - std::string Edits = - replacementsToEdits(Code, Server.formatRange(File, Params.range)); - C.reply("[" + Edits + "]"); + const auto File = Params.textDocument.uri.file; + auto Edits = Server.formatRange(File, Params.range); + if (Edits) + C.reply("[" + replacementsToEdits(Server.getDocument(File), *Edits) + "]"); + else + C.replyError(Edits.takeError()); } void ClangdLSPServer::onDocumentFormatting(Ctx C, DocumentFormattingParams &Params) { - auto File = Params.textDocument.uri.file; - std::string Code = Server.getDocument(File); - std::string Edits = replacementsToEdits(Code, Server.formatFile(File)); - C.reply("[" + Edits + "]"); + const auto File = Params.textDocument.uri.file; + auto Edits = Server.formatFile(File); + if (Edits) + C.reply("[" + replacementsToEdits(Server.getDocument(File), *Edits) + "]"); + else + C.replyError(Edits.takeError()); } void ClangdLSPServer::onCodeAction(Ctx C, CodeActionParams &Params) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits