@@ -1655,6 +1655,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1655
1655
DeducedAssociatedTypeCache;
1656
1656
1657
1657
Optional<SemanticContextKind> ForcedSemanticContext = None;
1658
+ bool IsUnresolvedMember = false ;
1658
1659
1659
1660
std::unique_ptr<ArchetypeTransformer> TransformerPt = nullptr ;
1660
1661
@@ -1885,6 +1886,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1885
1886
if (ForcedSemanticContext)
1886
1887
return *ForcedSemanticContext;
1887
1888
1889
+ if (IsUnresolvedMember) {
1890
+ if (isa<EnumElementDecl>(D)) {
1891
+ return SemanticContextKind::ExpressionSpecific;
1892
+ }
1893
+ }
1894
+
1888
1895
switch (Reason) {
1889
1896
case DeclVisibilityKind::LocalVariable:
1890
1897
case DeclVisibilityKind::FunctionParameter:
@@ -3002,20 +3009,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3002
3009
return false ;
3003
3010
}
3004
3011
3005
- void handleOptionSet (Decl *D, DeclVisibilityKind Reason) {
3006
- if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
3007
- if (isOptionSetDecl (NTD)) {
3008
- for (auto M : NTD->getMembers ()) {
3009
- if (auto *VD = dyn_cast<VarDecl>(M)) {
3010
- if (isOptionSet (VD->getType ()) && VD->isStatic ()) {
3011
- addVarDeclRef (VD, Reason);
3012
- }
3013
- }
3014
- }
3015
- }
3016
- }
3017
- }
3018
-
3019
3012
bool isOptionSetDecl (NominalTypeDecl *D) {
3020
3013
auto optionSetType = dyn_cast<ProtocolDecl>(Ctx.getOptionSetDecl ());
3021
3014
if (!optionSetType)
@@ -3659,13 +3652,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3659
3652
unboxType (FT->getInput ());
3660
3653
unboxType (FT->getResult ());
3661
3654
} else if (auto NTD = T->getNominalOrBoundGenericNominal ()){
3662
- if (HandledDecls.count (NTD) == 0 ) {
3663
- auto Reason = DeclVisibilityKind::MemberOfCurrentNominal;
3664
- if (!Lookup.handleEnumElement (NTD, Reason)) {
3665
- Lookup.handleOptionSet (NTD, Reason);
3666
- }
3667
- HandledDecls.insert (NTD);
3668
- }
3655
+ if (HandledDecls.insert (NTD).second )
3656
+ Lookup.getUnresolvedMemberCompletions (T);
3669
3657
}
3670
3658
}
3671
3659
@@ -3699,20 +3687,39 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3699
3687
}
3700
3688
};
3701
3689
3702
- void getUnresolvedMemberCompletions (SourceLoc Loc, SmallVectorImpl <Type> & Types) {
3690
+ void getUnresolvedMemberCompletions (ArrayRef <Type> Types) {
3703
3691
NeedLeadingDot = !HaveDot;
3704
3692
for (auto T : Types) {
3705
3693
if (T && T->getNominalOrBoundGenericNominal ()) {
3706
- auto Reason = DeclVisibilityKind::MemberOfCurrentNominal;
3707
- if (!handleEnumElement (T->getNominalOrBoundGenericNominal (), Reason)) {
3708
- handleOptionSet (T->getNominalOrBoundGenericNominal (), Reason);
3709
- }
3694
+ // We can only say .foo where foo is a static member of the contextual
3695
+ // type and has the same type (or if the member is a function, then the
3696
+ // same result type) as the contextual type.
3697
+ auto contextCanT = T->getCanonicalType ();
3698
+ FilteredDeclConsumer consumer (*this , [=](ValueDecl *VD, DeclVisibilityKind reason) {
3699
+ if (!VD->hasType ()) {
3700
+ TypeResolver->resolveDeclSignature (VD);
3701
+ if (!VD->hasType ())
3702
+ return false ;
3703
+ }
3704
+
3705
+ auto T = VD->getType ();
3706
+ while (auto FT = T->getAs <AnyFunctionType>())
3707
+ T = FT->getResult ();
3708
+ return T->getCanonicalType () == contextCanT;
3709
+ });
3710
+
3711
+ auto baseType = MetatypeType::get (T);
3712
+ llvm::SaveAndRestore<LookupKind> SaveLook (Kind, LookupKind::ValueExpr);
3713
+ llvm::SaveAndRestore<Type> SaveType (ExprType, baseType);
3714
+ llvm::SaveAndRestore<bool > SaveUnresolved (IsUnresolvedMember, true );
3715
+ lookupVisibleMemberDecls (consumer, baseType, CurrDeclContext,
3716
+ TypeResolver.get (),
3717
+ /* includeInstanceMembers=*/ false );
3710
3718
}
3711
3719
}
3712
3720
}
3713
3721
3714
- void getUnresolvedMemberCompletions (SourceLoc Loc,
3715
- std::vector<std::string> &FuncNames,
3722
+ void getUnresolvedMemberCompletions (std::vector<std::string> &FuncNames,
3716
3723
bool HasReturn) {
3717
3724
NeedLeadingDot = !HaveDot;
3718
3725
LookupByName Lookup (*this , FuncNames);
@@ -5186,12 +5193,10 @@ void CodeCompletionCallbacksImpl::doneParsing() {
5186
5193
eraseErrorTypes (PE);
5187
5194
Success = typeCheckUnresolvedExpr (*CurDeclContext, UnresolvedExpr, PE,
5188
5195
PossibleTypes);
5189
- Lookup.getUnresolvedMemberCompletions (
5190
- P.Context .SourceMgr .getCodeCompletionLoc (), PossibleTypes);
5196
+ Lookup.getUnresolvedMemberCompletions (PossibleTypes);
5191
5197
}
5192
5198
if (!Success) {
5193
5199
Lookup.getUnresolvedMemberCompletions (
5194
- P.Context .SourceMgr .getCodeCompletionLoc (),
5195
5200
TokensBeforeUnresolvedExpr,
5196
5201
UnresolvedExprInReturn);
5197
5202
}
0 commit comments