[Completion] Fix invertible type completion

The previous logic for this was unused, replace
it with new logic that consults
InvertibleProtocols.def for the list of protocols
to suggest.

rdar://139212286
This commit is contained in:
Hamish Knight
2024-11-19 11:37:52 +00:00
parent 51dadb03f0
commit c19d049493
7 changed files with 46 additions and 29 deletions

View File

@@ -204,6 +204,7 @@ enum class CompletionKind : uint8_t {
TypeSimpleBeginning,
TypeSimpleWithDot,
TypeSimpleWithoutDot,
TypeSimpleInverted,
CaseStmtKeyword,
CaseStmtBeginning,
NominalMemberBeginning,
@@ -231,9 +232,6 @@ enum class CompletionKind : uint8_t {
TypeAttrBeginning,
TypeAttrInheritanceBeginning,
OptionalBinding,
/// Completion after `~` in an inheritance clause.
WithoutConstraintType
};
enum class CodeCompletionDiagnosticSeverity : uint8_t {

View File

@@ -593,6 +593,9 @@ public:
void getTypeCompletions(Type BaseType);
/// Add completions for types that can appear after a \c ~ prefix.
void getInvertedTypeCompletions();
void getGenericRequirementCompletions(DeclContext *DC,
SourceLoc CodeCompletionLoc);
@@ -631,8 +634,6 @@ public:
void getStmtLabelCompletions(SourceLoc Loc, bool isContinue);
void getOptionalBindingCompletions(SourceLoc Loc);
void addWithoutConstraintTypes();
};
} // end namespace ide

View File

