Author: kadircet Date: Thu Sep 27 10:13:07 2018 New Revision: 343237 URL: http://llvm.org/viewvc/llvm-project?rev=343237&view=rev Log: Introduce completionItemKind capability support.
Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, ioeric, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D52616 Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=343237&r1=343236&r2=343237&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Thu Sep 27 10:13:07 2018 @@ -70,6 +70,14 @@ SymbolKindBitset defaultSymbolKinds() { return Defaults; } +CompletionItemKindBitset defaultCompletionItemKinds() { + CompletionItemKindBitset Defaults; + for (size_t I = CompletionItemKindMin; + I <= static_cast<size_t>(CompletionItemKind::Reference); ++I) + Defaults.set(I); + return Defaults; +} + } // namespace void ClangdLSPServer::onInitialize(InitializeParams &Params) { @@ -89,13 +97,20 @@ void ClangdLSPServer::onInitialize(Initi Params.capabilities.textDocument.publishDiagnostics.categorySupport; if (Params.capabilities.workspace && Params.capabilities.workspace->symbol && - Params.capabilities.workspace->symbol->symbolKind) { + Params.capabilities.workspace->symbol->symbolKind && + Params.capabilities.workspace->symbol->symbolKind->valueSet) { for (SymbolKind Kind : *Params.capabilities.workspace->symbol->symbolKind->valueSet) { SupportedSymbolKinds.set(static_cast<size_t>(Kind)); } } + if (Params.capabilities.textDocument.completion.completionItemKind && + Params.capabilities.textDocument.completion.completionItemKind->valueSet) + for (CompletionItemKind Kind : *Params.capabilities.textDocument.completion + .completionItemKind->valueSet) + SupportedCompletionItemKinds.set(static_cast<size_t>(Kind)); + reply(json::Object{ {{"capabilities", json::Object{ @@ -347,8 +362,12 @@ void ClangdLSPServer::onCompletion(TextD return replyError(List.takeError()); CompletionList LSPList; LSPList.isIncomplete = List->HasMore; - for (const auto &R : List->Completions) - LSPList.items.push_back(R.render(CCOpts)); + for (const auto &R : List->Completions) { + CompletionItem C = R.render(CCOpts); + C.kind = adjustKindToCapability( + C.kind, SupportedCompletionItemKinds); + LSPList.items.push_back(std::move(C)); + } return reply(std::move(LSPList)); }); } @@ -459,6 +478,7 @@ ClangdLSPServer::ClangdLSPServer(JSONOut : CompilationDB::makeDirectoryBased( std::move(CompileCommandsDir))), CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()), + SupportedCompletionItemKinds(defaultCompletionItemKinds()), Server(new ClangdServer(CDB.getCDB(), FSProvider, /*DiagConsumer=*/*this, Opts)) {} Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=343237&r1=343236&r2=343237&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Thu Sep 27 10:13:07 2018 @@ -164,6 +164,8 @@ private: ClangdDiagnosticOptions DiagOpts; /// The supported kinds of the client. SymbolKindBitset SupportedSymbolKinds; + /// The supported completion item kinds of the client. + CompletionItemKindBitset SupportedCompletionItemKinds; // Store of the current versions of the open documents. DraftStore DraftMgr; Modified: clang-tools-extra/trunk/clangd/Protocol.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=343237&r1=343236&r2=343237&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/Protocol.cpp (original) +++ clang-tools-extra/trunk/clangd/Protocol.cpp Thu Sep 27 10:13:07 2018 @@ -496,6 +496,57 @@ json::Value toJSON(const Hover &H) { return std::move(Result); } +bool fromJSON(const json::Value &E, CompletionItemKind &Out) { + if (auto T = E.getAsInteger()) { + if (*T < static_cast<int>(CompletionItemKind::Text) || + *T > static_cast<int>(CompletionItemKind::TypeParameter)) + return false; + Out = static_cast<CompletionItemKind>(*T); + return true; + } + return false; +} + +CompletionItemKind +adjustKindToCapability(CompletionItemKind Kind, + CompletionItemKindBitset &supportedCompletionItemKinds) { + auto KindVal = static_cast<size_t>(Kind); + if (KindVal >= CompletionItemKindMin && + KindVal <= supportedCompletionItemKinds.size() && + supportedCompletionItemKinds[KindVal]) + return Kind; + + switch (Kind) { + // Provide some fall backs for common kinds that are close enough. + case CompletionItemKind::Folder: + return CompletionItemKind::File; + case CompletionItemKind::EnumMember: + return CompletionItemKind::Enum; + case CompletionItemKind::Struct: + return CompletionItemKind::Class; + default: + return CompletionItemKind::Text; + } +} + +bool fromJSON(const json::Value &E, std::vector<CompletionItemKind> &Out) { + if (auto *A = E.getAsArray()) { + Out.clear(); + for (size_t I = 0; I < A->size(); ++I) { + CompletionItemKind KindOut; + if (fromJSON((*A)[I], KindOut)) + Out.push_back(KindOut); + } + return true; + } + return false; +} + +bool fromJSON(const json::Value &Params, CompletionItemKindCapabilities &R) { + json::ObjectMapper O(Params); + return O && O.map("valueSet", R.valueSet); +} + json::Value toJSON(const CompletionItem &CI) { assert(!CI.label.empty() && "completion item label is required"); json::Object Result{{"label", CI.label}}; Modified: clang-tools-extra/trunk/clangd/Protocol.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=343237&r1=343236&r2=343237&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/Protocol.h (original) +++ clang-tools-extra/trunk/clangd/Protocol.h Thu Sep 27 10:13:07 2018 @@ -233,13 +233,65 @@ struct CompletionItemClientCapabilities }; bool fromJSON(const llvm::json::Value &, CompletionItemClientCapabilities &); +/// The kind of a completion entry. +enum class CompletionItemKind { + Missing = 0, + Text = 1, + Method = 2, + Function = 3, + Constructor = 4, + Field = 5, + Variable = 6, + Class = 7, + Interface = 8, + Module = 9, + Property = 10, + Unit = 11, + Value = 12, + Enum = 13, + Keyword = 14, + Snippet = 15, + Color = 16, + File = 17, + Reference = 18, + Folder = 19, + EnumMember = 20, + Constant = 21, + Struct = 22, + Event = 23, + Operator = 24, + TypeParameter = 25, +}; +bool fromJSON(const llvm::json::Value &, CompletionItemKind &); + +struct CompletionItemKindCapabilities { + /// The CompletionItemKinds that the client supports. If not set, the client + /// only supports <= CompletionItemKind::Reference and will not fall back to a + /// valid default value. + llvm::Optional<std::vector<CompletionItemKind>> valueSet; +}; +// Discards unknown CompletionItemKinds. +bool fromJSON(const llvm::json::Value &, std::vector<CompletionItemKind> &); +bool fromJSON(const llvm::json::Value &, CompletionItemKindCapabilities &); + +constexpr auto CompletionItemKindMin = + static_cast<size_t>(CompletionItemKind::Text); +constexpr auto CompletionItemKindMax = + static_cast<size_t>(CompletionItemKind::TypeParameter); +using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>; +CompletionItemKind +adjustKindToCapability(CompletionItemKind Kind, + CompletionItemKindBitset &supportedCompletionItemKinds); + struct CompletionClientCapabilities { /// Whether completion supports dynamic registration. bool dynamicRegistration = false; /// The client supports the following `CompletionItem` specific capabilities. CompletionItemClientCapabilities completionItem; - // NOTE: not used by clangd at the moment. - // llvm::Optional<CompletionItemKindCapabilities> completionItemKind; + /// The CompletionItemKinds that the client supports. If not set, the client + /// only supports <= CompletionItemKind::Reference and will not fall back to a + /// valid default value. + llvm::Optional<CompletionItemKindCapabilities> completionItemKind; /// The client supports to send additional context information for a /// `textDocument/completion` request. @@ -305,6 +357,7 @@ struct SymbolKindCapabilities { /// value. llvm::Optional<std::vector<SymbolKind>> valueSet; }; +// Discards unknown SymbolKinds. bool fromJSON(const llvm::json::Value &, std::vector<SymbolKind> &); bool fromJSON(const llvm::json::Value &, SymbolKindCapabilities &); SymbolKind adjustKindToCapability(SymbolKind Kind, @@ -683,36 +736,6 @@ struct Hover { }; llvm::json::Value toJSON(const Hover &H); -/// The kind of a completion entry. -enum class CompletionItemKind { - Missing = 0, - Text = 1, - Method = 2, - Function = 3, - Constructor = 4, - Field = 5, - Variable = 6, - Class = 7, - Interface = 8, - Module = 9, - Property = 10, - Unit = 11, - Value = 12, - Enum = 13, - Keyword = 14, - Snippet = 15, - Color = 16, - File = 17, - Reference = 18, - Folder = 19, - EnumMember = 20, - Constant = 21, - Struct = 22, - Event = 23, - Operator = 24, - TypeParameter = 25, -}; - /// Defines whether the insert text in a completion item should be interpreted /// as plain text or a snippet. enum class InsertTextFormat { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits