Skip to content

Commit 50eafca

Browse files
committed
[Code Completion] Extract CodeCompletionResultTypeRelation to a top-level type
Preliminary work to compute the type relation when constructing a contextual code completion result.
1 parent e8c76a1 commit 50eafca

File tree

7 files changed

+115
-120
lines changed

7 files changed

+115
-120
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,31 @@ enum class CodeCompletionResultKind : uint8_t {
701701
MAX_VALUE = BuiltinOperator
702702
};
703703

704+
/// Describes the relationship between the type of the completion results and
705+
/// the expected type at the code completion position.
706+
enum class CodeCompletionResultTypeRelation : uint8_t {
707+
/// The result does not have a type (e.g. keyword).
708+
NotApplicable,
709+
710+
/// The type relation have not been calculated.
711+
Unknown,
712+
713+
/// The relationship of the result's type to the expected type is not
714+
/// invalid, not convertible, and not identical.
715+
Unrelated,
716+
717+
/// The result's type is invalid at the expected position.
718+
Invalid,
719+
720+
/// The result's type is convertible to the type of the expected.
721+
Convertible,
722+
723+
/// The result's type is identical to the type of the expected.
724+
Identical,
725+
726+
MAX_VALUE = Identical
727+
};
728+
704729
/// The parts of a \c CodeCompletionResult that are not dependent on the context
705730
/// it appears in and can thus be cached.
706731
class ContextFreeCodeCompletionResult {
@@ -909,34 +934,6 @@ class ContextFreeCodeCompletionResult {
909934
/// A single code completion result enriched with information that depend on
910935
/// the completion's usage context.
911936
class CodeCompletionResult {
912-
public:
913-
/// Describes the relationship between the type of the completion results and
914-
/// the expected type at the code completion position.
915-
enum class ExpectedTypeRelation : uint8_t {
916-
/// The result does not have a type (e.g. keyword).
917-
NotApplicable,
918-
919-
/// The type relation have not been calculated.
920-
Unknown,
921-
922-
/// The relationship of the result's type to the expected type is not
923-
/// invalid, not convertible, and not identical.
924-
Unrelated,
925-
926-
/// The result's type is invalid at the expected position.
927-
Invalid,
928-
929-
/// The result's type is convertible to the type of the expected.
930-
Convertible,
931-
932-
/// The result's type is identical to the type of the expected.
933-
Identical,
934-
935-
MAX_VALUE = Identical
936-
};
937-
938-
939-
private:
940937
const ContextFreeCodeCompletionResult &ContextFree;
941938
SemanticContextKind SemanticContext : 3;
942939
static_assert(int(SemanticContextKind::MAX_VALUE) < 1 << 3, "");
@@ -962,7 +959,9 @@ class CodeCompletionResult {
962959
static const unsigned MaxNumBytesToErase = 127;
963960

964961
private:
965-
ExpectedTypeRelation TypeDistance : 3;
962+
CodeCompletionResultTypeRelation TypeDistance : 3;
963+
static_assert(int(CodeCompletionResultTypeRelation::MAX_VALUE) < 1 << 3, "");
964+
966965
public:
967966
/// Enrich a \c ContextFreeCodeCompletionResult with the following contextual
968967
/// information.
@@ -972,7 +971,7 @@ class CodeCompletionResult {
972971
CodeCompletionResult(const ContextFreeCodeCompletionResult &ContextFree,
973972
SemanticContextKind SemanticContext,
974973
CodeCompletionFlair Flair, uint8_t NumBytesToErase,
975-
ExpectedTypeRelation TypeDistance,
974+
CodeCompletionResultTypeRelation TypeDistance,
976975
ContextualNotRecommendedReason NotRecommended,
977976
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
978977
StringRef DiagnosticMessage)
@@ -1024,7 +1023,9 @@ class CodeCompletionResult {
10241023

10251024
bool isSystem() const { return getContextFreeResult().isSystem(); }
10261025

1027-
ExpectedTypeRelation getExpectedTypeRelation() const { return TypeDistance; }
1026+
CodeCompletionResultTypeRelation getExpectedTypeRelation() const {
1027+
return TypeDistance;
1028+
}
10281029

10291030
/// Get the contextual not-recommended reason. This disregards context-free
10301031
/// not recommended reasons.

lib/IDE/CodeCompletion.cpp

Lines changed: 54 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -600,19 +600,19 @@ void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
600600
Prefix.append("]");
601601
}
602602
switch (getExpectedTypeRelation()) {
603-
case ExpectedTypeRelation::Invalid:
604-
Prefix.append("/TypeRelation[Invalid]");
605-
break;
606-
case ExpectedTypeRelation::Identical:
607-
Prefix.append("/TypeRelation[Identical]");
608-
break;
609-
case ExpectedTypeRelation::Convertible:
610-
Prefix.append("/TypeRelation[Convertible]");
611-
break;
612-
case ExpectedTypeRelation::NotApplicable:
613-
case ExpectedTypeRelation::Unknown:
614-
case ExpectedTypeRelation::Unrelated:
615-
break;
603+
case CodeCompletionResultTypeRelation::Invalid:
604+
Prefix.append("/TypeRelation[Invalid]");
605+
break;
606+
case CodeCompletionResultTypeRelation::Identical:
607+
Prefix.append("/TypeRelation[Identical]");
608+
break;
609+
case CodeCompletionResultTypeRelation::Convertible:
610+
Prefix.append("/TypeRelation[Convertible]");
611+
break;
612+
case CodeCompletionResultTypeRelation::NotApplicable:
613+
case CodeCompletionResultTypeRelation::Unknown:
614+
case CodeCompletionResultTypeRelation::Unrelated:
615+
break;
616616
}
617617

618618
Prefix.append(": ");
@@ -1141,44 +1141,44 @@ ArrayRef<StringRef> copyAssociatedUSRs(llvm::BumpPtrAllocator &Allocator,
11411141
return ArrayRef<StringRef>();
11421142
}
11431143

1144-
static CodeCompletionResult::ExpectedTypeRelation
1144+
static CodeCompletionResultTypeRelation
11451145
calculateTypeRelation(Type Ty, Type ExpectedTy, const DeclContext *DC) {
11461146
if (Ty.isNull() || ExpectedTy.isNull() ||
11471147
Ty->is<ErrorType>() ||
11481148
ExpectedTy->is<ErrorType>())
1149-
return CodeCompletionResult::ExpectedTypeRelation::Unrelated;
1149+
return CodeCompletionResultTypeRelation::Unrelated;
11501150

11511151
// Equality/Conversion of GenericTypeParameterType won't account for
11521152
// requirements – ignore them
11531153
if (!Ty->hasTypeParameter() && !ExpectedTy->hasTypeParameter()) {
11541154
if (Ty->isEqual(ExpectedTy))
1155-
return CodeCompletionResult::ExpectedTypeRelation::Identical;
1155+
return CodeCompletionResultTypeRelation::Identical;
11561156
bool isAny = false;
11571157
isAny |= ExpectedTy->isAny();
11581158
isAny |= ExpectedTy->is<ArchetypeType>() &&
11591159
!ExpectedTy->castTo<ArchetypeType>()->hasRequirements();
11601160

11611161
if (!isAny && isConvertibleTo(Ty, ExpectedTy, /*openArchetypes=*/true,
11621162
*const_cast<DeclContext *>(DC)))
1163-
return CodeCompletionResult::ExpectedTypeRelation::Convertible;
1163+
return CodeCompletionResultTypeRelation::Convertible;
11641164
}
11651165
if (auto FT = Ty->getAs<AnyFunctionType>()) {
11661166
if (FT->getResult()->isVoid())
1167-
return CodeCompletionResult::ExpectedTypeRelation::Invalid;
1167+
return CodeCompletionResultTypeRelation::Invalid;
11681168
}
1169-
return CodeCompletionResult::ExpectedTypeRelation::Unrelated;
1169+
return CodeCompletionResultTypeRelation::Unrelated;
11701170
}
11711171

1172-
static CodeCompletionResult::ExpectedTypeRelation
1172+
static CodeCompletionResultTypeRelation
11731173
calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
11741174
const DeclContext *DC) {
11751175
if (typeContext.empty())
1176-
return CodeCompletionResult::ExpectedTypeRelation::Unknown;
1176+
return CodeCompletionResultTypeRelation::Unknown;
11771177

11781178
if (auto funcTy = Ty->getAs<AnyFunctionType>())
11791179
Ty = funcTy->removeArgumentLabels(1);
11801180

1181-
auto Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
1181+
auto Result = CodeCompletionResultTypeRelation::Unrelated;
11821182
for (auto expectedTy : typeContext.possibleTypes) {
11831183
// Do not use Void type context for a single-expression body, since the
11841184
// implicit return does not constrain the expression.
@@ -1197,8 +1197,8 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
11971197
// Map invalid -> unrelated when in a single-expression body, since the
11981198
// input may be incomplete.
11991199
if (typeContext.isImplicitSingleExpressionReturn &&
1200-
Result == CodeCompletionResult::ExpectedTypeRelation::Invalid)
1201-
Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
1200+
Result == CodeCompletionResultTypeRelation::Invalid)
1201+
Result = CodeCompletionResultTypeRelation::Unrelated;
12021202
}
12031203
return Result;
12041204
}
@@ -2914,7 +2914,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29142914
Builder.addTypeAnnotation("Selector");
29152915
// This function is called only if the context type is 'Selector'.
29162916
Builder.setExpectedTypeRelation(
2917-
CodeCompletionResult::ExpectedTypeRelation::Identical);
2917+
CodeCompletionResultTypeRelation::Identical);
29182918
}
29192919

29202920
void addPoundKeyPath(bool needPound) {
@@ -2934,7 +2934,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29342934
Builder.addTypeAnnotation("String");
29352935
// This function is called only if the context type is 'String'.
29362936
Builder.setExpectedTypeRelation(
2937-
CodeCompletionResult::ExpectedTypeRelation::Identical);
2937+
CodeCompletionResultTypeRelation::Identical);
29382938
}
29392939

29402940
SemanticContextKind getSemanticContextKind(const ValueDecl *VD) {
@@ -3276,7 +3276,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32763276
expectedTypeContext.requiresNonVoid() &&
32773277
ResultType->isVoid()) {
32783278
Builder.setExpectedTypeRelation(
3279-
CodeCompletionResult::ExpectedTypeRelation::Invalid);
3279+
CodeCompletionResultTypeRelation::Invalid);
32803280
}
32813281
};
32823282

@@ -3655,7 +3655,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
36553655
auto maxRel = calculateMaxTypeRelation(funcTy, expectedTypeContext,
36563656
CurrDeclContext);
36573657
useFunctionReference =
3658-
maxRel >= CodeCompletionResult::ExpectedTypeRelation::Convertible;
3658+
maxRel >= CodeCompletionResultTypeRelation::Convertible;
36593659
}
36603660
if (!useFunctionReference)
36613661
return false;
@@ -4325,14 +4325,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43254325
if (!T)
43264326
continue;
43274327

4328-
auto typeRelation = CodeCompletionResult::ExpectedTypeRelation::Identical;
4328+
auto typeRelation = CodeCompletionResultTypeRelation::Identical;
43294329
// Convert through optional types unless we're looking for a protocol
43304330
// that Optional itself conforms to.
43314331
if (kind != CodeCompletionLiteralKind::NilLiteral) {
43324332
if (auto optionalObjT = T->getOptionalObjectType()) {
43334333
T = optionalObjT;
4334-
typeRelation =
4335-
CodeCompletionResult::ExpectedTypeRelation::Convertible;
4334+
typeRelation = CodeCompletionResultTypeRelation::Convertible;
43364335
}
43374336
}
43384337

@@ -4352,8 +4351,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
43524351
builder.addTypeAnnotation(defaultTy, PrintOptions());
43534352
builder.setExpectedTypeRelation(
43544353
expectedTypeContext.possibleTypes.empty()
4355-
? CodeCompletionResult::ExpectedTypeRelation::Unknown
4356-
: CodeCompletionResult::ExpectedTypeRelation::Unrelated);
4354+
? CodeCompletionResultTypeRelation::Unknown
4355+
: CodeCompletionResultTypeRelation::Unrelated);
43574356
}
43584357
}
43594358

@@ -4511,7 +4510,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
45114510
if (T && T->is<TupleType>() && !T->isVoid()) {
45124511
addTypeAnnotation(builder, T);
45134512
builder.setExpectedTypeRelation(
4514-
CodeCompletionResult::ExpectedTypeRelation::Identical);
4513+
CodeCompletionResultTypeRelation::Identical);
45154514
break;
45164515
}
45174516
}
@@ -4736,7 +4735,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
47364735
}
47374736
addTypeAnnotation(Builder, Ty);
47384737
Builder.setExpectedTypeRelation(
4739-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
4738+
CodeCompletionResultTypeRelation::NotApplicable);
47404739
}
47414740
}
47424741

@@ -5342,7 +5341,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
53425341
CodeCompletionResultKind::Declaration,
53435342
SemanticContextKind::Super, {});
53445343
Builder.setExpectedTypeRelation(
5345-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
5344+
CodeCompletionResultTypeRelation::NotApplicable);
53465345
Builder.setAssociatedDecl(FD);
53475346
addValueOverride(FD, Reason, dynamicLookupInfo, Builder, hasFuncIntroducer);
53485347
Builder.addBraceStmtWithCursor();
@@ -5371,7 +5370,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
53715370
CodeCompletionResultKind::Declaration,
53725371
SemanticContextKind::Super, {});
53735372
Builder.setExpectedTypeRelation(
5374-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
5373+
CodeCompletionResultTypeRelation::NotApplicable);
53755374
Builder.setAssociatedDecl(SD);
53765375
addValueOverride(SD, Reason, dynamicLookupInfo, Builder, false);
53775376
Builder.addBraceStmtWithCursor();
@@ -5383,7 +5382,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
53835382
CodeCompletionResultKind::Declaration,
53845383
SemanticContextKind::Super, {});
53855384
Builder.setExpectedTypeRelation(
5386-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
5385+
CodeCompletionResultTypeRelation::NotApplicable);
53875386
Builder.setAssociatedDecl(ATD);
53885387
if (!hasTypealiasIntroducer && !hasAccessModifier)
53895388
(void)addAccessControl(ATD, Builder);
@@ -5400,7 +5399,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
54005399
CodeCompletionResultKind::Declaration,
54015400
SemanticContextKind::Super, {});
54025401
Builder.setExpectedTypeRelation(
5403-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
5402+
CodeCompletionResultTypeRelation::NotApplicable);
54045403
Builder.setAssociatedDecl(CD);
54055404

54065405
CodeCompletionStringPrinter printer(Builder);
@@ -5600,7 +5599,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
56005599
SemanticContextKind::CurrentNominal,
56015600
{});
56025601
Builder.setExpectedTypeRelation(
5603-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
5602+
CodeCompletionResultTypeRelation::NotApplicable);
56045603

56055604
if (!hasFuncIntroducer) {
56065605
if (!hasAccessModifier &&
@@ -6034,12 +6033,12 @@ static bool isClangSubModule(ModuleDecl *TheModule) {
60346033
return false;
60356034
}
60366035

6037-
static void
6038-
addKeyword(CodeCompletionResultSink &Sink, StringRef Name,
6039-
CodeCompletionKeywordKind Kind, StringRef TypeAnnotation = "",
6040-
CodeCompletionResult::ExpectedTypeRelation TypeRelation =
6041-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
6042-
CodeCompletionFlair Flair = {}) {
6036+
static void addKeyword(CodeCompletionResultSink &Sink, StringRef Name,
6037+
CodeCompletionKeywordKind Kind,
6038+
StringRef TypeAnnotation = "",
6039+
CodeCompletionResultTypeRelation TypeRelation =
6040+
CodeCompletionResultTypeRelation::NotApplicable,
6041+
CodeCompletionFlair Flair = {}) {
60436042
CodeCompletionResultBuilder Builder(Sink, CodeCompletionResultKind::Keyword,
60446043
SemanticContextKind::None, {});
60456044
Builder.setKeywordKind(Kind);
@@ -6178,10 +6177,9 @@ static void addDeclKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
61786177
DeclAttribute::isDistributedOnly(*DAK))
61796178
return;
61806179

6181-
addKeyword(
6182-
Sink, Name, Kind, /*TypeAnnotation=*/"",
6183-
/*TypeRelation=*/CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
6184-
getFlair(Kind, DAK));
6180+
addKeyword(Sink, Name, Kind, /*TypeAnnotation=*/"",
6181+
/*TypeRelation=*/CodeCompletionResultTypeRelation::NotApplicable,
6182+
getFlair(Kind, DAK));
61856183
};
61866184

61876185
#define DECL_KEYWORD(kw) \
@@ -6213,8 +6211,7 @@ static void addStmtKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
62136211
if (!MaybeFuncBody && Kind == CodeCompletionKeywordKind::kw_return)
62146212
return;
62156213
addKeyword(Sink, Name, Kind, "",
6216-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
6217-
flair);
6214+
CodeCompletionResultTypeRelation::NotApplicable, flair);
62186215
};
62196216
#define STMT_KEYWORD(kw) AddStmtKeyword(#kw, CodeCompletionKeywordKind::kw_##kw);
62206217
#include "swift/Syntax/TokenKinds.def"
@@ -6249,13 +6246,13 @@ static void addExprKeywords(CodeCompletionResultSink &Sink, DeclContext *DC) {
62496246

62506247
// Expr keywords.
62516248
addKeyword(Sink, "try", CodeCompletionKeywordKind::kw_try, "",
6252-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
6249+
CodeCompletionResultTypeRelation::NotApplicable, flair);
62536250
addKeyword(Sink, "try!", CodeCompletionKeywordKind::kw_try, "",
6254-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
6251+
CodeCompletionResultTypeRelation::NotApplicable, flair);
62556252
addKeyword(Sink, "try?", CodeCompletionKeywordKind::kw_try, "",
6256-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
6253+
CodeCompletionResultTypeRelation::NotApplicable, flair);
62576254
addKeyword(Sink, "await", CodeCompletionKeywordKind::None, "",
6258-
CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
6255+
CodeCompletionResultTypeRelation::NotApplicable, flair);
62596256
}
62606257

62616258
static void addOpaqueTypeKeyword(CodeCompletionResultSink &Sink) {
@@ -7512,8 +7509,7 @@ copyCodeCompletionResults(CodeCompletionResultSink &targetSink,
75127509
auto contextualResult = new (*targetSink.Allocator) CodeCompletionResult(
75137510
*contextFreeResult, SemanticContextKind::OtherModule,
75147511
CodeCompletionFlair(),
7515-
/*numBytesToErase=*/0,
7516-
CodeCompletionResult::ExpectedTypeRelation::Unknown,
7512+
/*numBytesToErase=*/0, CodeCompletionResultTypeRelation::Unknown,
75177513
ContextualNotRecommendedReason::None,
75187514
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"");
75197515
targetSink.Results.push_back(contextualResult);

0 commit comments

Comments
 (0)