@@ -204,6 +204,9 @@ public:
/// Complete a given \c type-simple when there is no trailing dot.
virtual void completeTypeSimpleWithoutDot(TypeRepr *TR){};
/// Complete a given \c type-simple following a \c ~ prefix.
virtual void completeTypeSimpleInverted() {};
/// Complete the beginning of a case statement at the top of switch stmt.
virtual void completeCaseStmtKeyword() {};
@@ -291,8 +294,6 @@ public:
virtual void completeTypeAttrInheritanceBeginning() {};
virtual void completeOptionalBinding(){};
virtual void completeWithoutConstraintType(){};
};
class DoneParsingCallback {

View File

@@ -267,6 +267,7 @@ public:
void completeTypeSimpleBeginning() override;
void completeTypeSimpleWithDot(TypeRepr *TR) override;
void completeTypeSimpleWithoutDot(TypeRepr *TR) override;
void completeTypeSimpleInverted() override;
void completeCaseStmtKeyword() override;
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
@@ -305,7 +306,6 @@ public:
void completeTypeAttrBeginning() override;
void completeTypeAttrInheritanceBeginning() override;
void completeOptionalBinding() override;
void completeWithoutConstraintType() override;
void doneParsing(SourceFile *SrcFile) override;
@@ -509,6 +509,11 @@ void CodeCompletionCallbacksImpl::completeTypeSimpleWithoutDot(TypeRepr *TR) {
CurDeclContext = P.CurDeclContext;
}
void CodeCompletionCallbacksImpl::completeTypeSimpleInverted() {
Kind = CompletionKind::TypeSimpleInverted;
CurDeclContext = P.CurDeclContext;
}
void CodeCompletionCallbacksImpl::completeCaseStmtKeyword() {
Kind = CompletionKind::CaseStmtKeyword;
CurDeclContext = P.CurDeclContext;
@@ -646,11 +651,6 @@ void CodeCompletionCallbacksImpl::completeOptionalBinding() {
Kind = CompletionKind::OptionalBinding;
}
void CodeCompletionCallbacksImpl::completeWithoutConstraintType() {
CurDeclContext = P.CurDeclContext;
Kind = CompletionKind::WithoutConstraintType;
}
void CodeCompletionCallbacksImpl::completeTypeAttrBeginning() {
CurDeclContext = P.CurDeclContext;
Kind = CompletionKind::TypeAttrBeginning;
@@ -993,7 +993,6 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
case CompletionKind::TypeAttrBeginning:
case CompletionKind::TypeAttrInheritanceBeginning:
case CompletionKind::OptionalBinding:
case CompletionKind::WithoutConstraintType:
break;
case CompletionKind::EffectsSpecifier:
@@ -1066,6 +1065,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
break;
case CompletionKind::CaseStmtBeginning:
case CompletionKind::TypeSimpleWithDot:
case CompletionKind::TypeSimpleInverted:
break;
case CompletionKind::TypeSimpleWithoutDot:
@@ -1296,9 +1296,9 @@ void swift::ide::postProcessCompletionResults(
Kind != CompletionKind::TypeSimpleBeginning &&
Kind != CompletionKind::TypeSimpleWithoutDot &&
Kind != CompletionKind::TypeSimpleWithDot &&
Kind != CompletionKind::TypeSimpleInverted &&
Kind != CompletionKind::TypeDeclResultBeginning &&
Kind != CompletionKind::GenericRequirement &&
Kind != CompletionKind::WithoutConstraintType) {
Kind != CompletionKind::GenericRequirement) {
flair |= CodeCompletionFlairBit::RareTypeAtCurrentPosition;
modified = true;
}
@@ -1807,6 +1807,11 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
break;
}
case CompletionKind::TypeSimpleInverted: {
Lookup.getInvertedTypeCompletions();
break;
}
case CompletionKind::NominalMemberBeginning: {
CompletionOverrideLookup OverrideLookup(CompletionContext.getResultSink(),
P.Context, CurDeclContext,
@@ -1955,11 +1960,6 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
break;
}
case CompletionKind::WithoutConstraintType: {
Lookup.addWithoutConstraintTypes();
break;
}
case CompletionKind::AfterIfStmtElse:
case CompletionKind::CaseStmtKeyword:
case CompletionKind::EffectsSpecifier:

View File

@@ -2964,6 +2964,22 @@ void CompletionLookup::getTypeCompletions(Type BaseType) {
}
}
void CompletionLookup::getInvertedTypeCompletions() {
Kind = LookupKind::Type;
auto addCompletion = [&](InvertibleProtocolKind invertableKind) {
auto *P = Ctx.getProtocol(getKnownProtocolKind(invertableKind));
if (!P)
return;
addNominalTypeRef(P, DeclVisibilityKind::VisibleAtTopLevel,
DynamicLookupInfo());
};
#define INVERTIBLE_PROTOCOL(Name, Bit) \
addCompletion(InvertibleProtocolKind::Name);
#include "swift/ABI/InvertibleProtocols.def"
}
void CompletionLookup::getGenericRequirementCompletions(
DeclContext *DC, SourceLoc CodeCompletionLoc) {
auto genericSig = DC->getGenericSignatureOfContext();
@@ -3490,9 +3506,3 @@ void CompletionLookup::getOptionalBindingCompletions(SourceLoc Loc) {
lookupVisibleDecls(FilteringConsumer, Loc, CurrDeclContext,
/*IncludeTopLevel=*/false);
}
void CompletionLookup::addWithoutConstraintTypes() {
auto *CopyableDecl = Ctx.getProtocol(KnownProtocolKind::Copyable);
addNominalTypeRef(CopyableDecl, DeclVisibilityKind::VisibleAtTopLevel,
DynamicLookupInfo());
}

View File

@@ -227,7 +227,11 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
break;
case tok::code_complete:
if (CodeCompletionCallbacks) {
CodeCompletionCallbacks->completeTypeSimpleBeginning();
if (tildeLoc.isValid()) {
CodeCompletionCallbacks->completeTypeSimpleInverted();
} else {
CodeCompletionCallbacks->completeTypeSimpleBeginning();
}
}
return makeParserCodeCompletionResult<TypeRepr>(
ErrorTypeRepr::create(Context, consumeToken(tok::code_complete)));

View File

@@ -1,4 +1,7 @@
// RUN: %batch-code-completion
// rdar://139212286 - We should only suggest invertible types here.
struct FileDescriptor: ~#^COMPLETE^# {}
// COMPLETE: Decl[Protocol]/OtherModule[Swift]/IsSystem: Copyable[#Copyable#]; name=Copyable
// COMPLETE: Begin completions, 2 items
// COMPLETE-DAG: Decl[Protocol]/OtherModule[Swift]/IsSystem: Copyable[#Copyable#]; name=Copyable
// COMPLETE-DAG: Decl[Protocol]/OtherModule[Swift]/IsSystem: Escapable[#Escapable#]; name=Escapable