@@ -1594,6 +1594,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1594
1594
std::vector<Type> ExpectedTypes;
1595
1595
1596
1596
bool HaveDot = false ;
1597
+ bool IsUnwrappedOptional = false ;
1597
1598
SourceLoc DotLoc;
1598
1599
bool NeedLeadingDot = false ;
1599
1600
@@ -1734,6 +1735,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1734
1735
this ->DotLoc = DotLoc;
1735
1736
}
1736
1737
1738
+ void setIsUnwrappedOptional (bool value) {
1739
+ IsUnwrappedOptional = value;
1740
+ }
1741
+
1737
1742
void setIsStaticMetatype (bool value) {
1738
1743
IsStaticMetatype = value;
1739
1744
}
@@ -3131,9 +3136,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3131
3136
return false ;
3132
3137
}
3133
3138
3134
- void getTupleExprCompletions (TupleType *ExprType) {
3139
+ bool tryTupleExprCompletions (Type ExprType) {
3140
+ auto *TT = ExprType->getAs <TupleType>();
3141
+ if (!TT)
3142
+ return false ;
3143
+
3135
3144
unsigned Index = 0 ;
3136
- for (auto TupleElt : ExprType ->getElements ()) {
3145
+ for (auto TupleElt : TT ->getElements ()) {
3137
3146
CodeCompletionResultBuilder Builder (
3138
3147
Sink,
3139
3148
CodeCompletionResult::ResultKind::Pattern,
@@ -3152,6 +3161,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3152
3161
addTypeAnnotation (Builder, TupleElt.getType ());
3153
3162
Index++;
3154
3163
}
3164
+ return true ;
3155
3165
}
3156
3166
3157
3167
bool tryFunctionCallCompletions (Type ExprType, const ValueDecl *VD) {
@@ -3167,7 +3177,24 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3167
3177
return false ;
3168
3178
}
3169
3179
3170
- bool tryStdlibOptionalCompletions (Type ExprType, bool isIUO) {
3180
+ bool tryModuleCompletions (Type ExprType) {
3181
+ if (auto MT = ExprType->getAs <ModuleType>()) {
3182
+ ModuleDecl *M = MT->getModule ();
3183
+ if (CurrDeclContext->getParentModule () != M) {
3184
+ // Only use the cache if it is not the current module.
3185
+ RequestedCachedResults = RequestedResultsTy::fromModule (M)
3186
+ .needLeadingDot (needDot ());
3187
+ return true ;
3188
+ }
3189
+ }
3190
+ return false ;
3191
+ }
3192
+
3193
+ // / If the given ExprType is optional, this adds completions for the unwrapped
3194
+ // / type.
3195
+ // /
3196
+ // / \return true if the given type was Optional .
3197
+ bool tryUnwrappedCompletions (Type ExprType, bool isIUO) {
3171
3198
// FIXME: consider types convertible to T?.
3172
3199
3173
3200
ExprType = ExprType->getRValueType ();
@@ -3177,10 +3204,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3177
3204
if (Type Unwrapped = ExprType->getOptionalObjectType ()) {
3178
3205
lookupVisibleMemberDecls (*this , Unwrapped, CurrDeclContext,
3179
3206
TypeResolver.get (), IncludeInstanceMembers);
3180
- } else {
3181
- llvm_unreachable (" IUOs should always be optionals." );
3207
+ return true ;
3182
3208
}
3183
- } else if (Type Unwrapped = ExprType->getOptionalObjectType ()) {
3209
+ assert (IsUnwrappedOptional && " IUOs should be optional if not bound/forced" );
3210
+ return false ;
3211
+ }
3212
+
3213
+ if (Type Unwrapped = ExprType->getOptionalObjectType ()) {
3184
3214
llvm::SaveAndRestore<bool > ChangeNeedOptionalUnwrap (NeedOptionalUnwrap,
3185
3215
true );
3186
3216
if (DotLoc.isValid ()) {
@@ -3191,26 +3221,15 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3191
3221
}
3192
3222
if (NumBytesToEraseForOptionalUnwrap <=
3193
3223
CodeCompletionResult::MaxNumBytesToErase) {
3194
- if (auto *TT = Unwrapped->getAs <TupleType>()) {
3195
- getTupleExprCompletions (TT);
3196
- } else {
3224
+ if (!tryTupleExprCompletions (Unwrapped)) {
3197
3225
lookupVisibleMemberDecls (*this , Unwrapped, CurrDeclContext,
3198
3226
TypeResolver.get (),
3199
3227
IncludeInstanceMembers);
3200
3228
}
3201
3229
}
3202
- } else {
3203
- return false ;
3230
+ return true ;
3204
3231
}
3205
-
3206
- // Ignore the members of Optional, like getLogicValue(), map(), and
3207
- // flatMap().
3208
- //
3209
- // These are not commonly used and cause noise and confusion when showing
3210
- // among the members of the underlying type. If someone really wants to
3211
- // use them they can write them directly.
3212
-
3213
- return true ;
3232
+ return false ;
3214
3233
}
3215
3234
3216
3235
void getValueExprCompletions (Type ExprType, ValueDecl *VD = nullptr ) {
@@ -3231,30 +3250,20 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3231
3250
}
3232
3251
}
3233
3252
3234
- bool Done = false ;
3253
+ // Handle special cases
3254
+ bool isIUO = VD && VD->getAttrs ()
3255
+ .hasAttribute <ImplicitlyUnwrappedOptionalAttr>();
3235
3256
if (tryFunctionCallCompletions (ExprType, VD))
3236
- Done = true ;
3237
- if (auto MT = ExprType->getAs <ModuleType>()) {
3238
- ModuleDecl *M = MT->getModule ();
3239
- if (CurrDeclContext->getParentModule () != M) {
3240
- // Only use the cache if it is not the current module.
3241
- RequestedCachedResults = RequestedResultsTy::fromModule (M)
3242
- .needLeadingDot (needDot ());
3243
- Done = true ;
3244
- }
3245
- }
3246
- if (auto *TT = ExprType->getAs <TupleType>()) {
3247
- getTupleExprCompletions (TT);
3248
- Done = true ;
3249
- }
3250
- bool isIUO =
3251
- VD && VD->getAttrs ().hasAttribute <ImplicitlyUnwrappedOptionalAttr>();
3252
- tryStdlibOptionalCompletions (ExprType, isIUO);
3253
- if (!Done) {
3254
- lookupVisibleMemberDecls (*this , ExprType, CurrDeclContext,
3255
- TypeResolver.get (),
3256
- IncludeInstanceMembers);
3257
- }
3257
+ return ;
3258
+ if (tryModuleCompletions (ExprType))
3259
+ return ;
3260
+ if (tryTupleExprCompletions (ExprType))
3261
+ return ;
3262
+ // Don't check/return so we still add the members of Optional itself below
3263
+ tryUnwrappedCompletions (ExprType, isIUO);
3264
+
3265
+ lookupVisibleMemberDecls (*this , ExprType, CurrDeclContext,
3266
+ TypeResolver.get (), IncludeInstanceMembers);
3258
3267
}
3259
3268
3260
3269
template <typename T>
@@ -5294,6 +5303,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
5294
5303
if (isDynamicLookup (*ExprType))
5295
5304
Lookup.setIsDynamicLookup ();
5296
5305
5306
+ if (isa<BindOptionalExpr>(ParsedExpr) || isa<ForceValueExpr>(ParsedExpr))
5307
+ Lookup.setIsUnwrappedOptional (true );
5308
+
5297
5309
::CodeCompletionTypeContextAnalyzer TypeAnalyzer (CurDeclContext, ParsedExpr);
5298
5310
llvm::SmallVector<Type, 2 > PossibleTypes;
5299
5311
if (TypeAnalyzer.Analyze (PossibleTypes)) {
0 commit comments