@@ -188,12 +188,13 @@ bool SourceKit::CodeCompletion::addCustomCompletions(
188188class CodeCompletionOrganizer ::Impl {
189189 std::unique_ptr<Group> rootGroup;
190190 CompletionKind completionKind;
191+ bool completionHasExpectedTypes;
191192
192193 void groupStemsRecursive (Group *group, bool recurseIntoNewGroups,
193194 StringRef (getStem)(StringRef));
194195
195196public:
196- Impl (CompletionKind kind);
197+ Impl (CompletionKind kind, bool hasExpectedTypes );
197198
198199 void addCompletionsWithFilter (ArrayRef<Completion *> completions,
199200 StringRef filterText, Options options,
@@ -249,8 +250,9 @@ class CodeCompletionOrganizer::Impl {
249250// ===----------------------------------------------------------------------===//
250251
251252CodeCompletionOrganizer::CodeCompletionOrganizer (const Options &options,
252- CompletionKind kind)
253- : impl(*new Impl(kind)), options(options) {}
253+ CompletionKind kind,
254+ bool hasExpectedTypes)
255+ : impl(*new Impl(kind, hasExpectedTypes)), options(options) {}
254256CodeCompletionOrganizer::~CodeCompletionOrganizer () { delete &impl; }
255257
256258void CodeCompletionOrganizer::preSortCompletions (
@@ -383,8 +385,8 @@ static std::unique_ptr<Result> make_result(Completion *result) {
383385// CodeCompletionOrganizer::Impl implementation
384386// ===----------------------------------------------------------------------===//
385387
386- CodeCompletionOrganizer::Impl::Impl (CompletionKind kind)
387- : completionKind(kind) {
388+ CodeCompletionOrganizer::Impl::Impl (CompletionKind kind, bool hasExpectedTypes )
389+ : completionKind(kind), completionHasExpectedTypes(hasExpectedTypes) {
388390 assert (!rootGroup && " initialized twice" );
389391 rootGroup = make_group (" " );
390392}
@@ -516,7 +518,8 @@ void CodeCompletionOrganizer::Impl::addCompletionsWithFilter(
516518 }
517519 if (completion->getExpectedTypeRelation () >= Completion::Convertible ||
518520 (completion->getKind () == Completion::Literal &&
519- completionKind != CompletionKind::StmtOrExpr))
521+ completionKind != CompletionKind::StmtOrExpr &&
522+ !completionHasExpectedTypes))
520523 break ;
521524
522525 if (completion->getKind () == Completion::Keyword &&
@@ -543,6 +546,16 @@ void CodeCompletionOrganizer::Impl::addCompletionsWithFilter(
543546 if (rules.hideCompletion (completion))
544547 continue ;
545548
549+ // Hide literals other than the ones that are also keywords if they don't
550+ // match the expected types.
551+ if (completion->getKind () == Completion::Literal &&
552+ completionHasExpectedTypes &&
553+ completion->getExpectedTypeRelation () < Completion::Convertible &&
554+ completion->getLiteralKind () !=
555+ CodeCompletionLiteralKind::BooleanLiteral &&
556+ completion->getLiteralKind () != CodeCompletionLiteralKind::NilLiteral)
557+ continue ;
558+
546559 bool match = false ;
547560 if (options.fuzzyMatching && filterText.size () >= options.minFuzzyLength ) {
548561 match = pattern.matchesCandidate (completion->getName ());
@@ -641,7 +654,7 @@ enum class ResultBucket {
641654};
642655} // end anonymous namespace
643656
644- static ResultBucket getResultBucket (Item &item) {
657+ static ResultBucket getResultBucket (Item &item, bool hasExpectedTypes ) {
645658 if (isa<Group>(item))
646659 return ResultBucket::Normal; // FIXME: take best contained result.
647660 auto *completion = cast<Result>(item).value ;
@@ -655,7 +668,15 @@ static ResultBucket getResultBucket(Item &item) {
655668
656669 switch (completion->getKind ()) {
657670 case Completion::Literal:
658- return matchesType ? ResultBucket::LiteralTypeMatch : ResultBucket::Literal;
671+ if (matchesType) {
672+ return ResultBucket::LiteralTypeMatch;
673+ } else if (!hasExpectedTypes) {
674+ return ResultBucket::Literal;
675+ } else {
676+ // When we have type context, we still show literals that are keywords,
677+ // but we treat them as keywords instead of literals for prioritization.
678+ return ResultBucket::Normal;
679+ }
659680 case Completion::Keyword:
660681 return isHighPriorityKeyword (completion->getKeywordKind ())
661682 ? ResultBucket::HighPriorityKeyword
@@ -721,13 +742,14 @@ static int compareLiterals(Item &a_, Item &b_) {
721742 return 0 ;
722743}
723744
724- static void sortRecursive (const Options &options, Group *group) {
745+ static void sortRecursive (const Options &options, Group *group,
746+ bool hasExpectedTypes) {
725747 // Sort all of the subgroups first, and fill in the bucket for each result.
726748 auto &contents = group->contents ;
727749 double best = -1.0 ;
728750 for (auto &item : contents) {
729751 if (Group *g = dyn_cast<Group>(item.get ())) {
730- sortRecursive (options, g);
752+ sortRecursive (options, g, hasExpectedTypes );
731753 } else {
732754 Result *r = cast<Result>(item.get ());
733755 item->finalScore = combinedScore (options, item->matchScore , r->value );
@@ -749,40 +771,40 @@ static void sortRecursive(const Options &options, Group *group) {
749771 return ;
750772 }
751773
752- llvm::array_pod_sort (contents.begin (), contents.end (), [](const std::unique_ptr<Item> * a_, const std::unique_ptr<Item> * b_) {
753- Item &a = ** a_;
754- Item &b = ** b_;
774+ std::sort (contents.begin (), contents.end (), [= ](const std::unique_ptr<Item> & a_, const std::unique_ptr<Item> & b_) {
775+ Item &a = *a_;
776+ Item &b = *b_;
755777
756- auto bucketA = getResultBucket (a);
757- auto bucketB = getResultBucket (b);
778+ auto bucketA = getResultBucket (a, hasExpectedTypes );
779+ auto bucketB = getResultBucket (b, hasExpectedTypes );
758780 if (bucketA < bucketB)
759- return 1 ;
781+ return false ;
760782 else if (bucketB < bucketA)
761- return - 1 ;
783+ return true ;
762784
763785 // Special internal orderings.
764786 switch (bucketA) {
765787 case ResultBucket::HighPriorityKeyword:
766- return compareHighPriorityKeywords (a, b);
788+ return compareHighPriorityKeywords (a, b) < 0 ;
767789 case ResultBucket::Literal:
768790 case ResultBucket::LiteralTypeMatch:
769- return compareLiterals (a, b);
791+ return compareLiterals (a, b) < 0 ;
770792 default :
771793 break ;
772794 }
773795
774796 // "Normal" order.
775797 if (a.finalScore < b.finalScore )
776- return 1 ;
798+ return false ;
777799 else if (b.finalScore < a.finalScore )
778- return - 1 ;
800+ return true ;
779801
780- return compareResultName (a, b);
802+ return compareResultName (a, b) < 0 ;
781803 });
782804}
783805
784806void CodeCompletionOrganizer::Impl::sort (Options options) {
785- sortRecursive (options, rootGroup.get ());
807+ sortRecursive (options, rootGroup.get (), completionHasExpectedTypes );
786808}
787809
788810void CodeCompletionOrganizer::Impl::groupStemsRecursive (
0 commit comments