[clang-tools-extra] r318287 - [clangd] Support returning a limited number of completion results.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 15 01:16:29 PST 2017
Author: sammccall
Date: Wed Nov 15 01:16:29 2017
New Revision: 318287
URL: http://llvm.org/viewvc/llvm-project?rev=318287&view=rev
Log:
[clangd] Support returning a limited number of completion results.
Summary:
All results are scored, we only process CodeCompletionStrings for the winners.
We now return CompletionList rather than CompletionItem[] (both are valid).
sortText is now based on CodeCompletionResult::orderedName (mostly the same).
This is the first clangd-only completion option, so plumbing changed.
It requires a small clangd patch (exposing CodeCompletionResult::orderedName).
(This can't usefully be enabled yet: we don't support server-side filtering)
Reviewers: ilya-biryukov
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D39852
Modified:
clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
clang-tools-extra/trunk/clangd/ClangdServer.cpp
clang-tools-extra/trunk/clangd/ClangdServer.h
clang-tools-extra/trunk/clangd/ClangdUnit.cpp
clang-tools-extra/trunk/clangd/ClangdUnit.h
clang-tools-extra/trunk/clangd/Protocol.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/test/clangd/authority-less-uri.test
clang-tools-extra/trunk/test/clangd/completion-items-kinds.test
clang-tools-extra/trunk/test/clangd/completion-priorities.test
clang-tools-extra/trunk/test/clangd/completion-qualifiers.test
clang-tools-extra/trunk/test/clangd/completion-snippet.test
clang-tools-extra/trunk/test/clangd/completion.test
clang-tools-extra/trunk/test/clangd/protocol.test
clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Wed Nov 15 01:16:29 2017
@@ -195,15 +195,15 @@ void ClangdLSPServer::onCodeAction(Ctx C
}
void ClangdLSPServer::onCompletion(Ctx C, TextDocumentPositionParams &Params) {
- auto Items = Server
- .codeComplete(Params.textDocument.uri.file,
- Position{Params.position.line,
- Params.position.character})
- .get() // FIXME(ibiryukov): This could be made async if we
- // had an API that would allow to attach callbacks to
- // futures returned by ClangdServer.
- .Value;
- C.reply(json::ary(Items));
+ auto List = Server
+ .codeComplete(
+ Params.textDocument.uri.file,
+ Position{Params.position.line, Params.position.character})
+ .get() // FIXME(ibiryukov): This could be made async if we
+ // had an API that would allow to attach callbacks to
+ // futures returned by ClangdServer.
+ .Value;
+ C.reply(List);
}
void ClangdLSPServer::onSignatureHelp(Ctx C,
Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Wed Nov 15 01:16:29 2017
@@ -222,11 +222,11 @@ std::future<void> ClangdServer::forceRep
std::move(TaggedFS));
}
-std::future<Tagged<std::vector<CompletionItem>>>
+std::future<Tagged<CompletionList>>
ClangdServer::codeComplete(PathRef File, Position Pos,
llvm::Optional<StringRef> OverridenContents,
IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
- using ResultType = Tagged<std::vector<CompletionItem>>;
+ using ResultType = Tagged<CompletionList>;
std::promise<ResultType> ResultPromise;
@@ -242,11 +242,10 @@ ClangdServer::codeComplete(PathRef File,
}
void ClangdServer::codeComplete(
- UniqueFunction<void(Tagged<std::vector<CompletionItem>>)> Callback,
- PathRef File, Position Pos, llvm::Optional<StringRef> OverridenContents,
+ UniqueFunction<void(Tagged<CompletionList>)> Callback, PathRef File,
+ Position Pos, llvm::Optional<StringRef> OverridenContents,
IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
- using CallbackType =
- UniqueFunction<void(Tagged<std::vector<CompletionItem>>)>;
+ using CallbackType = UniqueFunction<void(Tagged<CompletionList>)>;
std::string Contents;
if (OverridenContents) {
@@ -283,7 +282,7 @@ void ClangdServer::codeComplete(
// FIXME(ibiryukov): even if Preamble is non-null, we may want to check
// both the old and the new version in case only one of them matches.
- std::vector<CompletionItem> Result = clangd::codeComplete(
+ CompletionList Result = clangd::codeComplete(
File, Resources->getCompileCommand(),
Preamble ? &Preamble->Preamble : nullptr, Contents, Pos,
TaggedFS.Value, PCHs, CodeCompleteOpts, Logger);
Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Wed Nov 15 01:16:29 2017
@@ -251,18 +251,17 @@ public:
/// This method should only be called for currently tracked files. However, it
/// is safe to call removeDocument for \p File after this method returns, even
/// while returned future is not yet ready.
- std::future<Tagged<std::vector<CompletionItem>>>
+ std::future<Tagged<CompletionList>>
codeComplete(PathRef File, Position Pos,
llvm::Optional<StringRef> OverridenContents = llvm::None,
IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
/// A version of `codeComplete` that runs \p Callback on the processing thread
/// when codeComplete results become available.
- void codeComplete(
- UniqueFunction<void(Tagged<std::vector<CompletionItem>>)> Callback,
- PathRef File, Position Pos,
- llvm::Optional<StringRef> OverridenContents = llvm::None,
- IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
+ void codeComplete(UniqueFunction<void(Tagged<CompletionList>)> Callback,
+ PathRef File, Position Pos,
+ llvm::Optional<StringRef> OverridenContents = llvm::None,
+ IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
/// Provide signature help for \p File at \p Pos. If \p OverridenContents is
/// not None, they will used only for signature help, i.e. no diagnostics
Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Wed Nov 15 01:16:29 2017
@@ -368,28 +368,90 @@ std::string getDocumentation(const CodeC
return Result;
}
+/// A scored code completion result.
+/// It may be promoted to a CompletionItem if it's among the top-ranked results.
+struct CompletionCandidate {
+ CompletionCandidate(CodeCompletionResult &Result)
+ : Result(&Result), Score(score(Result)) {}
+
+ CodeCompletionResult *Result;
+ // Higher score is worse. FIXME: use a more natural scale!
+ int Score;
+
+ // Comparison reflects rank: better candidates are smaller.
+ bool operator<(const CompletionCandidate &C) const {
+ if (Score != C.Score)
+ return Score < C.Score;
+ return *Result < *C.Result;
+ }
+
+ std::string sortText() const {
+ // Fill in the sortText of the CompletionItem.
+ assert(Score <= 999999 && "Expecting score to have at most 6-digits");
+ std::string S, NameStorage;
+ StringRef Name = Result->getOrderedName(NameStorage);
+ llvm::raw_string_ostream(S)
+ << llvm::format("%06d%.*s", Score, Name.size(), Name.data());
+ return S;
+ }
+
+private:
+ static int score(const CodeCompletionResult &Result) {
+ int Score = Result.Priority;
+ // Fill in the sortText of the CompletionItem.
+ assert(Score <= 99999 && "Expecting code completion result "
+ "priority to have at most 5-digits");
+
+ const int Penalty = 100000;
+ switch (static_cast<CXAvailabilityKind>(Result.Availability)) {
+ case CXAvailability_Available:
+ // No penalty.
+ break;
+ case CXAvailability_Deprecated:
+ Score += Penalty;
+ break;
+ case CXAvailability_NotAccessible:
+ Score += 2 * Penalty;
+ break;
+ case CXAvailability_NotAvailable:
+ Score += 3 * Penalty;
+ break;
+ }
+ return Score;
+ }
+};
+
class CompletionItemsCollector : public CodeCompleteConsumer {
public:
- CompletionItemsCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
- std::vector<CompletionItem> &Items)
- : CodeCompleteConsumer(CodeCompleteOpts, /*OutputIsBinary=*/false),
- Items(Items),
+ CompletionItemsCollector(const clangd::CodeCompleteOptions &CodeCompleteOpts,
+ CompletionList &Items)
+ : CodeCompleteConsumer(CodeCompleteOpts.getClangCompleteOpts(),
+ /*OutputIsBinary=*/false),
+ ClangdOpts(CodeCompleteOpts), Items(Items),
Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
CCTUInfo(Allocator) {}
void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
CodeCompletionResult *Results,
unsigned NumResults) override final {
- Items.reserve(NumResults);
+ std::priority_queue<CompletionCandidate> Candidates;
for (unsigned I = 0; I < NumResults; ++I) {
- auto &Result = Results[I];
- const auto *CCS = Result.CreateCodeCompletionString(
+ Candidates.emplace(Results[I]);
+ if (ClangdOpts.Limit && Candidates.size() > ClangdOpts.Limit) {
+ Candidates.pop();
+ Items.isIncomplete = true;
+ }
+ }
+ while (!Candidates.empty()) {
+ auto &Candidate = Candidates.top();
+ const auto *CCS = Candidate.Result->CreateCodeCompletionString(
S, Context, *Allocator, CCTUInfo,
CodeCompleteOpts.IncludeBriefComments);
assert(CCS && "Expected the CodeCompletionString to be non-null");
- Items.push_back(ProcessCodeCompleteResult(Result, *CCS));
+ Items.items.push_back(ProcessCodeCompleteResult(Candidate, *CCS));
+ Candidates.pop();
}
- std::sort(Items.begin(), Items.end());
+ std::reverse(Items.items.begin(), Items.items.end());
}
GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; }
@@ -398,7 +460,7 @@ public:
private:
CompletionItem
- ProcessCodeCompleteResult(const CodeCompletionResult &Result,
+ ProcessCodeCompleteResult(const CompletionCandidate &Candidate,
const CodeCompletionString &CCS) const {
// Adjust this to InsertTextFormat::Snippet iff we encounter a
@@ -407,15 +469,14 @@ private:
Item.insertTextFormat = InsertTextFormat::PlainText;
Item.documentation = getDocumentation(CCS);
+ Item.sortText = Candidate.sortText();
// Fill in the label, detail, insertText and filterText fields of the
// CompletionItem.
ProcessChunks(CCS, Item);
// Fill in the kind field of the CompletionItem.
- Item.kind = getKind(Result.Kind, Result.CursorKind);
-
- FillSortText(CCS, Item);
+ Item.kind = getKind(Candidate.Result->Kind, Candidate.Result->CursorKind);
return Item;
}
@@ -423,42 +484,8 @@ private:
virtual void ProcessChunks(const CodeCompletionString &CCS,
CompletionItem &Item) const = 0;
- static int GetSortPriority(const CodeCompletionString &CCS) {
- int Score = CCS.getPriority();
- // Fill in the sortText of the CompletionItem.
- assert(Score <= 99999 && "Expecting code completion result "
- "priority to have at most 5-digits");
-
- const int Penalty = 100000;
- switch (static_cast<CXAvailabilityKind>(CCS.getAvailability())) {
- case CXAvailability_Available:
- // No penalty.
- break;
- case CXAvailability_Deprecated:
- Score += Penalty;
- break;
- case CXAvailability_NotAccessible:
- Score += 2 * Penalty;
- break;
- case CXAvailability_NotAvailable:
- Score += 3 * Penalty;
- break;
- }
-
- return Score;
- }
-
- static void FillSortText(const CodeCompletionString &CCS,
- CompletionItem &Item) {
- int Priority = GetSortPriority(CCS);
- // Fill in the sortText of the CompletionItem.
- assert(Priority <= 999999 &&
- "Expecting sort priority to have at most 6-digits");
- llvm::raw_string_ostream(Item.sortText)
- << llvm::format("%06d%s", Priority, Item.filterText.c_str());
- }
-
- std::vector<CompletionItem> &Items;
+ clangd::CodeCompleteOptions ClangdOpts;
+ CompletionList &Items;
std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
CodeCompletionTUInfo CCTUInfo;
@@ -474,8 +501,8 @@ class PlainTextCompletionItemsCollector
public:
PlainTextCompletionItemsCollector(
- const clang::CodeCompleteOptions &CodeCompleteOpts,
- std::vector<CompletionItem> &Items)
+ const clangd::CodeCompleteOptions &CodeCompleteOpts,
+ CompletionList &Items)
: CompletionItemsCollector(CodeCompleteOpts, Items) {}
private:
@@ -511,8 +538,8 @@ class SnippetCompletionItemsCollector fi
public:
SnippetCompletionItemsCollector(
- const clang::CodeCompleteOptions &CodeCompleteOpts,
- std::vector<CompletionItem> &Items)
+ const clangd::CodeCompleteOptions &CodeCompleteOpts,
+ CompletionList &Items)
: CompletionItemsCollector(CodeCompleteOpts, Items) {}
private:
@@ -795,7 +822,8 @@ clangd::CodeCompleteOptions::CodeComplet
IncludeMacros(IncludeMacros), IncludeGlobals(IncludeGlobals),
IncludeBriefComments(IncludeBriefComments) {}
-clang::CodeCompleteOptions clangd::CodeCompleteOptions::getClangCompleteOpts() {
+clang::CodeCompleteOptions
+clangd::CodeCompleteOptions::getClangCompleteOpts() const {
clang::CodeCompleteOptions Result;
Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
Result.IncludeMacros = IncludeMacros;
@@ -805,25 +833,24 @@ clang::CodeCompleteOptions clangd::CodeC
return Result;
}
-std::vector<CompletionItem>
+CompletionList
clangd::codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
PrecompiledPreamble const *Preamble, StringRef Contents,
Position Pos, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
std::shared_ptr<PCHContainerOperations> PCHs,
clangd::CodeCompleteOptions Opts, clangd::Logger &Logger) {
- std::vector<CompletionItem> Results;
+ CompletionList Results;
std::unique_ptr<CodeCompleteConsumer> Consumer;
- clang::CodeCompleteOptions ClangCompleteOpts = Opts.getClangCompleteOpts();
if (Opts.EnableSnippets) {
- Consumer = llvm::make_unique<SnippetCompletionItemsCollector>(
- ClangCompleteOpts, Results);
+ Consumer =
+ llvm::make_unique<SnippetCompletionItemsCollector>(Opts, Results);
} else {
- Consumer = llvm::make_unique<PlainTextCompletionItemsCollector>(
- ClangCompleteOpts, Results);
+ Consumer =
+ llvm::make_unique<PlainTextCompletionItemsCollector>(Opts, Results);
}
- invokeCodeComplete(std::move(Consumer), ClangCompleteOpts, FileName, Command,
- Preamble, Contents, Pos, std::move(VFS), std::move(PCHs),
- Logger);
+ invokeCodeComplete(std::move(Consumer), Opts.getClangCompleteOpts(), FileName,
+ Command, Preamble, Contents, Pos, std::move(VFS),
+ std::move(PCHs), Logger);
return Results;
}
Modified: clang-tools-extra/trunk/clangd/ClangdUnit.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.h Wed Nov 15 01:16:29 2017
@@ -263,7 +263,7 @@ struct CodeCompleteOptions {
bool IncludeBriefComments);
/// Returns options that can be passed to clang's completion engine.
- clang::CodeCompleteOptions getClangCompleteOpts();
+ clang::CodeCompleteOptions getClangCompleteOpts() const;
/// When true, completion items will contain expandable code snippets in
/// completion (e.g. `return ${1:expression}` or `foo(${1:int a}, ${2:int
@@ -285,10 +285,14 @@ struct CodeCompleteOptions {
/// FIXME(ibiryukov): it looks like turning this option on significantly slows
/// down completion, investigate if it can be made faster.
bool IncludeBriefComments = true;
+
+ /// Limit the number of results returned (0 means no limit).
+ /// If more results are available, we set CompletionList.isIncomplete.
+ size_t Limit = 0;
};
/// Get code completions at a specified \p Pos in \p FileName.
-std::vector<CompletionItem>
+CompletionList
codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
PrecompiledPreamble const *Preamble, StringRef Contents,
Position Pos, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Wed Nov 15 01:16:29 2017
@@ -1043,6 +1043,13 @@ bool clangd::operator<(const CompletionI
(R.sortText.empty() ? R.label : R.sortText);
}
+json::Expr CompletionList::unparse(const CompletionList &L) {
+ return json::obj{
+ {"isIncomplete", L.isIncomplete},
+ {"items", json::ary(L.items)},
+ };
+}
+
json::Expr ParameterInformation::unparse(const ParameterInformation &PI) {
assert(!PI.label.empty() && "parameter information label is required");
json::obj Result{{"label", PI.label}};
Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Wed Nov 15 01:16:29 2017
@@ -547,6 +547,18 @@ struct CompletionItem {
bool operator<(const CompletionItem &, const CompletionItem &);
+/// Represents a collection of completion items to be presented in the editor.
+struct CompletionList {
+ /// The list is not complete. Further typing should result in recomputing the
+ /// list.
+ bool isIncomplete = false;
+
+ /// The completion items.
+ std::vector<CompletionItem> items;
+
+ static json::Expr unparse(const CompletionList &);
+};
+
/// A single parameter of a particular signature.
struct ParameterInformation {
Modified: clang-tools-extra/trunk/test/clangd/authority-less-uri.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/authority-less-uri.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/authority-less-uri.test (original)
+++ clang-tools-extra/trunk/test/clangd/authority-less-uri.test Wed Nov 15 01:16:29 2017
@@ -17,14 +17,17 @@ Content-Length: 146
#
# CHECK: "id": 1,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK: ]
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK: ]
+# CHECK-NEXT: }
Content-Length: 172
{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"uri":"file:///main.cpp","position":{"line":3,"character":5}}}
@@ -32,14 +35,17 @@ Content-Length: 172
#
# CHECK: "id": 2,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK: ]
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK: ]
+# CHECK-NEXT: }
Content-Length: 44
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Modified: clang-tools-extra/trunk/test/clangd/completion-items-kinds.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion-items-kinds.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion-items-kinds.test (original)
+++ clang-tools-extra/trunk/test/clangd/completion-items-kinds.test Wed Nov 15 01:16:29 2017
@@ -11,7 +11,7 @@ Content-Length: 148
{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":4,"character":7}}}
Content-Length: 58
-# CHECK: {"id":1,"jsonrpc":"2.0","result":[
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"isIncomplete":false,"items":
#
# Keyword
# CHECK-DAG: {"filterText":"int","insertText":"int","insertTextFormat":1,"kind":14,"label":"int","sortText":"000050int"}
@@ -31,6 +31,6 @@ Content-Length: 58
# Function
# CHECK-DAG: {"detail":"int","filterText":"function","insertText":"function()","insertTextFormat":1,"kind":3,"label":"function()","sortText":"000012function"}
#
-# CHECK-SAME: ]}
+# CHECK-SAME: ]}}
{"jsonrpc":"2.0","id":3,"method":"shutdown","params":null}
Modified: clang-tools-extra/trunk/test/clangd/completion-priorities.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion-priorities.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion-priorities.test (original)
+++ clang-tools-extra/trunk/test/clangd/completion-priorities.test Wed Nov 15 01:16:29 2017
@@ -15,69 +15,74 @@ Content-Length: 151
{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":12,"character":8}}}
# CHECK: "id": 2,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "void",
-# CHECK-NEXT: "filterText": "priv",
-# CHECK-NEXT: "insertText": "priv",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "priv()",
-# CHECK-NEXT: "sortText": "000034priv"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "void",
-# CHECK-NEXT: "filterText": "prot",
-# CHECK-NEXT: "insertText": "prot",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "prot()",
-# CHECK-NEXT: "sortText": "000034prot"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "void",
-# CHECK-NEXT: "filterText": "pub",
-# CHECK-NEXT: "insertText": "pub",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "pub()",
-# CHECK-NEXT: "sortText": "000034pub"
-# CHECK-NEXT: },
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "void",
+# CHECK-NEXT: "filterText": "priv",
+# CHECK-NEXT: "insertText": "priv",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "priv()",
+# CHECK-NEXT: "sortText": "000034priv"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "void",
+# CHECK-NEXT: "filterText": "prot",
+# CHECK-NEXT: "insertText": "prot",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "prot()",
+# CHECK-NEXT: "sortText": "000034prot"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "void",
+# CHECK-NEXT: "filterText": "pub",
+# CHECK-NEXT: "insertText": "pub",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "pub()",
+# CHECK-NEXT: "sortText": "000034pub"
+# CHECK-NEXT: },
Content-Length: 151
{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":4}}}
# CHECK: "id": 3,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "void",
-# CHECK-NEXT: "filterText": "pub",
-# CHECK-NEXT: "insertText": "pub",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "pub()",
-# CHECK-NEXT: "sortText": "000034pub"
-# CHECK-NEXT: },
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "void",
+# CHECK-NEXT: "filterText": "pub",
+# CHECK-NEXT: "insertText": "pub",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "pub()",
+# CHECK-NEXT: "sortText": "000034pub"
+# CHECK-NEXT: },
# priv() and prot() are at the end of the list
-# CHECK-NEXT: {
-# CHECK: "detail": "void",
-# CHECK: "filterText": "priv",
-# CHECK-NEXT: "insertText": "priv",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "priv()",
-# CHECK-NEXT: "sortText": "200034priv"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "void",
-# CHECK-NEXT: "filterText": "prot",
-# CHECK-NEXT: "insertText": "prot",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "prot()",
-# CHECK-NEXT: "sortText": "200034prot"
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
+# CHECK-NEXT: {
+# CHECK: "detail": "void",
+# CHECK: "filterText": "priv",
+# CHECK-NEXT: "insertText": "priv",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "priv()",
+# CHECK-NEXT: "sortText": "200034priv"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "void",
+# CHECK-NEXT: "filterText": "prot",
+# CHECK-NEXT: "insertText": "prot",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "prot()",
+# CHECK-NEXT: "sortText": "200034prot"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
Content-Length: 58
{"jsonrpc":"2.0","id":4,"method":"shutdown","params":null}
Modified: clang-tools-extra/trunk/test/clangd/completion-qualifiers.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion-qualifiers.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion-qualifiers.test (original)
+++ clang-tools-extra/trunk/test/clangd/completion-qualifiers.test Wed Nov 15 01:16:29 2017
@@ -10,37 +10,40 @@ Content-Length: 151
{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":11,"character":8}}}
# CHECK: "id": 2,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
# Eligible const functions are at the top of the list.
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int",
-# CHECK-NEXT: "filterText": "bar",
-# CHECK-NEXT: "insertText": "bar",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "bar() const",
-# CHECK-NEXT: "sortText": "000037bar"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int",
-# CHECK-NEXT: "filterText": "foo",
-# CHECK-NEXT: "insertText": "foo",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "Foo::foo() const",
-# CHECK-NEXT: "sortText": "000037foo"
-# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "bar",
+# CHECK-NEXT: "insertText": "bar",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "bar() const",
+# CHECK-NEXT: "sortText": "000037bar"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "foo",
+# CHECK-NEXT: "insertText": "foo",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "Foo::foo() const",
+# CHECK-NEXT: "sortText": "000037foo"
+# CHECK-NEXT: },
# Ineligible non-const function is at the bottom of the list.
-# CHECK-NEXT: {
-# CHECK: "detail": "int",
-# CHECK: "filterText": "foo",
-# CHECK-NEXT: "insertText": "foo",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "foo() const",
-# CHECK-NEXT: "sortText": "200035foo"
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
+# CHECK-NEXT: {
+# CHECK: "detail": "int",
+# CHECK: "filterText": "foo",
+# CHECK-NEXT: "insertText": "foo",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "foo() const",
+# CHECK-NEXT: "sortText": "200035foo"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
Content-Length: 44
{"jsonrpc":"2.0","id":4,"method":"shutdown"}
Modified: clang-tools-extra/trunk/test/clangd/completion-snippet.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion-snippet.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion-snippet.test (original)
+++ clang-tools-extra/trunk/test/clangd/completion-snippet.test Wed Nov 15 01:16:29 2017
@@ -14,71 +14,74 @@ Content-Length: 148
{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}}
# CHECK: "id": 1,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# 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": "000035a"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int",
-# CHECK-NEXT: "filterText": "bb",
-# CHECK-NEXT: "insertText": "bb",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 5,
-# CHECK-NEXT: "label": "bb",
-# CHECK-NEXT: "sortText": "000035bb"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int",
-# CHECK-NEXT: "filterText": "ccc",
-# CHECK-NEXT: "insertText": "ccc",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 5,
-# CHECK-NEXT: "label": "ccc",
-# CHECK-NEXT: "sortText": "000035ccc"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int",
-# CHECK-NEXT: "filterText": "f",
-# CHECK-NEXT: "insertText": "f(${1:int i}, ${2:const float f})",
-# CHECK-NEXT: "insertTextFormat": 2,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "f(int i, const float f) const",
-# CHECK-NEXT: "sortText": "000035f"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake::",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK-NEXT: },
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "fake &",
-# CHECK-NEXT: "filterText": "operator=",
-# CHECK-NEXT: "insertText": "operator=(${1:const fake &})",
-# CHECK-NEXT: "insertTextFormat": 2,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "operator=(const fake &)",
-# CHECK-NEXT: "sortText": "000079operator="
-# CHECK-NEXT: },
+# 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": "000035a"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "bb",
+# CHECK-NEXT: "insertText": "bb",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": "bb",
+# CHECK-NEXT: "sortText": "000035bb"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "ccc",
+# CHECK-NEXT: "insertText": "ccc",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 5,
+# CHECK-NEXT: "label": "ccc",
+# CHECK-NEXT: "sortText": "000035ccc"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int",
+# CHECK-NEXT: "filterText": "f",
+# CHECK-NEXT: "insertText": "f(${1:int i}, ${2:const float f})",
+# CHECK-NEXT: "insertTextFormat": 2,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "f(int i, const float f) const",
+# CHECK-NEXT: "sortText": "000035f"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake::",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK-NEXT: },
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "fake &",
+# CHECK-NEXT: "filterText": "operator=",
+# CHECK-NEXT: "insertText": "operator=(${1:const fake &})",
+# CHECK-NEXT: "insertTextFormat": 2,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "operator=(const fake &)",
+# CHECK-NEXT: "sortText": "000079operator="
+# CHECK-NEXT: },
# FIXME: Why do some buildbots show an extra operator==(fake&&) here?
-# CHECK: {
-# CHECK: "detail": "void",
-# CHECK-NEXT: "filterText": "~fake",
-# CHECK-NEXT: "insertText": "~fake()",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 4,
-# CHECK-NEXT: "label": "~fake()",
-# CHECK-NEXT: "sortText": "000079~fake"
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
+# CHECK: {
+# CHECK: "detail": "void",
+# CHECK-NEXT: "filterText": "~fake",
+# CHECK-NEXT: "insertText": "~fake()",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 4,
+# CHECK-NEXT: "label": "~fake()",
+# CHECK-NEXT: "sortText": "000079~fake"
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
# Update the source file and check for completions again.
Content-Length: 226
@@ -89,16 +92,18 @@ Content-Length: 148
{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}}
# CHECK: "id": 3,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK-NEXT: {
-# CHECK-NEXT: "detail": "int (*)(int, int)",
-# CHECK-NEXT: "filterText": "func",
-# CHECK-NEXT: "insertText": "func()",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 2,
-# CHECK-NEXT: "label": "func()",
-# CHECK-NEXT: "sortText": "000034func"
-# CHECK-NEXT: },
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "detail": "int (*)(int, int)",
+# CHECK-NEXT: "filterText": "func",
+# CHECK-NEXT: "insertText": "func()",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 2,
+# CHECK-NEXT: "label": "func()",
+# CHECK-NEXT: "sortText": "000034func"
+# CHECK-NEXT: },
Content-Length: 44
{"jsonrpc":"2.0","id":4,"method":"shutdown"}
Modified: clang-tools-extra/trunk/test/clangd/completion.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion.test (original)
+++ clang-tools-extra/trunk/test/clangd/completion.test Wed Nov 15 01:16:29 2017
@@ -14,7 +14,9 @@ Content-Length: 148
{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}}
# CHECK: "id": 1
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
# CHECK-NEXT: {
# CHECK-NEXT: "detail": "int",
# CHECK-NEXT: "filterText": "a",
@@ -84,7 +86,9 @@ Content-Length: 148
{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}}
# CHECK: "id": 2
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
# CHECK-NEXT: {
# CHECK-NEXT: "detail": "int",
# CHECK-NEXT: "filterText": "a",
@@ -158,7 +162,9 @@ Content-Length: 148
{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}}
# CHECK: "id": 3,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
# CHECK-NEXT: {
# CHECK-NEXT: "detail": "int (*)(int, int)",
# CHECK-NEXT: "filterText": "func",
Modified: clang-tools-extra/trunk/test/clangd/protocol.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/protocol.test?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clangd/protocol.test (original)
+++ clang-tools-extra/trunk/test/clangd/protocol.test Wed Nov 15 01:16:29 2017
@@ -31,14 +31,17 @@ Content-Length: 146
#
# CHECK: "id": 1,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK: ]
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK: ]
+# CHECK-NEXT: }
X-Test: Testing
Content-Type: application/vscode-jsonrpc; charset-utf-8
@@ -57,14 +60,17 @@ Content-Length: 146
#
# CHECK: "id": 3,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK: ]
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK: ]
+# CHECK-NEXT: }
# STDERR: Warning: Duplicate Content-Length header received. The previous value for this message (10) was ignored.
Content-Type: application/vscode-jsonrpc; charset-utf-8
@@ -83,14 +89,17 @@ Content-Length: 146
#
# CHECK: "id": 5,
# CHECK-NEXT: "jsonrpc": "2.0",
-# CHECK-NEXT: "result": [
-# CHECK: "filterText": "fake",
-# CHECK-NEXT: "insertText": "fake",
-# CHECK-NEXT: "insertTextFormat": 1,
-# CHECK-NEXT: "kind": 7,
-# CHECK-NEXT: "label": "fake::",
-# CHECK-NEXT: "sortText": "000075fake"
-# CHECK: ]
+# CHECK-NEXT: "result": {
+# CHECK-NEXT: "isIncomplete": false,
+# CHECK-NEXT: "items": [
+# CHECK: "filterText": "fake",
+# CHECK-NEXT: "insertText": "fake",
+# CHECK-NEXT: "insertTextFormat": 1,
+# CHECK-NEXT: "kind": 7,
+# CHECK-NEXT: "label": "fake::",
+# CHECK-NEXT: "sortText": "000075fake"
+# CHECK: ]
+# CHECK-NEXT: }
Content-Length: 1024
{"jsonrpc":"2.0","id":5,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:/main.cpp"},"position":{"line":3,"character":5}}}
Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=318287&r1=318286&r2=318287&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Wed Nov 15 01:16:29 2017
@@ -619,16 +619,15 @@ struct bar { T x; };
class ClangdCompletionTest : public ClangdVFSTest {
protected:
template <class Predicate>
- bool ContainsItemPred(std::vector<CompletionItem> const &Items,
- Predicate Pred) {
- for (const auto &Item : Items) {
+ bool ContainsItemPred(CompletionList const &Items, Predicate Pred) {
+ for (const auto &Item : Items.items) {
if (Pred(Item))
return true;
}
return false;
}
- bool ContainsItem(std::vector<CompletionItem> const &Items, StringRef Name) {
+ bool ContainsItem(CompletionList const &Items, StringRef Name) {
return ContainsItemPred(Items, [Name](clangd::CompletionItem Item) {
return Item.insertText == Name;
});
@@ -694,6 +693,44 @@ int b = ;
}
}
+TEST_F(ClangdCompletionTest, Limit) {
+ MockFSProvider FS;
+ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+ CDB.ExtraClangFlags.push_back("-xc++");
+ ErrorCheckingDiagConsumer DiagConsumer;
+ clangd::CodeCompleteOptions Opts;
+ Opts.Limit = 2;
+ ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+ Opts, EmptyLogger::getInstance());
+
+ auto FooCpp = getVirtualTestFilePath("foo.cpp");
+ FS.Files[FooCpp] = "";
+ FS.ExpectedFile = FooCpp;
+ StringWithPos Completion = parseTextMarker(R"cpp(
+struct ClassWithMembers {
+ int AAA();
+ int BBB();
+ int CCC();
+}
+int main() { ClassWithMembers().{complete} }
+ )cpp",
+ "complete");
+ Server.addDocument(FooCpp, Completion.Text);
+
+ /// For after-dot completion we must always get consistent results.
+ auto Results = Server
+ .codeComplete(FooCpp, Completion.MarkerPos,
+ StringRef(Completion.Text))
+ .get()
+ .Value;
+
+ EXPECT_TRUE(Results.isIncomplete);
+ EXPECT_EQ(Opts.Limit, Results.items.size());
+ EXPECT_TRUE(ContainsItem(Results, "AAA"));
+ EXPECT_TRUE(ContainsItem(Results, "BBB"));
+ EXPECT_FALSE(ContainsItem(Results, "CCC"));
+}
+
TEST_F(ClangdCompletionTest, CompletionOptions) {
MockFSProvider FS;
ErrorCheckingDiagConsumer DiagConsumer;
More information about the cfe-commits
mailing list