@@ -743,6 +743,8 @@ void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
743743 PRINT_FLAIR (ArgumentLabels, " ArgLabels" );
744744 PRINT_FLAIR (CommonKeywordAtCurrentPosition, " CommonKeyword" )
745745 PRINT_FLAIR (RareKeywordAtCurrentPosition, " RareKeyword" )
746+ PRINT_FLAIR (RareTypeAtCurrentPosition, " RareType" )
747+ PRINT_FLAIR (ExpressionAtNonScriptOrMainFileScope, " ExprAtFileScope" )
746748 Prefix.append (" ]" );
747749 }
748750 if (NotRecommended)
@@ -6477,10 +6479,54 @@ static void addConditionalCompilationFlags(ASTContext &Ctx,
64776479 }
64786480}
64796481
6482+ static void postProcessResults (ArrayRef<CodeCompletionResult *> results,
6483+ CompletionKind Kind, DeclContext *DC) {
6484+ auto isExprKeyword = [](const CodeCompletionResult *result) {
6485+ if (result->getKind () != CodeCompletionResult::ResultKind::Keyword)
6486+ return false ;
6487+ switch (result->getKeywordKind ()) {
6488+ #define POUND_DIRECTIVE_KEYWORD (kw )
6489+ #define POUND_CONFIG (kw )
6490+ #define POUND_KEYWORD (kw ) case CodeCompletionKeywordKind::pound_##kw:
6491+ #include " swift/Syntax/TokenKinds.def"
6492+ return true ;
6493+ default :
6494+ return false ;
6495+ }
6496+ };
6497+ for (CodeCompletionResult *result : results) {
6498+ auto flair = result->getFlair ();
6499+
6500+ // Starting a statement with a protocol name is not common. So protocol
6501+ // names at non-type name position are "rare".
6502+ if (result->getKind () == CodeCompletionResult::ResultKind::Declaration &&
6503+ result->getAssociatedDeclKind () == CodeCompletionDeclKind::Protocol &&
6504+ Kind != CompletionKind::TypeSimpleBeginning &&
6505+ Kind != CompletionKind::TypeIdentifierWithoutDot &&
6506+ Kind != CompletionKind::TypeIdentifierWithDot &&
6507+ Kind != CompletionKind::TypeDeclResultBeginning &&
6508+ Kind != CompletionKind::GenericRequirement) {
6509+ flair |= CodeCompletionFlairBit::RareTypeAtCurrentPosition;
6510+ }
6511+
6512+ // Starting a statement at top-level in non-script files is invalid.
6513+ if (Kind == CompletionKind::StmtOrExpr &&
6514+ isCodeCompletionAtTopLevel (DC) &&
6515+ !DC->getParentSourceFile ()->isScriptMode () &&
6516+ (result->getKind () == CodeCompletionResult::ResultKind::Declaration ||
6517+ result->getKind () == CodeCompletionResult::ResultKind::Literal ||
6518+ isExprKeyword (result))) {
6519+ flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
6520+ }
6521+ result->setFlair (flair);
6522+ }
6523+ }
6524+
64806525static void deliverCompletionResults (CodeCompletionContext &CompletionContext,
64816526 CompletionLookup &Lookup,
6482- SourceFile &SF ,
6527+ DeclContext *DC ,
64836528 CodeCompletionConsumer &Consumer) {
6529+ auto &SF = *DC->getParentSourceFile ();
64846530 llvm::SmallPtrSet<Identifier, 8 > seenModuleNames;
64856531 std::vector<RequestedCachedModule> RequestedModules;
64866532
@@ -6591,12 +6637,10 @@ static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
65916637 Lookup.RequestedCachedResults .clear ();
65926638 CompletionContext.typeContextKind = Lookup.typeContextKind ();
65936639
6594- // Use the current SourceFile as the DeclContext so that we can use it to
6595- // perform qualified lookup, and to get the correct visibility for
6596- // @testable imports.
6597- DeclContext *DCForModules = &SF;
6598- Consumer.handleResultsAndModules (CompletionContext, RequestedModules,
6599- DCForModules);
6640+ postProcessResults (CompletionContext.getResultSink ().Results ,
6641+ CompletionContext.CodeCompletionKind , DC);
6642+
6643+ Consumer.handleResultsAndModules (CompletionContext, RequestedModules, DC);
66006644}
66016645
66026646void deliverUnresolvedMemberResults (
@@ -6634,8 +6678,8 @@ void deliverUnresolvedMemberResults(
66346678 }
66356679 Lookup.getUnresolvedMemberCompletions (Result.ExpectedTy );
66366680 }
6637- SourceFile *SF = DC-> getParentSourceFile ();
6638- deliverCompletionResults (CompletionCtx, Lookup, *SF , Consumer);
6681+
6682+ deliverCompletionResults (CompletionCtx, Lookup, DC , Consumer);
66396683}
66406684
66416685void deliverDotExprResults (
@@ -6675,8 +6719,7 @@ void deliverDotExprResults(
66756719 Lookup.getValueExprCompletions (Result.BaseTy , Result.BaseDecl );
66766720 }
66776721
6678- SourceFile *SF = DC->getParentSourceFile ();
6679- deliverCompletionResults (CompletionCtx, Lookup, *SF, Consumer);
6722+ deliverCompletionResults (CompletionCtx, Lookup, DC, Consumer);
66806723}
66816724
66826725bool CodeCompletionCallbacksImpl::trySolverCompletion (bool MaybeFuncBody) {
@@ -7306,7 +7349,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
73067349 break ;
73077350 }
73087351
7309- deliverCompletionResults (CompletionContext, Lookup, P. SF , Consumer);
7352+ deliverCompletionResults (CompletionContext, Lookup, CurDeclContext , Consumer);
73107353}
73117354
73127355void PrintingCodeCompletionConsumer::handleResults (
@@ -7382,16 +7425,17 @@ void swift::ide::lookupCodeCompletionResultsFromModule(
73827425 CompletionLookup Lookup (targetSink, module ->getASTContext (), SF);
73837426 Lookup.lookupExternalModuleDecls (module , accessPath, needLeadingDot);
73847427}
7385-
7386- void swift::ide::copyCodeCompletionResults (CodeCompletionResultSink &targetSink,
7387- CodeCompletionResultSink &sourceSink,
7388- bool onlyTypes,
7389- bool onlyPrecedenceGroups) {
7428+ ArrayRef<CodeCompletionResult *>
7429+ swift::ide::copyCodeCompletionResults (CodeCompletionResultSink &targetSink,
7430+ CodeCompletionResultSink &sourceSink,
7431+ bool onlyTypes,
7432+ bool onlyPrecedenceGroups) {
73907433
73917434 // We will be adding foreign results (from another sink) into TargetSink.
73927435 // TargetSink should have an owning pointer to the allocator that keeps the
73937436 // results alive.
73947437 targetSink.ForeignAllocators .push_back (sourceSink.Allocator );
7438+ auto startSize = targetSink.Results .size ();
73957439
73967440 if (onlyTypes) {
73977441 std::copy_if (sourceSink.Results .begin (), sourceSink.Results .end (),
@@ -7441,12 +7485,21 @@ void swift::ide::copyCodeCompletionResults(CodeCompletionResultSink &targetSink,
74417485 sourceSink.Results .begin (),
74427486 sourceSink.Results .end ());
74437487 }
7488+
7489+ return llvm::makeArrayRef (targetSink.Results .data () + startSize,
7490+ targetSink.Results .size () - startSize);
74447491}
74457492
74467493void SimpleCachingCodeCompletionConsumer::handleResultsAndModules (
74477494 CodeCompletionContext &context,
74487495 ArrayRef<RequestedCachedModule> requestedModules,
7449- DeclContext *DCForModules) {
7496+ DeclContext *DC) {
7497+
7498+ // Use the current SourceFile as the DeclContext so that we can use it to
7499+ // perform qualified lookup, and to get the correct visibility for
7500+ // @testable imports.
7501+ DeclContext *DCForModules = DC->getParentSourceFile ();
7502+
74507503 for (auto &R : requestedModules) {
74517504 // FIXME(thread-safety): lock the whole AST context. We might load a
74527505 // module.
@@ -7462,8 +7515,9 @@ void SimpleCachingCodeCompletionConsumer::handleResultsAndModules(
74627515 context.Cache .set (R.Key , *V);
74637516 }
74647517 assert (V.hasValue ());
7465- copyCodeCompletionResults (context.getResultSink (), (*V)->Sink ,
7466- R.OnlyTypes , R.OnlyPrecedenceGroups );
7518+ auto newItems = copyCodeCompletionResults (context.getResultSink (), (*V)->Sink ,
7519+ R.OnlyTypes , R.OnlyPrecedenceGroups );
7520+ postProcessResults (newItems, context.CodeCompletionKind , DC);
74677521 }
74687522
74697523 handleResults (context.takeResults ());
0 commit comments