This revision was automatically updated to reflect the committed changes. Closed by commit rL362811: [clangd] Return empty results on spurious completion triggers (authored by ibiryukov, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D62999?vs=203567&id=203572#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D62999/new/ https://reviews.llvm.org/D62999 Files: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test Index: clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test =================================================================== --- clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test +++ clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test @@ -4,11 +4,12 @@ {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"namespace ns { int ns_member; } struct vector { int size; static int default_capacity; };\nvoid test(vector *a, vector *b) {\n if (a > b) {} \n a->size = 10;\n\n a ? a : b;\n ns::ns_member = 10;\n}"}}} --- {"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":9},"context":{"triggerKind":2,"triggerCharacter":">"}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32001, -# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 1, +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0" +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [] +# CHECK-NEXT: } --- {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":3,"character":5},"context":{"triggerKind":2,"triggerCharacter":">"}}} # CHECK: "id": 2, @@ -64,11 +65,12 @@ # CHECK-NEXT: } --- {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":5,"character":9},"context":{"triggerKind":2,"triggerCharacter":":"}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32001, -# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 3, +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [] +# CHECK-NEXT: } --- {"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":6,"character":6},"context":{"triggerKind":2,"triggerCharacter":":"}}} --- Index: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp @@ -25,16 +25,6 @@ namespace clang { namespace clangd { namespace { -class IgnoreCompletionError : public llvm::ErrorInfo<CancelledError> { -public: - void log(llvm::raw_ostream &OS) const override { - OS << "ignored auto-triggered completion, preceding char did not match"; - } - std::error_code convertToErrorCode() const override { - return std::make_error_code(std::errc::operation_canceled); - } -}; - /// Transforms a tweak into a code action that would apply it if executed. /// EXPECTS: T.prepare() was called and returned true. CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File, @@ -738,8 +728,12 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params, Callback<CompletionList> Reply) { - if (!shouldRunCompletion(Params)) - return Reply(llvm::make_error<IgnoreCompletionError>()); + if (!shouldRunCompletion(Params)) { + // Clients sometimes auto-trigger completions in undesired places (e.g. + // 'a >^ '), we return empty results in those cases. + vlog("ignored auto-triggered completion, preceding char did not match"); + return Reply(CompletionList()); + } Server->codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts, Bind( [this](decltype(Reply) Reply,
Index: clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test =================================================================== --- clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test +++ clang-tools-extra/trunk/clangd/test/completion-auto-trigger.test @@ -4,11 +4,12 @@ {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"namespace ns { int ns_member; } struct vector { int size; static int default_capacity; };\nvoid test(vector *a, vector *b) {\n if (a > b) {} \n a->size = 10;\n\n a ? a : b;\n ns::ns_member = 10;\n}"}}} --- {"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":9},"context":{"triggerKind":2,"triggerCharacter":">"}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32001, -# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 1, +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0" +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [] +# CHECK-NEXT: } --- {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":3,"character":5},"context":{"triggerKind":2,"triggerCharacter":">"}}} # CHECK: "id": 2, @@ -64,11 +65,12 @@ # CHECK-NEXT: } --- {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":5,"character":9},"context":{"triggerKind":2,"triggerCharacter":":"}}} -# CHECK: "error": { -# CHECK-NEXT: "code": -32001, -# CHECK-NEXT: "message": "ignored auto-triggered completion, preceding char did not match" -# CHECK-NEXT: }, -# CHECK-NEXT: "id": 3, +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "isIncomplete": false, +# CHECK-NEXT: "items": [] +# CHECK-NEXT: } --- {"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":6,"character":6},"context":{"triggerKind":2,"triggerCharacter":":"}}} --- Index: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp @@ -25,16 +25,6 @@ namespace clang { namespace clangd { namespace { -class IgnoreCompletionError : public llvm::ErrorInfo<CancelledError> { -public: - void log(llvm::raw_ostream &OS) const override { - OS << "ignored auto-triggered completion, preceding char did not match"; - } - std::error_code convertToErrorCode() const override { - return std::make_error_code(std::errc::operation_canceled); - } -}; - /// Transforms a tweak into a code action that would apply it if executed. /// EXPECTS: T.prepare() was called and returned true. CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File, @@ -738,8 +728,12 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params, Callback<CompletionList> Reply) { - if (!shouldRunCompletion(Params)) - return Reply(llvm::make_error<IgnoreCompletionError>()); + if (!shouldRunCompletion(Params)) { + // Clients sometimes auto-trigger completions in undesired places (e.g. + // 'a >^ '), we return empty results in those cases. + vlog("ignored auto-triggered completion, preceding char did not match"); + return Reply(CompletionList()); + } Server->codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts, Bind( [this](decltype(Reply) Reply,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits