Skip to content

Commit c21a75d

Browse files
committed
[CodeCompletion] Migrate CaseStmtBeginning to solver-based
1 parent 1e1d4e3 commit c21a75d

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

include/swift/IDE/ExprCompletion.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class ExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
3131
/// functions is supported.
3232
bool IsInAsyncContext;
3333

34+
/// If unresolved member lookup is enabled in the completion callback,
35+
/// the type that the unresolved member lookup should be performed on,
36+
/// otherwise a null type.
37+
Type UnresolvedMemberBaseType;
38+
3439
/// Types of variables that were determined in the solution that produced
3540
/// this result. This in particular includes parameters of closures that
3641
/// were type-checked with the code completion expression.
@@ -54,6 +59,11 @@ class ExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
5459
/// in almost all cases and acceptable results in the other cases.
5560
SmallVector<Type, 4> ExpectedTypes;
5661

62+
/// When \c true, unresolved member completions of the expected types are
63+
/// also reported when delivering results. Used in places that frequently
64+
/// use unresolved members such as enum cases.
65+
bool AddUnresolvedMemberCompletions;
66+
5767
SmallVector<Result, 4> Results;
5868

5969
/// Adds the given type to \c ExpectedTypes unless \c ExpectedTypes already
@@ -62,17 +72,22 @@ class ExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
6272

6373
/// Adds the result with the given parameters to \c Results unless \c Results
6474
/// already contains an entry with exactly the same values.
75+
/// If \c AddUnresolvedMemberCompletions is false, the
76+
/// \p UnresolvedMemberBaseType is ignored.
6577
void addResult(
6678
bool IsImplicitSingleExpressionReturn, bool IsInAsyncContext,
79+
Type UnresolvedMemberBaseType,
6780
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes);
6881

6982
void sawSolutionImpl(const constraints::Solution &solution) override;
7083

7184
public:
7285
/// \param DC The decl context in which the \p CompletionExpr occurs.
7386
ExprTypeCheckCompletionCallback(CodeCompletionExpr *CompletionExpr,
74-
DeclContext *DC)
75-
: CompletionExpr(CompletionExpr), DC(DC) {}
87+
DeclContext *DC,
88+
bool AddUnresolvedMemberCompletions)
89+
: CompletionExpr(CompletionExpr), DC(DC),
90+
AddUnresolvedMemberCompletions(AddUnresolvedMemberCompletions) {}
7691

7792
/// \param CCLoc The location of the code completion token.
7893
void deliverResults(SourceLoc CCLoc,

lib/IDE/CodeCompletion.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -1405,13 +1405,16 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
14051405
return true;
14061406
}
14071407
case CompletionKind::AccessorBeginning:
1408+
case CompletionKind::CaseStmtBeginning:
14081409
case CompletionKind::ForEachSequence:
14091410
case CompletionKind::PostfixExprBeginning:
14101411
case CompletionKind::StmtOrExpr: {
14111412
assert(CurDeclContext);
14121413

1413-
ExprTypeCheckCompletionCallback Lookup(CodeCompleteTokenExpr,
1414-
CurDeclContext);
1414+
bool AddUnresolvedMemberCompletions =
1415+
(Kind == CompletionKind::CaseStmtBeginning);
1416+
ExprTypeCheckCompletionCallback Lookup(
1417+
CodeCompleteTokenExpr, CurDeclContext, AddUnresolvedMemberCompletions);
14151418
if (CodeCompleteTokenExpr) {
14161419
// 'CodeCompletionTokenExpr == nullptr' happens when completing e.g.
14171420
// var x: Int {
@@ -1583,6 +1586,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
15831586
case CompletionKind::PostfixExprBeginning:
15841587
case CompletionKind::AfterPoundExpr:
15851588
case CompletionKind::AccessorBeginning:
1589+
case CompletionKind::CaseStmtBeginning:
15861590
llvm_unreachable("should be already handled");
15871591
return;
15881592

@@ -1681,16 +1685,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
16811685
break;
16821686
}
16831687

1684-
case CompletionKind::CaseStmtBeginning: {
1685-
ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
1686-
Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
1687-
ContextInfo.isImplicitSingleExpressionReturn());
1688-
Lookup.setIdealExpectedType(CodeCompleteTokenExpr->getType());
1689-
Lookup.getUnresolvedMemberCompletions(ContextInfo.getPossibleTypes());
1690-
DoPostfixExprBeginning();
1691-
break;
1692-
}
1693-
16941688
case CompletionKind::NominalMemberBeginning: {
16951689
CompletionOverrideLookup OverrideLookup(CompletionContext.getResultSink(),
16961690
P.Context, CurDeclContext,

lib/IDE/CompletionLookup.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2683,6 +2683,8 @@ void CompletionLookup::getUnresolvedMemberCompletions(Type T) {
26832683
if (!T->mayHaveMembers())
26842684
return;
26852685

2686+
NeedLeadingDot = !HaveDot;
2687+
26862688
if (auto objT = T->getOptionalObjectType()) {
26872689
// Add 'nil' keyword with erasing '.' instruction.
26882690
unsigned bytesToErase = 0;

lib/IDE/ExprCompletion.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ bool ExprTypeCheckCompletionCallback::Result::operator==(
4242
return IsImplicitSingleExpressionReturn ==
4343
Other.IsImplicitSingleExpressionReturn &&
4444
IsInAsyncContext == Other.IsInAsyncContext &&
45+
nullableTypesEqual(UnresolvedMemberBaseType,
46+
Other.UnresolvedMemberBaseType) &&
4547
solutionSpecificVarTypesEqual(SolutionSpecificVarTypes,
4648
Other.SolutionSpecificVarTypes);
4749
}
@@ -58,9 +60,13 @@ void ExprTypeCheckCompletionCallback::addExpectedType(Type ExpectedType) {
5860

5961
void ExprTypeCheckCompletionCallback::addResult(
6062
bool IsImplicitSingleExpressionReturn, bool IsInAsyncContext,
63+
Type UnresolvedMemberBaseType,
6164
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes) {
65+
if (!AddUnresolvedMemberCompletions) {
66+
UnresolvedMemberBaseType = Type();
67+
}
6268
Result NewResult = {IsImplicitSingleExpressionReturn, IsInAsyncContext,
63-
SolutionSpecificVarTypes};
69+
UnresolvedMemberBaseType, SolutionSpecificVarTypes};
6470
if (llvm::is_contained(Results, NewResult)) {
6571
return;
6672
}
@@ -80,10 +86,12 @@ void ExprTypeCheckCompletionCallback::sawSolutionImpl(
8086
llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes;
8187
getSolutionSpecificVarTypes(S, SolutionSpecificVarTypes);
8288

83-
addResult(ImplicitReturn, IsAsync, SolutionSpecificVarTypes);
89+
addResult(ImplicitReturn, IsAsync, ExpectedTy, SolutionSpecificVarTypes);
8490
addExpectedType(ExpectedTy);
8591

8692
if (auto PatternMatchType = getPatternMatchType(S, CompletionExpr)) {
93+
addResult(ImplicitReturn, IsAsync, PatternMatchType,
94+
SolutionSpecificVarTypes);
8795
addExpectedType(PatternMatchType);
8896
}
8997
}
@@ -104,6 +112,9 @@ void ExprTypeCheckCompletionCallback::deliverResults(
104112

105113
Lookup.getValueCompletionsInDeclContext(CCLoc);
106114
Lookup.getSelfTypeCompletionInDeclContext(CCLoc, /*isForDeclResult=*/false);
115+
if (Result.UnresolvedMemberBaseType) {
116+
Lookup.getUnresolvedMemberCompletions(Result.UnresolvedMemberBaseType);
117+
}
107118
}
108119

109120
deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);

test/IDE/complete_enum_elements.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ enum FooEnum: CaseIterable {
1414
}
1515

1616
// FOO_ENUM_TYPE_CONTEXT: Begin completions
17-
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Identical]: .Foo1[#FooEnum#]{{; name=.+$}}
18-
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Identical]: .Foo2[#FooEnum#]{{; name=.+$}}
19-
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[StaticVar]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Identical]: .alias1[#FooEnum#]; name=alias1
17+
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/TypeRelation[Identical]: .Foo1[#FooEnum#]{{; name=.+$}}
18+
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/TypeRelation[Identical]: .Foo2[#FooEnum#]{{; name=.+$}}
19+
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[StaticVar]/CurrNominal/TypeRelation[Identical]: .alias1[#FooEnum#]; name=alias1
2020
// FOO_ENUM_TYPE_CONTEXT: End completions
2121

2222
// FOO_ENUM_NO_DOT: Begin completions
@@ -202,8 +202,8 @@ enum QuxEnum : Int {
202202
}
203203

204204
// QUX_ENUM_TYPE_CONTEXT: Begin completions
205-
// QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Identical]: .Qux1[#QuxEnum#]{{; name=.+$}}
206-
// QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Identical]: .Qux2[#QuxEnum#]{{; name=.+$}}
205+
// QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/TypeRelation[Identical]: .Qux1[#QuxEnum#]{{; name=.+$}}
206+
// QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/CurrNominal/TypeRelation[Identical]: .Qux2[#QuxEnum#]{{; name=.+$}}
207207
// QUX_ENUM_TYPE_CONTEXT: End completions
208208

209209
// QUX_ENUM_NO_DOT: Begin completions, 7 items

0 commit comments

Comments
 (0)