summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [clangd] Lay JSONRPCDispatcher to rest.Sam McCall2018-10-181-208/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Most of its functionality is moved into ClangdLSPServer. The decoupling between JSONRPCDispatcher, ProtocolCallbacks, ClangdLSPServer was never real, and only served to obfuscate. Some previous implicit/magic stuff is now explicit: - the return type of LSP method calls are now in the signature - no more reply() that gets the ID using global context magic - arg tracing no longer relies on RequestArgs::stash context magic either This is mostly refactoring, but some deliberate fixes while here: - LSP method params are now by const reference - notifications and calls are now distinct namespaces. (some tests had protocol errors and needed updating) - we now reply to calls we failed to decode - outgoing calls use distinct IDs A few error codes and message IDs changed in unimportant ways (see tests). Reviewers: ioeric Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D53387 llvm-svn: 344737
* [clangd] Hide unused function. NFCSam McCall2018-10-171-6/+2
| | | | llvm-svn: 344676
* [clangd] Rename and move trivial logger to Logger.cpp. NFCSam McCall2018-10-171-14/+0
| | | | llvm-svn: 344675
* [clangd] Refactor JSON-over-stdin/stdout code into Transport abstraction. ↵Sam McCall2018-10-171-252/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | (re-land r344620) Summary: This paves the way for alternative transports (mac XPC, maybe messagepack?), and also generally improves layering: testing ClangdLSPServer becomes less of a pipe dream, we split up the JSONOutput monolith, etc. This isn't a final state, much of what remains in JSONRPCDispatcher can go away, handlers can call reply() on the transport directly, JSONOutput can be renamed to StreamLogger and removed, etc. But this patch is sprawling already. The main observable change (see tests) is that hitting EOF on input is now an error: the client should send the 'exit' notification. This is defensible: the protocol doesn't spell this case out. Reproducing the current behavior for all combinations of shutdown/exit/EOF clutters interfaces. We can iterate on this if desired. Reviewers: jkorous, ioeric, hokein Subscribers: mgorny, ilya-biryukov, MaskRay, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D53286 llvm-svn: 344672
* Revert "[clangd] Refactor JSON-over-stdin/stdout code into Transport ↵Krasimir Georgiev2018-10-161-49/+252
| | | | | | | | | abstraction." This reverts commit r344620. Breaks upstream bots. llvm-svn: 344637
* [clangd] Refactor JSON-over-stdin/stdout code into Transport abstraction.Sam McCall2018-10-161-252/+49
| | | | | | | | | | | | | | | | | | | | | | | | | Summary: This paves the way for alternative transports (mac XPC, maybe messagepack?), and also generally improves layering: testing ClangdLSPServer becomes less of a pipe dream, we split up the JSONOutput monolith, etc. This isn't a final state, much of what remains in JSONRPCDispatcher can go away, handlers can call reply() on the transport directly, JSONOutput can be renamed to StreamLogger and removed, etc. But this patch is sprawling already. The main observable change (see tests) is that hitting EOF on input is now an error: the client should send the 'exit' notification. This is defensible: the protocol doesn't spell this case out. Reproducing the current behavior for all combinations of shutdown/exit/EOF clutters interfaces. We can iterate on this if desired. Reviewers: jkorous, ioeric, hokein Subscribers: mgorny, ilya-biryukov, MaskRay, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D53286 llvm-svn: 344620
* [clangd] Allow all LSP methods to signal cancellation via $/cancelRequestSam McCall2018-09-131-2/+48
| | | | | | | | | | | | | | | | | | | | | | | | | Summary: The cancelable scopes are managed by JSONRPCDispatcher so that all Handlers run in cancelable contexts. (Previously ClangdServer did this, for code completion only). Cancellation request processing is therefore also in JSONRPCDispatcher. (Previously it was in ClangdLSPServer). This doesn't actually make any new commands *respect* cancellation - they'd need to check isCancelled() and bail out. But it opens the door to doing this incrementally, and putting such logic in common machinery like TUScheduler. I also rewrote the ClangdServer class/threading comments because I wanted to add to it and I got carried away. Reviewers: ilya-biryukov, kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D52004 llvm-svn: 342135
* [clangd] Fix typo. NFCFangrui Song2018-09-051-1/+1
| | | | llvm-svn: 341452
* [clangd] Initial cancellation mechanism for LSP requests.Kadir Cetinkaya2018-08-241-2/+17
| | | | | | | | | | | | Reviewers: ilya-biryukov, ioeric, hokein Reviewed By: ilya-biryukov Subscribers: mgorny, ioeric, MaskRay, jkorous, arphaman, jfb, cfe-commits Differential Revision: https://reviews.llvm.org/D50502 llvm-svn: 340607
* [clangd] Fix (most) naming warnings from clang-tidy. NFCIlya Biryukov2018-07-261-4/+4
| | | | llvm-svn: 338021
* [clangd] log request/response messages with method/ID/error at INFO levelSam McCall2018-07-121-8/+29
| | | | | | | | | | | | Summary: Bodies are logged at VERBOSE level (since r336785), tweak the formatting. Reviewers: hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, cfe-commits Differential Revision: https://reviews.llvm.org/D49224 llvm-svn: 336899
* [clangd] Upgrade logging facilities with levels and formatv.Sam McCall2018-07-111-19/+24
| | | | | | | | | | | | | | | | | | | | | | Summary: log() is split into four functions: - elog()/log()/vlog() have different severity levels, allowing filtering - dlog() is a lazy macro which uses LLVM_DEBUG - it logs to the logger, but conditionally based on -debug-only flag and is omitted in release builds All logging functions use formatv-style format strings now, e.g: log("Could not resolve URI {0}: {1}", URI, Result.takeError()); Existing log sites have been split between elog/log/vlog by best guess. This includes a workaround for passing Error to formatv that can be simplified when D49170 or similar lands. Subscribers: ilya-biryukov, javed.absar, ioeric, MaskRay, jkorous, cfe-commits Differential Revision: https://reviews.llvm.org/D49008 llvm-svn: 336785
* [clangd] Remove JSON library in favor of llvm/Support/JSONSam McCall2018-07-091-23/+25
| | | | | | | | | | | | | | | | | | | | Summary: The library has graduated from clangd to llvm/Support. This is a mechanical change to move to the new API and remove the old one. Main API changes: - namespace clang::clangd::json --> llvm::json - json::Expr --> json::Value - Expr::asString() etc --> Value::getAsString() etc - unsigned longs need a cast (due to r336541 adding lossless integer support) Reviewers: ilya-biryukov Subscribers: mgorny, ioeric, MaskRay, jkorous, omtcyfz, cfe-commits Differential Revision: https://reviews.llvm.org/D49077 llvm-svn: 336549
* [clangd] Rewrite JSON dispatcher loop using C IO (FILE*) instead of ↵Sam McCall2018-06-051-57/+75
| | | | | | | | | | | | | | | | | | | | | | | | std::istream. Summary: The EINTR loop around getline was added to fix an issue with mac gdb, but seems to loop infinitely in rare cases on linux where the parent editor exits (most reports with VSCode). I can't work out how to fix this in a portable way with std::istream, but the C APIs have clearer contracts and LLVM has a RetryAfterSignal function for use with them which seems battle-tested. While here, clean up some inconsistency around \n in log messages (now add it only after JSON payloads), and reduce the scope of the long-message handling which was only really added to fight fuzzers. Reviewers: malaperle, ilya-biryukov Subscribers: klimek, ioeric, jkorous, cfe-commits Differential Revision: https://reviews.llvm.org/D47643 llvm-svn: 333993
* [clangd][tests] Fix delimiter handlingJan Korous2018-04-231-1/+1
| | | | | | | | Empty line shouldn't be considered a delimiter Differential Revision: https://reviews.llvm.org/D45764 llvm-svn: 330609
* [clangd][tests] Fix handling of EOF in delimited inputJan Korous2018-04-231-9/+7
| | | | | | | | Request in delimited input ended by EOF shouldn't be an error state. Comments at the end of test file shouldn't be logged as an error state. Input mirroring should work for the last request in delimited test file. llvm-svn: 330608
* [clangd][nfc] Simplify readDelimitedMessage()Jan Korous2018-04-121-3/+3
| | | | | | istream::eof() is always false after successful getline() llvm-svn: 329958
* [clangd] Include timestamps in log messages.Sam McCall2018-02-161-9/+9
| | | | llvm-svn: 325357
* [clangd] Remove unused variable. NFCEric Liu2018-02-061-1/+0
| | | | llvm-svn: 324354
* [clangd] Support simpler JSON-RPC stream parsing for lit tests.Sam McCall2018-02-061-82/+121
| | | | | | | | | | | | | | Summary: Instead of content-length, we delimit messages with ---. This also removes the need for (most) dos-formatted test files. Reviewers: ioeric Subscribers: klimek, ilya-biryukov, jkorous-apple, cfe-commits Differential Revision: https://reviews.llvm.org/D42919 llvm-svn: 324333
* [clangd] Pass Context implicitly using TLS.Sam McCall2018-01-311-42/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Instead of passing Context explicitly around, we now have a thread-local Context object `Context::current()` which is an implicit argument to every function. Most manipulation of this should use the WithContextValue helper, which augments the current Context to add a single KV pair, and restores the old context on destruction. Advantages are: - less boilerplate in functions that just propagate contexts - reading most code doesn't require understanding context at all, and using context as values in fewer places still - fewer options to pass the "wrong" context when it changes within a scope (e.g. when using Span) - contexts pass through interfaces we can't modify, such as VFS - propagating contexts across threads was slightly tricky (e.g. copy vs move, no move-init in lambdas), and is now encapsulated in the threadpool Disadvantages are all the usual TLS stuff - hidden magic, and potential for higher memory usage on threads that don't use the context. (In practice, it's just one pointer) Reviewers: ilya-biryukov Subscribers: klimek, jkorous-apple, ioeric, cfe-commits Differential Revision: https://reviews.llvm.org/D42517 llvm-svn: 323872
* [clangd] Fix GCC build break 'declaration changes meaning'Sam McCall2018-01-261-4/+4
| | | | llvm-svn: 323518
* [clangd] Modify the Span API so that Spans propagate with contexts.Sam McCall2018-01-261-17/+40
| | | | | | | | | | | | | | | | | | | | | | | | Summary: This is probably the right behavior for distributed tracers, and makes unpaired begin-end events impossible without requiring Spans to be bound to a thread. The API is conceptually clean but syntactically awkward. As discussed offline, this is basically a naming problem and will go away if (when) we use TLS to store the current context. The apparently-unrelated change to onScopeExit are because its move semantics broken if Func is POD-like since r322838. This is true of function pointers, and the lambda I use here that captures two pointers only. I've raised this issue on llvm-dev and will revert this part if we fix it in some other way. Reviewers: ilya-biryukov Subscribers: klimek, jkorous-apple, ioeric, cfe-commits Differential Revision: https://reviews.llvm.org/D42499 llvm-svn: 323511
* Avoid int to string conversion in Twine or raw_ostream contexts.Benjamin Kramer2017-12-281-5/+4
| | | | | | Some output changes from uppercase hex to lowercase hex, no other functionality change intended. llvm-svn: 321526
* [clangd] Implemented tracing using ContextIlya Biryukov2017-12-141-7/+10
| | | | | | | | | | | | Reviewers: sammccall, ioeric, hokein Reviewed By: sammccall Subscribers: klimek, luckygeck, cfe-commits Differential Revision: https://reviews.llvm.org/D40488 llvm-svn: 320706
* [clangd] Implemented logging using ContextIlya Biryukov2017-12-131-48/+78
| | | | | | | | | | | | Reviewers: sammccall, ioeric, hokein Reviewed By: sammccall Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D40486 llvm-svn: 320576
* [clangd] Logger implicitly adds newlineSam McCall2017-11-301-11/+11
| | | | llvm-svn: 319497
* [clangd] Switch from YAMLParser to JSONExprSam McCall2017-11-281-88/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: - Converted Protocol.h parse() functions to take JSON::Expr. These no longer detect and log unknown fields, as this is not that useful and no longer free. I haven't changed the error handling too much: fields that were treated as optional before are still optional, even when it's wrong. Exception: object properties with the wrong type are now ignored. - Made JSONRPCDispatcher parse using json::parse - The bug where 'method' must come before 'params' in the stream is fixed as a side-effect. (And the same bug in executeCommand). - Some parser crashers fixed as a side effect. e.g. https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3890 - The debug stream now prettyprints the input messages with --pretty. - Request params are attached to traces when tracing is enabled. - Fixed some bugs in tests (errors tolerated by YAMLParser, and off-by-ones in Content-Length that our null-termination was masking) - Fixed a random double-escape bug in ClangdLSPServer (it was our last use of YAMLParser!) Reviewers: ilya-biryukov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D40406 llvm-svn: 319159
* [clangd] Tracing improvementsSam McCall2017-11-231-3/+7
| | | | | | | | | | | | | | | | | | | | Summary: [clangd] Tracing improvements Compose JSON using JSONExpr Allow attaching metadata to spans (and avoid it if tracing is off) Attach IDs and responses of JSON RPCs to their spans The downside is that large responses make the trace viewer sluggish. We should make our responses less huge :-) Or fix trace viewer. Reviewers: ilya-biryukov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D40132 llvm-svn: 318928
* [clangd] clang-format the source code. NFC.Ilya Biryukov2017-11-151-2/+4
| | | | llvm-svn: 318317
* [clangd] don't crash on invalid JSON-RPC IDSam McCall2017-11-071-1/+3
| | | | llvm-svn: 317580
* [clangd] Add ErrorCode enum class.Haojian Wu2017-11-071-3/+3
| | | | | | | | | | | | | | Summary: Avoid using magic number in the code everywhere. Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, cfe-commits Differential Revision: https://reviews.llvm.org/D39718 llvm-svn: 317559
* Adds a json::Expr type to represent intermediate JSON expressions.Sam McCall2017-11-061-23/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This form can be created with a nice clang-format-friendly literal syntax, and gets escaping right. It knows how to call unparse() on our Protocol types. All the places where we pass around JSON internally now use this type. Object properties are sorted (stored as std::map) and so serialization is canonicalized, with optional prettyprinting (triggered by a -pretty flag). This makes the lit tests much nicer to read and somewhat nicer to debug. (Unfortunately the completion tests use CHECK-DAG, which only has line-granularity, so pretty-printing is disabled there. In future we could make completion ordering deterministic, or switch to unittests). Compared to the current approach, it has some efficiencies like avoiding copies of string literals used as object keys, but is probably slower overall. I think the code/test quality benefits are worth it. This patch doesn't attempt to do anything about JSON *parsing*. It takes direction from the proposal in this doc[1], but is limited in scope and visibility, for now. I am of half a mind just to use Expr as the target of a parser, and maybe do a little string deduplication, but not bother with clever memory allocation. That would be simple, and fast enough for clangd... [1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit +cc d0k so he can tell me not to use std::map. Reviewers: ioeric, malaperle Subscribers: bkramer, ilya-biryukov, mgorny, klimek Differential Revision: https://reviews.llvm.org/D39435 llvm-svn: 317486
* [clangd] Handle clangd.applyFix server-sideMarc-Andre Laperle2017-11-031-0/+7
| | | | | | | | | | | | | | | | | | | | | | | Summary: When the user selects a fix-it (or any code action with commands), it is possible to let the client forward the selected command to the server. When the clangd.applyFix command is handled on the server, it can send a workspace/applyEdit request to the client. This has the advantage that the client doesn't explicitly have to know how to handle clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS Code extension (and any other Clangd client) is not required anymore. Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein Reviewed By: hokein Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D39276 llvm-svn: 317322
* Performance tracing facility for clangd.Sam McCall2017-11-021-13/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This lets you visualize clangd's activity on different threads over time, and understand critical paths of requests and object lifetimes. The data produced can be visualized in Chrome (at chrome://tracing), or in a standalone copy of catapult (http://github.com/catapult-project/catapult) This patch consists of: - a command line flag "-trace" that causes clangd to emit JSON trace data - an API (in Trace.h) allowing clangd code to easily add events to the stream - several initial uses of this API to capture JSON-RPC requests, builds, logs Example result: https://photos.app.goo.gl/12L9swaz5REGQ1rm1 Caveats: - JSON serialization is ad-hoc (isn't it everywhere?) so the API is limited to naming events rather than attaching arbitrary metadata. I'd like to fix this (I think we could use a JSON-object abstraction). - The recording is very naive: events are written immediately by locking a mutex. Contention on the mutex might disturb performance. - For now it just traces instants or spans on the current thread. There are other things that make sense to show (cross-thread flows, non-thread resources such as ASTs). But we have to start somewhere. Reviewers: ioeric, ilya-biryukov Subscribers: cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D39086 llvm-svn: 317193
* [clangd] Don't crash on extremely large JSON messages.Benjamin Kramer2017-10-271-0/+9
| | | | | | Found by clangd-fuzzer. llvm-svn: 316774
* [clangd] Harden clangd a bit against garbage input.Benjamin Kramer2017-10-271-6/+3
| | | | | | | There can be nullptrs here if the YAML fails to parse. Found by clangd-fuzzer! llvm-svn: 316770
* [clangd] less boilerplate in RPC dispatchSam McCall2017-10-121-22/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Make the ProtocolHandlers glue between JSONRPCDispatcher and ClangdLSPServer generic. Eliminate small differences between methods, de-emphasize the unimportant distinction between notifications and methods. ClangdLSPServer is no longer responsible for producing a complete JSON-RPC response, just the JSON of the result object. (In future, we should move that JSON serialization out, too). Handler methods now take a context object that we may hang more functionality off in the future. Added documentation to ProtocolHandlers. Reviewers: ilya-biryukov, bkramer Reviewed By: ilya-biryukov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D38464 llvm-svn: 315577
* Revert "Revert r315214 since diff -Z isn't portable, this is breaking:"Ilya Biryukov2017-10-101-10/+23
| | | | | | | | | This reverts commit r315242 and restores r315214. To fix original failure, replaced non-portable `diff -Z` with portable alternative: `diff -b`. llvm-svn: 315287
* Revert r315214 since diff -Z isn't portable, this is breaking:Bruno Cardoso Lopes2017-10-091-23/+10
| | | | | | | http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-expensive http://green.lab.llvm.org/green/job/clang-stage1-configure-RA llvm-svn: 315242
* [clangd] Added a command-line arg to mirror clangd input into a file.Ilya Biryukov2017-10-091-10/+23
| | | | | | | | | | | | | | Summary: The arg is useful for debugging and creating test cases. Reviewers: bkramer, krasimir Reviewed By: bkramer Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D37970 llvm-svn: 315214
* [clangd] Fix missing "message" key when responding with unsupported methodBenjamin Kramer2017-09-251-1/+1
| | | | | | | | | | | | | | The language server protocol dictates that a ResponseError should have a [message string][1] describing the error. This adds a simple message to the error and a simple test. [1]: https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#response-message Patch by Raoul Wols! Differential Revision: https://reviews.llvm.org/D38225 llvm-svn: 314119
* clangd: Tolerate additional headersIlya Biryukov2017-09-041-38/+63
| | | | | | | | | | | | | | | | | | Summary: The language server protocol specified 2 headers (Content-Length and Content-Type), but does not specify their sequence. It specifies that an empty line ends headers. Clangd has been updated to handle arbitrary sequences of headers, extracting only the content length. Patch by puremourning (Ben Jackson). Reviewers: bkramer, klimek, ilya-biryukov Reviewed By: ilya-biryukov Subscribers: cfe-commits, ilya-biryukov Differential Revision: https://reviews.llvm.org/D37282 llvm-svn: 312483
* Added missing includes in clangd to fix the build.Ilya Biryukov2017-05-161-0/+2
| | | | | | This commit should fix buildbot failures. llvm-svn: 303177
* [clangd] Refactor ProtocolHandlers to decouple them from ClangdLSPServerIlya Biryukov2017-05-161-0/+58
| | | | | | | | | | | | | | | | | | | | | | | | Summary: A refactoring to decouple ProtocolHandlers and Language Server input parsing loop from the ClangdLSPServer. The input parsing was extracted from `main` to a function(runLanguageServerLoop). ProtocolHandlers now provide an interface to handle various LSP methods, this interface is used by ClangdLSPServer. Methods for code formatting were moved from ProtocolHandlers to ClangdServer. ClangdLSPServer now provides a cleaner interface that only runs Language Server input loop. Reviewers: bkramer, krasimir Reviewed By: krasimir Subscribers: cfe-commits, klimek Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D33201 llvm-svn: 303173
* [clangd] Synchronize logs access.Benjamin Kramer2017-02-151-2/+8
| | | | | | | I don't think that this is necessary for correctness, but makes tsan much more useful. llvm-svn: 295194
* [clangd] Refactor stream output into a single thread-safe output object.Benjamin Kramer2017-02-101-3/+4
| | | | | | | This abstracts away the passing of raw_ostreams everywhere, thread safety will be used soon. llvm-svn: 294747
* Add a prototype for clangdBenjamin Kramer2017-02-071-0/+124
clangd is a language server protocol implementation based on clang. It's supposed to provide editor integration while not suffering from the confined ABI of libclang. This implementation is limited to the bare minimum functionality of doing (whole-document) formatting and rangeFormatting. The JSON parsing is based on LLVM's YAMLParser but yet most of the code of clangd is currently dealing with JSON serialization and deserialization. This was only tested with VS Code so far, mileage with other LSP clients may vary. Differential Revision: https://reviews.llvm.org/D29451 llvm-svn: 294291
OpenPOWER on IntegriCloud