Sorry about that, `diff -b` seems to work. Restored commit and changed to `diff -b` in r315287. Thanks for spotting and reverting this.
On Mon, Oct 9, 2017 at 8:45 PM, Bruno Cardoso Lopes <bruno.card...@gmail.com > wrote: > Hi, > > On Mon, Oct 9, 2017 at 9:58 AM, Ilya Biryukov via cfe-commits > <cfe-commits@lists.llvm.org> wrote: > > Author: ibiryukov > > Date: Mon Oct 9 09:58:16 2017 > > New Revision: 315214 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=315214&view=rev > > Log: > > [clangd] Added a command-line arg to mirror clangd input into a file. > > > > Summary: The arg is useful for debugging and creating test cases. > > > > Reviewers: bkramer, krasimir > > > > Reviewed By: bkramer > > > > Subscribers: klimek, cfe-commits > > > > Differential Revision: https://reviews.llvm.org/D37970 > > > > Added: > > clang-tools-extra/trunk/test/clangd/input-mirror.test > > Modified: > > clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp > > clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h > > clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp > > > > Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp > > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ > JSONRPCDispatcher.cpp?rev=315214&r1=315213&r2=315214&view=diff > > ============================================================ > ================== > > --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original) > > +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Mon Oct 9 > 09:58:16 2017 > > @@ -37,6 +37,14 @@ void JSONOutput::log(const Twine &Messag > > Logs.flush(); > > } > > > > +void JSONOutput::mirrorInput(const Twine &Message) { > > + if (!InputMirror) > > + return; > > + > > + *InputMirror << Message; > > + InputMirror->flush(); > > +} > > + > > void Handler::handleMethod(llvm::yaml::MappingNode *Params, StringRef > ID) { > > Output.log("Method ignored.\n"); > > // Return that this method is unsupported. > > @@ -147,6 +155,14 @@ void clangd::runLanguageServerLoop(std:: > > continue; > > } > > > > + Out.mirrorInput(Line); > > + // Mirror '\n' that gets consumed by std::getline, but is not > included in > > + // the resulting Line. > > + // Note that '\r' is part of Line, so we don't need to mirror it > > + // separately. > > + if (!In.eof()) > > + Out.mirrorInput("\n"); > > + > > llvm::StringRef LineRef(Line); > > > > // We allow YAML-style comments in headers. Technically this > isn't part > > @@ -163,9 +179,8 @@ void clangd::runLanguageServerLoop(std:: > > if (LineRef.consume_front("Content-Length: ")) { > > if (ContentLength != 0) { > > Out.log("Warning: Duplicate Content-Length header received. " > > - "The previous value for this message (" > > - + std::to_string(ContentLength) > > - + ") was ignored.\n"); > > + "The previous value for this message (" + > > + std::to_string(ContentLength) + ") was ignored.\n"); > > } > > > > llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength); > > @@ -185,15 +200,13 @@ void clangd::runLanguageServerLoop(std:: > > // parser. > > std::vector<char> JSON(ContentLength + 1, '\0'); > > In.read(JSON.data(), ContentLength); > > + Out.mirrorInput(StringRef(JSON.data(), In.gcount())); > > > > // If the stream is aborted before we read ContentLength bytes, In > > // will have eofbit and failbit set. > > if (!In) { > > - Out.log("Input was aborted. Read only " > > - + std::to_string(In.gcount()) > > - + " bytes of expected " > > - + std::to_string(ContentLength) > > - + ".\n"); > > + Out.log("Input was aborted. Read only " + > std::to_string(In.gcount()) + > > + " bytes of expected " + std::to_string(ContentLength) + > ".\n"); > > break; > > } > > > > @@ -209,8 +222,8 @@ void clangd::runLanguageServerLoop(std:: > > if (IsDone) > > break; > > } else { > > - Out.log( "Warning: Missing Content-Length header, or message has > zero " > > - "length.\n" ); > > + Out.log("Warning: Missing Content-Length header, or message has > zero " > > + "length.\n"); > > } > > } > > } > > > > Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h > > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ > JSONRPCDispatcher.h?rev=315214&r1=315213&r2=315214&view=diff > > ============================================================ > ================== > > --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h (original) > > +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h Mon Oct 9 > 09:58:16 2017 > > @@ -24,8 +24,9 @@ namespace clangd { > > /// them. > > class JSONOutput : public Logger { > > public: > > - JSONOutput(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs) > > - : Outs(Outs), Logs(Logs) {} > > + JSONOutput(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs, > > + llvm::raw_ostream *InputMirror = nullptr) > > + : Outs(Outs), Logs(Logs), InputMirror(InputMirror) {} > > > > /// Emit a JSONRPC message. > > void writeMessage(const Twine &Message); > > @@ -33,9 +34,15 @@ public: > > /// Write to the logging stream. > > void log(const Twine &Message) override; > > > > + /// Mirror \p Message into InputMirror stream. Does nothing if > InputMirror is > > + /// null. > > + /// Unlike other methods of JSONOutput, mirrorInput is not > thread-safe. > > + void mirrorInput(const Twine &Message); > > + > > private: > > llvm::raw_ostream &Outs; > > llvm::raw_ostream &Logs; > > + llvm::raw_ostream *InputMirror; > > > > std::mutex StreamMutex; > > }; > > > > Modified: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp > > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/ > trunk/clangd/tool/ClangdMain.cpp?rev=315214&r1=315213&r2=315214&view=diff > > ============================================================ > ================== > > --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp (original) > > +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Mon Oct 9 > 09:58:16 2017 > > @@ -9,10 +9,12 @@ > > > > #include "ClangdLSPServer.h" > > #include "JSONRPCDispatcher.h" > > +#include "Path.h" > > #include "llvm/Support/CommandLine.h" > > #include "llvm/Support/FileSystem.h" > > #include "llvm/Support/Path.h" > > #include "llvm/Support/Program.h" > > +#include "llvm/Support/raw_ostream.h" > > #include <iostream> > > #include <memory> > > #include <string> > > @@ -43,11 +45,17 @@ static llvm::cl::opt<bool> RunSynchronou > > llvm::cl::desc("Parse on main thread. If set, -j is ignored"), > > llvm::cl::init(false), llvm::cl::Hidden); > > > > -static llvm::cl::opt<std::string> > > +static llvm::cl::opt<Path> > > ResourceDir("resource-dir", > > llvm::cl::desc("Directory for system clang headers"), > > llvm::cl::init(""), llvm::cl::Hidden); > > > > +static llvm::cl::opt<Path> InputMirrorFile( > > + "input-mirror-file", > > + llvm::cl::desc( > > + "Mirror all LSP input to the specified file. Useful for > debugging."), > > + llvm::cl::init(""), llvm::cl::Hidden); > > + > > int main(int argc, char *argv[]) { > > llvm::cl::ParseCommandLineOptions(argc, argv, "clangd"); > > > > @@ -63,9 +71,21 @@ int main(int argc, char *argv[]) { > > WorkerThreadsCount = 0; > > > > /// Validate command line arguments. > > + llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream; > > + if (!InputMirrorFile.empty()) { > > + std::error_code EC; > > + InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC, > llvm::sys::fs::F_RW); > > + if (EC) { > > + InputMirrorStream.reset(); > > + llvm::errs() << "Error while opening an input mirror file: " > > + << EC.message(); > > + } > > + } > > + > > llvm::raw_ostream &Outs = llvm::outs(); > > llvm::raw_ostream &Logs = llvm::errs(); > > - JSONOutput Out(Outs, Logs); > > + JSONOutput Out(Outs, Logs, > > + InputMirrorStream ? InputMirrorStream.getPointer() : > nullptr); > > > > // If --compile-commands-dir arg was invoked, check value and > override default > > // path. > > > > Added: clang-tools-extra/trunk/test/clangd/input-mirror.test > > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/ > trunk/test/clangd/input-mirror.test?rev=315214&view=auto > > ============================================================ > ================== > > --- clang-tools-extra/trunk/test/clangd/input-mirror.test (added) > > +++ clang-tools-extra/trunk/test/clangd/input-mirror.test Mon Oct 9 > 09:58:16 2017 > > @@ -0,0 +1,154 @@ > > +# RUN: clangd -run-synchronously -input-mirror-file %t < %s > > +# Note that we have to use '-Z' as -input-mirror-file does not have a > newline at the end of file. > > "-Z" isn't supported in some versions of diff, I tested "-b" and it > seems to do the job here, can you change that? > > Thanks, > > > +# RUN: diff -Z %t %s > > +# It is absolutely vital that this file has CRLF line endings. > > +# > > +Content-Length: 125 > > + > > +{"jsonrpc":"2.0","id":0,"method":"initialize","params": > {"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} > > + > > +Content-Length: 172 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didOpen","params" > :{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"int > main() {\nint a;\na;\n}\n"}}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 2,"character":0}}} > > +# Go to local variable > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 2,"character":1}}} > > +# Go to local variable, end of token > > + > > +Content-Length: 214 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 2},"contentChanges":[{"text":"struct Foo {\nint x;\n};\nint main() {\n > Foo bar = { x : 1 };\n}\n"}]}} > > + > > +Content-Length: 149 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 4,"character":14}}} > > +# Go to field, GNU old-style field designator > > + > > +Content-Length: 215 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 3},"contentChanges":[{"text":"struct Foo {\nint x;\n};\nint main() {\n > Foo baz = { .x = 2 };\n}\n"}]}} > > + > > +Content-Length: 149 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 4,"character":15}}} > > +# Go to field, field designator > > + > > +Content-Length: 187 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 4},"contentChanges":[{"text":"int main() {\n main();\n return > 0;\n}"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 1,"character":3}}} > > +# Go to function declaration, function call > > + > > +Content-Length: 208 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 5},"contentChanges":[{"text":"struct Foo {\n};\nint main() {\n Foo > bar;\n return 0;\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 3,"character":3}}} > > +# Go to struct declaration, new struct instance > > + > > +Content-Length: 231 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 5},"contentChanges":[{"text":"namespace n1 {\nstruct Foo {\n};\n}\nint > main() {\n n1::Foo bar;\n return 0;\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 5,"character":4}}} > > +# Go to struct declaration, new struct instance, qualified name > > + > > +Content-Length: 215 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 6},"contentChanges":[{"text":"struct Foo {\n int x;\n};\nint main() {\n > Foo bar;\n bar.x;\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 5,"character":7}}} > > +# Go to field declaration, field reference > > + > > +Content-Length: 220 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"struct Foo {\n void x();\n};\nint main() > {\n Foo bar;\n bar.x();\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 5,"character":7}}} > > +# Go to method declaration, method call > > + > > +Content-Length: 240 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"struct Foo {\n};\ntypedef Foo > TypedefFoo;\nint main() {\n TypedefFoo bar;\n return 0;\n}\n"}]}} > > + > > +Content-Length: 149 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 4,"character":10}}} > > +# Go to typedef > > + > > +Content-Length: 254 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"template <typename MyTemplateParam>\nvoid > foo() {\n MyTemplateParam a;\n}\nint main() {\n return 0;\n}\n"}]}} > > + > > +Content-Length: 149 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 2,"character":13}}} > > +# Go to template type parameter. Fails until clangIndex is modified to > handle those. > > +# no-CHECK: {"jsonrpc":"2.0","id":1,"result":[{"uri": > "file:///main.cpp", "range": {"start": {"line": 0, "character": 10}, "end": > {"line": 0, "character": 34}}}]} > > + > > +Content-Length: 256 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"namespace ns {\nstruct Foo {\nstatic void > bar() {}\n};\n}\nint main() {\n ns::Foo::bar();\n return 0;\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 6,"character":4}}} > > +# Go to namespace, static method call > > + > > +Content-Length: 265 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"namespace ns {\nstruct Foo {\n int > field;\n Foo(int param) : field(param) {}\n};\n}\nint main() {\n return > 0;\n}\n"}]}} > > + > > +Content-Length: 149 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 3,"character":21}}} > > +# Go to field, member initializer > > + > > +Content-Length: 204 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"#define MY_MACRO 0\nint main() {\n return > MY_MACRO;\n}\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 2,"character":9}}} > > +# Go to macro. > > + > > +Content-Length: 217 > > + > > +{"jsonrpc":"2.0","method":"textDocument/didChange"," > params":{"textDocument":{"uri":"file:///main.cpp","version": > 7},"contentChanges":[{"text":"#define FOO 1\nint a = FOO;\n#define FOO > 2\nint b = FOO;\n#undef FOO\n"}]}} > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 1,"character":8}}} > > +# Go to macro, re-defined later > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 3,"character":8}}} > > +# Go to macro, undefined later > > + > > +Content-Length: 148 > > + > > +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{" > textDocument":{"uri":"file:///main.cpp"},"position":{"line": > 4,"character":7}}} > > +# Go to macro, being undefined > > + > > +Content-Length: 44 > > + > > +{"jsonrpc":"2.0","id":3,"method":"shutdown"} > > > > > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits@lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > > > -- > Bruno Cardoso Lopes > http://www.brunocardoso.cc > -- Regards, Ilya Biryukov
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits