[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 13:36:15 PST 2017
Thanks! After thinking about it further, I can't see a simple combination
of flags to set that won't break other platforms.
So I've disabled the tests on PS4 for now, and will fix this properly once
I get some sleep.
On Wed, Nov 15, 2017 at 9:49 PM, Robinson, Paul <paul.robinson at sony.com>
wrote:
> You could build a PS4-target compiler yourself, actually, at least
> adequate for running lit tests. (Sorry it's not enough to build actual PS4
> code!) In a new build directory, run cmake with
> `-DLLVM_DEFAULT_TRIPLE=x86_64-scei-ps4` and then it should all Just
> Work. That's all the upstream PS4 bots are doing.
>
> --paulr
>
>
>
> *From:* Sam McCall [mailto:sam.mccall at gmail.com]
> *Sent:* Wednesday, November 15, 2017 12:42 PM
> *To:* Robinson, Paul
> *Cc:* Galina Kistanova; cfe-commits (cfe-commits at lists.llvm.org)
>
> *Subject:* Re: [clang-tools-extra] r318287 - [clangd] Support returning a
> limited number of completion results.
>
>
>
> On Wed, Nov 15, 2017 at 8:46 PM, Sam McCall <sam.mccall at gmail.com> wrote:
>
> That sounds great - I think using the same default std as clang is what we
> want.
>
> Unfortunately, passing --std=c++11 isn't ideal - we want to keep using the
> existing logic to derive the std from the language of the input file.
>
> For now r318327 explicitly sets the target triple to -pc-, which should
> get us back to uniform behavior across platforms.
>
> Well, this didn't fix it. Lacking a machine to test on, I'll try to
> disable the tests on PS4 until this can be fixed in some other way.
>
>
>
> This is obviously a hack and makes for a rocky -std transition, I'll look
> into this.
>
>
>
> (All this defaulting only happens if the user hasn't set up a compilation
> database to tell clangd how to build their project - unfortunately the
> tests do this)
>
>
>
> On Wed, Nov 15, 2017 at 8:13 PM, Robinson, Paul <paul.robinson at sony.com>
> wrote:
>
> Thanks for looking into it.
>
> I should point out that Clang is planning to update the default –std for
> everyone, hopefully before 6.0 branches, and it might be best to be ready
> for that rather than sticking with C++98.
>
> --paulr
>
>
>
> *From:* Sam McCall [mailto:sam.mccall at gmail.com]
> *Sent:* Wednesday, November 15, 2017 11:09 AM
> *To:* Robinson, Paul; Galina Kistanova
> *Cc:* cfe-commits (cfe-commits at lists.llvm.org)
> *Subject:* Re: [clang-tools-extra] r318287 - [clangd] Support returning a
> limited number of completion results.
>
>
>
> Sorry about these - I've finally understood what's going on.
>
> It looks like the PS4 has a different default --std, which probably
> doesn't make sense for clangd. I'll override it.
>
>
>
> On Wed, Nov 15, 2017 at 7:49 PM, Robinson, Paul <paul.robinson at sony.com>
> wrote:
>
> Hi Sam,
> It looks like llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast has been
> failing a couple of clangd tests ever since this went in.
>
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_
> 64-scei-ps4-windows10pro-fast/builds/13517
>
> Please fix or revert ASAP when bots go red. Failures like this interfere
> with our CI process.
>
> Thanks,
> --paulr
> PS4 code owner
>
>
> > -----Original Message-----
> > From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf
> Of
> > Sam McCall via cfe-commits
> > Sent: Wednesday, November 15, 2017 1:16 AM
> > To: cfe-commits at lists.llvm.org
> > Subject: [clang-tools-extra] r318287 - [clangd] Support returning a
> > limited number of completion results.
> >
> > 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=di
> > ff
> > ============================================================
> ==============
> > ====
> > --- 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":{"text
> > Document":{"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":{"text
> > Document":{"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,
> "lab
> > el":"int","sortText":"000050int"}
> > @@ -31,6 +31,6 @@ Content-Length: 58
> > # Function
> > # CHECK-DAG:
> > {"detail":"int","filterText":"function","insertText":"
> function()","insertT
> > extFormat":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":{"text
> > Document":{"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":{"text
> > Document":{"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":{"text
> > Document":{"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":{"text
> > Document":{"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":{"text
> > Document":{"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&vie
> > w=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":{"text
> > Document":{"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":{"text
> > Document":{"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":{"text
> > Document":{"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":{"text
> > Document":{"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=31828
> > 7&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;
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171115/18d7b30f/attachment-0001.html>
More information about the cfe-commits
mailing list