Index: clang-tools-extra/trunk/clangd/ClangdLSPServer.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h @@ -45,7 +45,8 @@ /// each instance of ClangdLSPServer. /// /// \return Wether we received a 'shutdown' request before an 'exit' request - bool run(std::istream &In); + bool run(std::istream &In, + JSONStreamStyle InputStyle = JSONStreamStyle::Standard); private: // Implement DiagnosticsConsumer. Index: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp @@ -332,7 +332,7 @@ StorePreamblesInMemory, BuildDynamicSymbolIndex, StaticIdx, ResourceDir) {} -bool ClangdLSPServer::run(std::istream &In) { +bool ClangdLSPServer::run(std::istream &In, JSONStreamStyle InputStyle) { assert(!IsDone && "Run was called before"); // Set up JSONRPCDispatcher. @@ -342,7 +342,7 @@ registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this); // Run the Language Server loop. - runLanguageServerLoop(In, Out, Dispatcher, IsDone); + runLanguageServerLoop(In, Out, InputStyle, Dispatcher, IsDone); // 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. Index: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h =================================================================== --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h @@ -88,6 +88,14 @@ Handler UnknownHandler; }; +/// Controls the way JSON-RPC messages are encoded (both input and output). +enum JSONStreamStyle { + /// Encoding per the LSP specification, with mandatory Content-Length header. + Standard, + /// Messages are delimited by a '---' line. Comment lines start with #. + Delimited +}; + /// Parses input queries from LSP client (coming from \p In) and runs call /// method of \p Dispatcher for each query. /// After handling each query checks if \p IsDone is set true and exits the loop @@ -95,6 +103,7 @@ /// Input stream(\p In) must be opened in binary mode to avoid preliminary /// replacements of \r\n with \n. void runLanguageServerLoop(std::istream &In, JSONOutput &Out, + JSONStreamStyle InputStyle, JSONRPCDispatcher &Dispatcher, bool &IsDone); } // namespace clangd Index: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp =================================================================== --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp @@ -180,89 +180,132 @@ return true; } -void clangd::runLanguageServerLoop(std::istream &In, JSONOutput &Out, - JSONRPCDispatcher &Dispatcher, - bool &IsDone) { +static llvm::Optional readStandardMessage(std::istream &In, + JSONOutput &Out) { + // A Language Server Protocol message starts with a set of HTTP headers, + // delimited by \r\n, and terminated by an empty line (\r\n). + unsigned long long ContentLength = 0; while (In.good()) { - // A Language Server Protocol message starts with a set of HTTP headers, - // delimited by \r\n, and terminated by an empty line (\r\n). - unsigned long long ContentLength = 0; - while (In.good()) { - std::string Line; - std::getline(In, Line); - if (!In.good() && errno == EINTR) { - In.clear(); - continue; - } + std::string Line; + std::getline(In, Line); + if (!In.good() && errno == EINTR) { + In.clear(); + 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 comments in headers. Technically this isn't part - // of the LSP specification, but makes writing tests easier. - if (LineRef.startswith("#")) - continue; - - // Content-Type is a specified header, but does nothing. - // Content-Length is a mandatory header. It specifies the length of the - // following JSON. - // It is unspecified what sequence headers must be supplied in, so we - // allow any sequence. - // The end of headers is signified by an empty line. - if (LineRef.consume_front("Content-Length: ")) { - if (ContentLength != 0) { - log("Warning: Duplicate Content-Length header received. " - "The previous value for this message (" + - llvm::Twine(ContentLength) + ") was ignored.\n"); - } - - llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength); - continue; - } else if (!LineRef.trim().empty()) { - // It's another header, ignore it. - continue; - } else { - // An empty line indicates the end of headers. - // Go ahead and read the JSON. - break; + 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 comments in headers. Technically this isn't part + // of the LSP specification, but makes writing tests easier. + if (LineRef.startswith("#")) + continue; + + // Content-Type is a specified header, but does nothing. + // Content-Length is a mandatory header. It specifies the length of the + // following JSON. + // It is unspecified what sequence headers must be supplied in, so we + // allow any sequence. + // The end of headers is signified by an empty line. + if (LineRef.consume_front("Content-Length: ")) { + if (ContentLength != 0) { + log("Warning: Duplicate Content-Length header received. " + "The previous value for this message (" + + llvm::Twine(ContentLength) + ") was ignored.\n"); } - } - // Guard against large messages. This is usually a bug in the client code - // and we don't want to crash downstream because of it. - if (ContentLength > 1 << 30) { // 1024M - In.ignore(ContentLength); - log("Skipped overly large message of " + Twine(ContentLength) + - " bytes.\n"); + llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength); continue; + } else if (!LineRef.trim().empty()) { + // It's another header, ignore it. + continue; + } else { + // An empty line indicates the end of headers. + // Go ahead and read the JSON. + break; } + } - if (ContentLength > 0) { - std::vector JSON(ContentLength); - llvm::StringRef JSONRef; - { - 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) { - log("Input was aborted. Read only " + llvm::Twine(In.gcount()) + - " bytes of expected " + llvm::Twine(ContentLength) + ".\n"); - break; - } + // Guard against large messages. This is usually a bug in the client code + // and we don't want to crash downstream because of it. + if (ContentLength > 1 << 30) { // 1024M + In.ignore(ContentLength); + log("Skipped overly large message of " + Twine(ContentLength) + + " bytes.\n"); + return llvm::None; + } - JSONRef = StringRef(JSON.data(), ContentLength); - } + if (ContentLength > 0) { + std::string JSON(ContentLength, '\0'); + llvm::StringRef JSONRef; + In.read(&JSON[0], 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) { + log("Input was aborted. Read only " + llvm::Twine(In.gcount()) + + " bytes of expected " + llvm::Twine(ContentLength) + ".\n"); + return llvm::None; + } + return std::move(JSON); + } else { + log("Warning: Missing Content-Length header, or message has zero " + "length.\n"); + return llvm::None; + } +} + +// For lit tests we support a simplified syntax: +// - messages are delimited by '---' on a line by itself +// - lines starting with # are ignored. +// This is a testing path, so favor simplicity over performance here. +static llvm::Optional readDelimitedMessage(std::istream &In, + JSONOutput &Out) { + std::string JSON; + std::string Line; + while (std::getline(In, Line)) { + if (!In.eof()) // getline() consumed the newline. + Line.push_back('\n'); + auto LineRef = llvm::StringRef(Line).trim(); + if (LineRef.startswith("#")) // comment + continue; + + bool IsDelim = LineRef.find_first_not_of('-') == llvm::StringRef::npos; + if (!IsDelim) // Line is part of a JSON message. + JSON += Line; + if (IsDelim || In.eof()) { + Out.mirrorInput( + llvm::formatv("Content-Length: {0}\r\n\r\n{1}", JSON.size(), JSON)); + return std::move(JSON); + } + } + + if (In.bad()) { + log("Input error while reading message!"); + return llvm::None; + } else { + log("Input message terminated by EOF"); + return std::move(JSON); + } +} - if (auto Doc = json::parse(JSONRef)) { +void clangd::runLanguageServerLoop(std::istream &In, JSONOutput &Out, + JSONStreamStyle InputStyle, + JSONRPCDispatcher &Dispatcher, + bool &IsDone) { + auto &ReadMessage = + (InputStyle == Delimited) ? readDelimitedMessage : readStandardMessage; + while (In.good()) { + if (auto JSON = ReadMessage(In, Out)) { + if (auto Doc = json::parse(*JSON)) { // Log the formatted message. log(llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc)); // Finally, execute the action for this JSON message. @@ -270,17 +313,13 @@ log("JSON dispatch failed!\n"); } else { // Parse error. Log the raw message. - log("<-- " + JSONRef + "\n"); + log(llvm::formatv("<-- {0}\n" , *JSON)); log(llvm::Twine("JSON parse error: ") + llvm::toString(Doc.takeError()) + "\n"); } - - // If we're done, exit the loop. - if (IsDone) - break; - } else { - log("Warning: Missing Content-Length header, or message has zero " - "length.\n"); } + // If we're done, exit the loop. + if (IsDone) + break; } } Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp @@ -73,10 +73,25 @@ llvm::cl::init(clangd::CodeCompleteOptions().IncludeIneligibleResults), llvm::cl::Hidden); +static llvm::cl::opt InputStyle( + "input-style", llvm::cl::desc("Input JSON stream encoding"), + llvm::cl::values( + clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"), + clEnumValN(JSONStreamStyle::Delimited, "delimited", + "messages delimited by --- lines, with # comment support")), + llvm::cl::init(JSONStreamStyle::Standard)); + static llvm::cl::opt PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"), llvm::cl::init(false)); +static llvm::cl::opt Test( + "lit-test", + llvm::cl::desc( + "Abbreviation for -input-style=delimited -pretty -run-synchronously. " + "Intended to simplify lit tests."), + llvm::cl::init(false), llvm::cl::Hidden); + static llvm::cl::opt PCHStorage( "pch-storage", llvm::cl::desc("Storing PCHs in memory increases memory usages, but may " @@ -132,6 +147,11 @@ int main(int argc, char *argv[]) { llvm::cl::ParseCommandLineOptions(argc, argv, "clangd"); + if (Test) { + RunSynchronously = true; + InputStyle = JSONStreamStyle::Delimited; + PrettyPrint = true; + } if (!RunSynchronously && WorkerThreadsCount == 0) { llvm::errs() << "A number of worker threads cannot be 0. Did you mean to " @@ -228,5 +248,5 @@ EnableIndexBasedCompletion, StaticIdx.get()); constexpr int NoShutdownRequestErrorCode = 1; llvm::set_thread_name("clangd.main"); - return LSPServer.run(std::cin) ? 0 : NoShutdownRequestErrorCode; + return LSPServer.run(std::cin, InputStyle) ? 0 : NoShutdownRequestErrorCode; } Index: clang-tools-extra/trunk/test/clangd/completion.test =================================================================== --- clang-tools-extra/trunk/test/clangd/completion.test +++ clang-tools-extra/trunk/test/clangd/completion.test @@ -1,57 +1,44 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# RUN: clangd -pretty -run-synchronously -pch-storage=memory < %s | FileCheck -strict-whitespace %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: 186 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct S { int a; };\nint main() {\nS().\n}"}}} - -Content-Length: 148 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}} -# CHECK: "id": 1 -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "isIncomplete": false, -# CHECK-NEXT: "items": [ -# CHECK-NEXT: { -# CHECK-NEXT: "detail": "int", -# CHECK-NEXT: "filterText": "a", -# CHECK-NEXT: "insertText": "a", -# CHECK-NEXT: "insertTextFormat": 1, -# CHECK-NEXT: "kind": 5, -# CHECK-NEXT: "label": "a", -# CHECK-NEXT: "sortText": "{{.*}}a" -# CHECK-NEXT: }, -# CHECK: ] -# Update the source file and check for completions again. -Content-Length: 190 - -{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":2},"contentChanges":[{"text":"struct S { int b; };\nint main() {\nS().\n}"}]}} - -Content-Length: 148 - -{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}} -# CHECK: "id": 3, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "isIncomplete": false, -# CHECK-NEXT: "items": [ -# CHECK-NEXT: { -# CHECK-NEXT: "detail": "int", -# CHECK-NEXT: "filterText": "b", -# CHECK-NEXT: "insertText": "b", -# CHECK-NEXT: "insertTextFormat": 1, -# CHECK-NEXT: "kind": 5, -# CHECK-NEXT: "label": "b", -# CHECK-NEXT: "sortText": "{{.*}}b" -# CHECK-NEXT: }, -# CHECK: ] -Content-Length: 44 - -{"jsonrpc":"2.0","id":4,"method":"shutdown"} - +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct S { int a; };\nint main() {\nS().\n}"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}} +# CHECK: "id": 1 +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "a", +# CHECK-NEXT: "insertText": "a", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "a", +# CHECK-NEXT: "sortText": "{{.*}}a" +# CHECK-NEXT: }, +# CHECK: ] +--- +# Update the source file and check for completions again. +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":2},"contentChanges":[{"text":"struct S { int b; };\nint main() {\nS().\n}"}]}} +--- +{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":4}}} +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "b", +# CHECK-NEXT: "insertText": "b", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "b", +# CHECK-NEXT: "sortText": "{{.*}}b" +# CHECK-NEXT: }, +# CHECK: ] +--- +{"jsonrpc":"2.0","id":4,"method":"shutdown"} Index: clang-tools-extra/trunk/test/clangd/crash-non-added-files.test =================================================================== --- clang-tools-extra/trunk/test/clangd/crash-non-added-files.test +++ clang-tools-extra/trunk/test/clangd/crash-non-added-files.test @@ -1,45 +1,34 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 746 - -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32602 -# CHECK-NEXT: "message": "onCodeAction called for non-added file" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 2, -Content-Length: 233 - -{"jsonrpc":"2.0","id":3,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"file:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32602 -# CHECK-NEXT: "message": "onDocumentRangeFormatting called for non-added file" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 3, -Content-Length: 153 - -{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"file:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32602 -# CHECK-NEXT: "message": "onDocumentFormatting called for non-added file" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 4, -Content-Length: 204 - -{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"file:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32602 -# CHECK-NEXT: "message": "onDocumentOnTypeFormatting called for non-added file" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 5, -Content-Length: 44 - -{"jsonrpc":"2.0","id":6,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32602 +# CHECK-NEXT: "message": "onCodeAction called for non-added file" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 2, +--- +{"jsonrpc":"2.0","id":3,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"file:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32602 +# CHECK-NEXT: "message": "onDocumentRangeFormatting called for non-added file" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 3, +--- +{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"file:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32602 +# CHECK-NEXT: "message": "onDocumentFormatting called for non-added file" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 4, +--- +{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"file:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32602 +# CHECK-NEXT: "message": "onDocumentOnTypeFormatting called for non-added file" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 5, +--- +{"jsonrpc":"2.0","id":6,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/diagnostics.test =================================================================== --- clang-tools-extra/trunk/test/clangd/diagnostics.test +++ clang-tools-extra/trunk/test/clangd/diagnostics.test @@ -1,50 +1,42 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 152 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} -# CHECK: "method": "textDocument/publishDiagnostics", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "diagnostics": [ -# CHECK-NEXT: { -# CHECK-NEXT: "message": "return type of 'main' is not 'int'", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 0, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "change return type to 'int'", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 0, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" -# CHECK-NEXT: } -Content-Length: 44 - -{"jsonrpc":"2.0","id":5,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "return type of 'main' is not 'int'", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "change return type to 'int'", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/execute-command.test =================================================================== --- clang-tools-extra/trunk/test/clangd/execute-command.test +++ clang-tools-extra/trunk/test/clangd/execute-command.test @@ -1,112 +1,92 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 180 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}} -# CHECK: "method": "textDocument/publishDiagnostics", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "diagnostics": [ -# CHECK-NEXT: { -# CHECK-NEXT: "message": "using the result of an assignment as a condition without parentheses", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "place parentheses around the assignment to silence this warning", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "use '==' to turn this assignment into an equality comparison", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" -# CHECK-NEXT: } -Content-Length: 72 - -{"jsonrpc":"2.0","id":3,"method":"workspace/executeCommand","params":{}} -# No command name -Content-Length: 85 - -{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command": {}}} -# Invalid, non-scalar command name -Content-Length: 345 - -{"jsonrpc":"2.0","id":5,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} -Content-Length: 117 - -{"jsonrpc":"2.0","id":6,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":"foo"}} -# Arguments not a sequence. -Content-Length: 93 - -{"jsonrpc":"2.0","id":7,"method":"workspace/executeCommand","params":{"command":"mycommand"}} -# Unknown command. -Content-Length: 132 - -{"jsonrpc":"2.0","id":8,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[""]}} -# ApplyFix argument not a mapping node. -Content-Length: 345 - -{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} -# Custom field in WorkspaceEdit -Content-Length: 132 - -{"jsonrpc":"2.0","id":10,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":"foo"}]}} -# changes in WorkspaceEdit with no mapping node -Content-Length: 346 - -{"jsonrpc":"2.0","id":11,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}], "custom":"foo"}}]}} -# Custom field in WorkspaceEditChange -Content-Length: 150 - -{"jsonrpc":"2.0","id":12,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":"bar"}}]}} -# No sequence node for TextEdits -Content-Length: 149 - -{"jsonrpc":"2.0","id":13,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[""]}}]}} -# No mapping node for TextEdit -Content-Length: 265 - -{"jsonrpc":"2.0","id":14,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":"","newText":")"}]}}]}} -# TextEdit not decoded -Content-Length: 345 - -{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}],"command":"clangd.applyFix"}} -# Command name after arguments -Content-Length: 44 - -{"jsonrpc":"2.0","id":3,"method":"shutdown"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "place parentheses around the assignment to silence this warning", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "use '==' to turn this assignment into an equality comparison", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +# No command name +{"jsonrpc":"2.0","id":3,"method":"workspace/executeCommand","params":{}} +--- +# Invalid, non-scalar command name +{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command": {}}} +--- +{"jsonrpc":"2.0","id":5,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} +--- +# Arguments not a sequence. +{"jsonrpc":"2.0","id":6,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":"foo"}} +--- +# Unknown command. +{"jsonrpc":"2.0","id":7,"method":"workspace/executeCommand","params":{"command":"mycommand"}} +--- +# ApplyFix argument not a mapping node. +{"jsonrpc":"2.0","id":8,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","custom":"foo", "arguments":[""]}} +--- +# Custom field in WorkspaceEdit +{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} +--- +# changes in WorkspaceEdit with no mapping node +{"jsonrpc":"2.0","id":10,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":"foo"}]}} +--- +# Custom field in WorkspaceEditChange +{"jsonrpc":"2.0","id":11,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}], "custom":"foo"}}]}} +--- +# No sequence node for TextEdits +{"jsonrpc":"2.0","id":12,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":"bar"}}]}} +--- +# No mapping node for TextEdit +{"jsonrpc":"2.0","id":13,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[""]}}]}} +--- +# TextEdit not decoded +{"jsonrpc":"2.0","id":14,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":"","newText":")"}]}}]}} +--- +# Command name after arguments +{"jsonrpc":"2.0","id":9,"method":"workspace/executeCommand","params":{"arguments":[{"custom":"foo", "changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}],"command":"clangd.applyFix"}} +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} Index: clang-tools-extra/trunk/test/clangd/extra-flags.test =================================================================== --- clang-tools-extra/trunk/test/clangd/extra-flags.test +++ clang-tools-extra/trunk/test/clangd/extra-flags.test @@ -1,89 +1,80 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 205 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"},"metadata":{"extraFlags":["-Wall"]}}} -# CHECK: "method": "textDocument/publishDiagnostics", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "diagnostics": [ -# CHECK-NEXT: { -# CHECK-NEXT: "message": "variable 'i' is uninitialized when used here", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 28, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 27, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "initialize the variable 'i' to silence this warning", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 19, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 18, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" -# CHECK-NEXT: } -Content-Length: 175 - -{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":2},"contentChanges":[{"text":"int main() { int i; return i; }"}]}} -# CHECK: "method": "textDocument/publishDiagnostics", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "diagnostics": [ -# CHECK-NEXT: { -# CHECK-NEXT: "message": "variable 'i' is uninitialized when used here", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 28, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 27, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "initialize the variable 'i' to silence this warning", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 19, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 18, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" -# CHECK-NEXT: } -Content-Length: 44 - -{"jsonrpc":"2.0","id":5,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} - - +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"},"metadata":{"extraFlags":["-Wall"]}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "variable 'i' is uninitialized when used here", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 28, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 27, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "initialize the variable 'i' to silence this warning", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 19, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 18, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":2},"contentChanges":[{"text":"int main() { int i; return i; }"}]}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "variable 'i' is uninitialized when used here", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 28, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 27, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "initialize the variable 'i' to silence this warning", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 19, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 18, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} + + Index: clang-tools-extra/trunk/test/clangd/fixits.test =================================================================== --- clang-tools-extra/trunk/test/clangd/fixits.test +++ clang-tools-extra/trunk/test/clangd/fixits.test @@ -1,249 +1,238 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 180 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}} -# CHECK: "method": "textDocument/publishDiagnostics", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "diagnostics": [ -# CHECK-NEXT: { -# CHECK-NEXT: "message": "using the result of an assignment as a condition without parentheses", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "place parentheses around the assignment to silence this warning", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "message": "use '==' to turn this assignment into an equality comparison", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "severity": 3 -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" -# CHECK-NEXT: } -Content-Length: 746 - -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} -# CHECK: "id": 2, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "arguments": [ -# CHECK-NEXT: { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "file://{{.*}}/foo.c": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "(", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": ")", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "command": "clangd.applyFix", -# CHECK-NEXT: "title": "Apply FixIt place parentheses around the assignment to silence this warning" -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "arguments": [ -# CHECK-NEXT: { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "file://{{.*}}/foo.c": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "==", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "command": "clangd.applyFix", -# CHECK-NEXT: "title": "Apply FixIt use '==' to turn this assignment into an equality comparison" -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 771 - -{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"code":"1","source":"foo","message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} -# Make sure unused "code" and "source" fields ignored gracefully -# CHECK: "id": 3, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "arguments": [ -# CHECK-NEXT: { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "file://{{.*}}/foo.c": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "(", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": ")", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "command": "clangd.applyFix", -# CHECK-NEXT: "title": "Apply FixIt place parentheses around the assignment to silence this warning" -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "arguments": [ -# CHECK-NEXT: { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "file://{{.*}}/foo.c": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "==", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 35, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 34, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ], -# CHECK-NEXT: "command": "clangd.applyFix", -# CHECK-NEXT: "title": "Apply FixIt use '==' to turn this assignment into an equality comparison" -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 329 - -{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} -# CHECK: "id": 4, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": "Fix applied." -# -# CHECK: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "method": "workspace/applyEdit", -# CHECK-NEXT: "params": { -# CHECK-NEXT: "edit": { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "{{.*}}/foo.c": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "(", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 32, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": ")", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 37, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -Content-Length: 44 - -{"jsonrpc":"2.0","id":4,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main(int i, char **a) { if (i = 2) {}}"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "place parentheses around the assignment to silence this warning", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "message": "use '==' to turn this assignment into an equality comparison", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 3 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "arguments": [ +# CHECK-NEXT: { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "file://{{.*}}/foo.c": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "(", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": ")", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "command": "clangd.applyFix", +# CHECK-NEXT: "title": "Apply FixIt place parentheses around the assignment to silence this warning" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "arguments": [ +# CHECK-NEXT: { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "file://{{.*}}/foo.c": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "==", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "command": "clangd.applyFix", +# CHECK-NEXT: "title": "Apply FixIt use '==' to turn this assignment into an equality comparison" +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"code":"1","source":"foo","message":"using the result of an assignment as a condition without parentheses"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"place parentheses around the assignment to silence this warning"},{"range":{"start": {"line": 0, "character": 34}, "end": {"line": 0, "character": 35}},"severity":3,"message":"use '==' to turn this assignment into an equality comparison"}]}}} +# Make sure unused "code" and "source" fields ignored gracefully +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "arguments": [ +# CHECK-NEXT: { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "file://{{.*}}/foo.c": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "(", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": ")", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "command": "clangd.applyFix", +# CHECK-NEXT: "title": "Apply FixIt place parentheses around the assignment to silence this warning" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "arguments": [ +# CHECK-NEXT: { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "file://{{.*}}/foo.c": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "==", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 35, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 34, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "command": "clangd.applyFix", +# CHECK-NEXT: "title": "Apply FixIt use '==' to turn this assignment into an equality comparison" +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":4,"method":"workspace/executeCommand","params":{"command":"clangd.applyFix","arguments":[{"changes":{"test:///foo.c":[{"range":{"start":{"line":0,"character":32},"end":{"line":0,"character":32}},"newText":"("},{"range":{"start":{"line":0,"character":37},"end":{"line":0,"character":37}},"newText":")"}]}}]}} +# CHECK: "id": 4, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": "Fix applied." +# +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "method": "workspace/applyEdit", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "edit": { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "{{.*}}/foo.c": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "(", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 32, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": ")", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 37, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":4,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/formatting.test =================================================================== --- clang-tools-extra/trunk/test/clangd/formatting.test +++ clang-tools-extra/trunk/test/clangd/formatting.test @@ -1,207 +1,187 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 193 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int foo ( int x ) {\n x = x+1;\n return x;\n }"}}} -Content-Length: 233 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "\n ", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 19, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": " ", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": " ", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 10, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 10, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "\n ", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 2 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 12, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 197 - -{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n }"}]}} -# -# -Content-Length: 233 - -{"jsonrpc":"2.0","id":2,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":2},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "id": 2, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [] -Content-Length: 153 - -{"jsonrpc":"2.0","id":3,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "id": 3, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 8, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 7, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 10, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 16, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 15, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "\n", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 3 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 11, -# CHECK-NEXT: "line": 2 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 190 - -{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":9},"contentChanges":[{"text":"int foo(int x) {\n x = x + 1;\n return x;\n}"}]}} -# -# -Content-Length: 153 - -{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "id": 4, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [] -Content-Length: 193 - -{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n}"}]}} -# -# -Content-Length: 204 - -{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}} -# CHECK: "id": 5, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 8, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 7, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 10, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 16, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 15, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] - -Content-Length: 44 - -{"jsonrpc":"2.0","id":6,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int foo ( int x ) {\n x = x+1;\n return x;\n }"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":4},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "\n ", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 19, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": " ", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": " ", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "\n ", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 12, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n }"}]}} +# +# +--- +{"jsonrpc":"2.0","id":2,"method":"textDocument/rangeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":1,"character":2},"end":{"line":1,"character":12}},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [] +--- +{"jsonrpc":"2.0","id":3,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 8, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 7, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 16, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 15, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "\n", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 3 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 11, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":9},"contentChanges":[{"text":"int foo(int x) {\n x = x + 1;\n return x;\n}"}]}} +--- +{"jsonrpc":"2.0","id":4,"method":"textDocument/formatting","params":{"textDocument":{"uri":"test:///foo.c"},"options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "id": 4, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [] +--- +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///foo.c","version":5},"contentChanges":[{"text":"int foo ( int x ) {\n x = x + 1;\n return x;\n}"}]}} +--- +{"jsonrpc":"2.0","id":5,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"test:///foo.c"},"position":{"line":3,"character":1},"ch":"}","options":{"tabSize":4,"insertSpaces":true}}} +# CHECK: "id": 5, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 8, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 7, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 16, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 15, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":6,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test =================================================================== --- clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test +++ clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test @@ -1,49 +1,43 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# It is absolutely vital that this file has CRLF line endings. -# -# Test with invalid initialize request parameters -Content-Length: 142 - -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}} -# CHECK: "id": 0, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "capabilities": { -# CHECK-NEXT: "codeActionProvider": true, -# CHECK-NEXT: "completionProvider": { -# CHECK-NEXT: "resolveProvider": false, -# CHECK-NEXT: "triggerCharacters": [ -# CHECK-NEXT: ".", -# CHECK-NEXT: ">", -# CHECK-NEXT: ":" -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "definitionProvider": true, -# CHECK-NEXT: "documentFormattingProvider": true, -# CHECK-NEXT: "documentHighlightProvider": true, -# CHECK-NEXT: "documentOnTypeFormattingProvider": { -# CHECK-NEXT: "firstTriggerCharacter": "}", -# CHECK-NEXT: "moreTriggerCharacter": [] -# CHECK-NEXT: }, -# CHECK-NEXT: "documentRangeFormattingProvider": true, -# CHECK-NEXT: "executeCommandProvider": { -# CHECK-NEXT: "commands": [ -# CHECK-NEXT: "clangd.applyFix" -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "renameProvider": true, -# CHECK-NEXT: "signatureHelpProvider": { -# CHECK-NEXT: "triggerCharacters": [ -# CHECK-NEXT: "(", -# CHECK-NEXT: "," -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "textDocumentSync": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -Content-Length: 44 - -{"jsonrpc":"2.0","id":3,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# Test with invalid initialize request parameters +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}} +# CHECK: "id": 0, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "capabilities": { +# CHECK-NEXT: "codeActionProvider": true, +# CHECK-NEXT: "completionProvider": { +# CHECK-NEXT: "resolveProvider": false, +# CHECK-NEXT: "triggerCharacters": [ +# CHECK-NEXT: ".", +# CHECK-NEXT: ">", +# CHECK-NEXT: ":" +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "definitionProvider": true, +# CHECK-NEXT: "documentFormattingProvider": true, +# CHECK-NEXT: "documentHighlightProvider": true, +# CHECK-NEXT: "documentOnTypeFormattingProvider": { +# CHECK-NEXT: "firstTriggerCharacter": "}", +# CHECK-NEXT: "moreTriggerCharacter": [] +# CHECK-NEXT: }, +# CHECK-NEXT: "documentRangeFormattingProvider": true, +# CHECK-NEXT: "executeCommandProvider": { +# CHECK-NEXT: "commands": [ +# CHECK-NEXT: "clangd.applyFix" +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "renameProvider": true, +# CHECK-NEXT: "signatureHelpProvider": { +# CHECK-NEXT: "triggerCharacters": [ +# CHECK-NEXT: "(", +# CHECK-NEXT: "," +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "textDocumentSync": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/initialize-params.test =================================================================== --- clang-tools-extra/trunk/test/clangd/initialize-params.test +++ clang-tools-extra/trunk/test/clangd/initialize-params.test @@ -1,52 +1,46 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# It is absolutely vital that this file has CRLF line endings. -# -# Test initialize request parameters with rootUri -Content-Length: 143 - -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}} -# CHECK: "id": 0, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "capabilities": { -# CHECK-NEXT: "codeActionProvider": true, -# CHECK-NEXT: "completionProvider": { -# CHECK-NEXT: "resolveProvider": false, -# CHECK-NEXT: "triggerCharacters": [ -# CHECK-NEXT: ".", -# CHECK-NEXT: ">", -# CHECK-NEXT: ":" -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "definitionProvider": true, -# CHECK-NEXT: "documentFormattingProvider": true, -# CHECK-NEXT: "documentHighlightProvider": true, -# CHECK-NEXT: "documentOnTypeFormattingProvider": { -# CHECK-NEXT: "firstTriggerCharacter": "}", -# CHECK-NEXT: "moreTriggerCharacter": [] -# CHECK-NEXT: }, -# CHECK-NEXT: "documentRangeFormattingProvider": true, -# CHECK-NEXT: "executeCommandProvider": { -# CHECK-NEXT: "commands": [ -# CHECK-NEXT: "clangd.applyFix" -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "renameProvider": true, -# CHECK-NEXT: "signatureHelpProvider": { -# CHECK-NEXT: "triggerCharacters": [ -# CHECK-NEXT: "(", -# CHECK-NEXT: "," -# CHECK-NEXT: ] -# CHECK-NEXT: }, -# CHECK-NEXT: "textDocumentSync": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -Content-Length: 44 - -{"jsonrpc":"2.0","id":3,"method":"shutdown"} -# CHECK: "id": 3, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": null -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# Test initialize request parameters with rootUri +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}} +# CHECK: "id": 0, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "capabilities": { +# CHECK-NEXT: "codeActionProvider": true, +# CHECK-NEXT: "completionProvider": { +# CHECK-NEXT: "resolveProvider": false, +# CHECK-NEXT: "triggerCharacters": [ +# CHECK-NEXT: ".", +# CHECK-NEXT: ">", +# CHECK-NEXT: ":" +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "definitionProvider": true, +# CHECK-NEXT: "documentFormattingProvider": true, +# CHECK-NEXT: "documentHighlightProvider": true, +# CHECK-NEXT: "documentOnTypeFormattingProvider": { +# CHECK-NEXT: "firstTriggerCharacter": "}", +# CHECK-NEXT: "moreTriggerCharacter": [] +# CHECK-NEXT: }, +# CHECK-NEXT: "documentRangeFormattingProvider": true, +# CHECK-NEXT: "executeCommandProvider": { +# CHECK-NEXT: "commands": [ +# CHECK-NEXT: "clangd.applyFix" +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "renameProvider": true, +# CHECK-NEXT: "signatureHelpProvider": { +# CHECK-NEXT: "triggerCharacters": [ +# CHECK-NEXT: "(", +# CHECK-NEXT: "," +# CHECK-NEXT: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "textDocumentSync": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": null +--- +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/rename.test =================================================================== --- clang-tools-extra/trunk/test/clangd/rename.test +++ clang-tools-extra/trunk/test/clangd/rename.test @@ -1,50 +1,39 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 150 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","version":1,"text":"int foo;"}}} - -Content-Length: 159 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":5},"newName":"bar"}} -# CHECK: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "changes": { -# CHECK-NEXT: "file://{{.*}}/foo.cpp": [ -# CHECK-NEXT: { -# CHECK-NEXT: "newText": "bar", -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 7 -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 4 -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: } -Content-Length: 159 - -{"jsonrpc":"2.0","id":2,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":2},"newName":"bar"}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32603, -# CHECK-NEXT: "message": "clang diagnostic" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 2, -# CHECK-NEXT: "jsonrpc": "2.0" -Content-Length: 44 - -{"jsonrpc":"2.0","id":3,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","version":1,"text":"int foo;"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":5},"newName":"bar"}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "changes": { +# CHECK-NEXT: "file://{{.*}}/foo.cpp": [ +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "bar", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 7 +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 4 +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":2,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":2},"newName":"bar"}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32603, +# CHECK-NEXT: "message": "clang diagnostic" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0" +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test =================================================================== --- clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test +++ clang-tools-extra/trunk/test/clangd/shutdown-with-exit.test @@ -1,9 +1,4 @@ -# RUN: clangd -run-synchronously < %s -# vim: fileformat=dos -# It is absolutely vital that this file has CRLF line endings. -Content-Length: 44 - -{"jsonrpc":"2.0","id":3,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: clangd -lit-test < %s +{"jsonrpc":"2.0","id":3,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test =================================================================== --- clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test +++ clang-tools-extra/trunk/test/clangd/shutdown-without-exit.test @@ -1,6 +1,2 @@ -# RUN: not clangd -run-synchronously < %s -# vim: fileformat=dos -# It is absolutely vital that this file has CRLF line endings. -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: not clangd -lit-test < %s +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/signature-help.test =================================================================== --- clang-tools-extra/trunk/test/clangd/signature-help.test +++ clang-tools-extra/trunk/test/clangd/signature-help.test @@ -1,37 +1,25 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# It is absolutely vital that this file has CRLF line endings. - -# Start a session. -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":"test:///main.cpp","languageId":"cpp","version":1,"text":"void x(int);\nint main(){\nx("}}} - -Content-Length: 151 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":2}}} -# CHECK: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": { -# CHECK-NEXT: "activeParameter": 0, -# CHECK-NEXT: "activeSignature": 0, -# CHECK-NEXT: "signatures": [ -# CHECK-NEXT: { -# CHECK-NEXT: "label": "x(int) -> void", -# CHECK-NEXT: "parameters": [ -# CHECK-NEXT: { -# CHECK-NEXT: "label": "int" -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK-NEXT: } - -# Shutdown. -Content-Length: 49 - -{"jsonrpc":"2.0","id":100000,"method":"shutdown"} -Content-Length: 33 +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# Start a session. +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void x(int);\nint main(){\nx("}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":2}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "activeParameter": 0, +# CHECK-NEXT: "activeSignature": 0, +# CHECK-NEXT: "signatures": [ +# CHECK-NEXT: { +# CHECK-NEXT: "label": "x(int) -> void", +# CHECK-NEXT: "parameters": [ +# CHECK-NEXT: { +# CHECK-NEXT: "label": "int" +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":100000,"method":"shutdown"} Index: clang-tools-extra/trunk/test/clangd/test-uri-posix.test =================================================================== --- clang-tools-extra/trunk/test/clangd/test-uri-posix.test +++ clang-tools-extra/trunk/test/clangd/test-uri-posix.test @@ -1,19 +1,11 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# UNSUPPORTED: mingw32,win32 -# It is absolutely vital that this file has CRLF line endings. -# -# Test authority-less URI -Content-Length: 125 - -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} -# -Content-Length: 152 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} -# CHECK: "uri": "file:///clangd-test/foo.c" -Content-Length: 44 - -{"jsonrpc":"2.0","id":5,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# UNSUPPORTED: mingw32,win32 +# Test authority-less URI +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} +# CHECK: "uri": "file:///clangd-test/foo.c" +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/test-uri-windows.test =================================================================== --- clang-tools-extra/trunk/test/clangd/test-uri-windows.test +++ clang-tools-extra/trunk/test/clangd/test-uri-windows.test @@ -1,19 +1,11 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# REQUIRES: mingw32 || win32 -# It is absolutely vital that this file has CRLF line endings. -# -# Test authority-less URI -Content-Length: 125 - -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} -# -Content-Length: 152 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} -# CHECK: "uri": "file:///C:/clangd-test/foo.c" -Content-Length: 44 - -{"jsonrpc":"2.0","id":5,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0","method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# REQUIRES: mingw32 || win32 +# Test authority-less URI +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} +# CHECK: "uri": "file:///C:/clangd-test/foo.c" +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/trunk/test/clangd/trace.test =================================================================== --- clang-tools-extra/trunk/test/clangd/trace.test +++ clang-tools-extra/trunk/test/clangd/trace.test @@ -1,26 +1,19 @@ -# RUN: clangd -pretty -run-synchronously -trace %t < %s && FileCheck %s < %t -# 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: 152 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} -# CHECK: {"displayTimeUnit":"ns","traceEvents":[ -# Start opening the doc. -# CHECK: "name": "textDocument/didOpen" -# CHECK: "ph": "B" -# Start building the preamble. -# CHECK: "name": "Preamble" -# CHECK: }, -# Finish building the preamble, with filename. -# CHECK: "File": "{{.*}}/foo.c" -# CHECK-NEXT: }, -# CHECK-NEXT: "ph": "E" -# Start building the file. -# CHECK: "name": "Build" -Content-Length: 44 - -{"jsonrpc":"2.0","id":5,"method":"shutdown"} +# RUN: clangd -lit-test -trace %t < %s && FileCheck %s < %t +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}} +# CHECK: {"displayTimeUnit":"ns","traceEvents":[ +# Start opening the doc. +# CHECK: "name": "textDocument/didOpen" +# CHECK: "ph": "B" +# Start building the preamble. +# CHECK: "name": "Preamble" +# CHECK: }, +# Finish building the preamble, with filename. +# CHECK: "File": "{{.*}}/foo.c" +# CHECK-NEXT: }, +# CHECK-NEXT: "ph": "E" +# Start building the file. +# CHECK: "name": "Build" +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} Index: clang-tools-extra/trunk/test/clangd/unsupported-method.test =================================================================== --- clang-tools-extra/trunk/test/clangd/unsupported-method.test +++ clang-tools-extra/trunk/test/clangd/unsupported-method.test @@ -1,27 +1,16 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 143 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":""}}} - -Content-Length: 92 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/jumpInTheAirLikeYouJustDontCare","params":{}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32601, -# CHECK-NEXT: "message": "method not found" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0" - -Content-Length: 44 - -{"jsonrpc":"2.0","id":2,"method":"shutdown"} -Content-Length: 33 - -{"jsonrpc":"2.0":"method":"exit"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":""}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/jumpInTheAirLikeYouJustDontCare","params":{}} +# CHECK: "error": { +# CHECK-NEXT: "code": -32601, +# CHECK-NEXT: "message": "method not found" +# CHECK-NEXT: }, +# CHECK-NEXT: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0" +--- +{"jsonrpc":"2.0","id":2,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} Index: clang-tools-extra/trunk/test/clangd/xrefs.test =================================================================== --- clang-tools-extra/trunk/test/clangd/xrefs.test +++ clang-tools-extra/trunk/test/clangd/xrefs.test @@ -1,67 +1,57 @@ -# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %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: 165 - -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x = 0;\nint y = x;"}}} - -Content-Length: 148 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} -# CHECK: "id": 1, -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 0, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: "uri": "file://{{.*}}/{{([A-Z]:/)?}}main.cpp" -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 155 - -{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} -# CHECK: "id": 1 -# CHECK-NEXT: "jsonrpc": "2.0", -# CHECK-NEXT: "result": [ -# CHECK-NEXT: { -# CHECK-NEXT: "kind": 1, -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 5, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 4, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: }, -# CHECK-NEXT: { -# CHECK-NEXT: "kind": 2, -# CHECK-NEXT: "range": { -# CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: }, -# CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 8, -# CHECK-NEXT: "line": 1 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -Content-Length: 48 - -{"jsonrpc":"2.0","id":10000,"method":"shutdown"} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x = 0;\nint y = x;"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file://{{.*}}/{{([A-Z]:/)?}}main.cpp" +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} +# CHECK: "id": 1 +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "kind": 1, +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 5, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 8, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":10000,"method":"shutdown"}