[clang-tools-extra] r315214 - [clangd] Added a command-line arg to mirror clangd input into a file.

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 10 02:28:16 PDT 2017


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.cardoso at gmail.com
> wrote:

> Hi,
>
> On Mon, Oct 9, 2017 at 9:58 AM, Ilya Biryukov via cfe-commits
> <cfe-commits at 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 at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
>
> --
> Bruno Cardoso Lopes
> http://www.brunocardoso.cc
>



-- 
Regards,
Ilya Biryukov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171010/c8df85fd/attachment-0001.html>


More information about the cfe-commits mailing list