20
20
#include " swift/AST/Initializer.h"
21
21
#include " swift/AST/LazyResolver.h"
22
22
#include " swift/AST/Module.h"
23
+ #include " swift/AST/ParameterList.h"
23
24
#include " swift/AST/Pattern.h"
24
25
#include " swift/AST/Stmt.h"
25
26
#include " swift/AST/Type.h"
@@ -336,7 +337,9 @@ void collectPossibleCalleesByQualifiedLookup(
336
337
Type declaredMemberType = VD->getInterfaceType ();
337
338
if (VD->getDeclContext ()->isTypeContext ()) {
338
339
if (isa<FuncDecl>(VD)) {
339
- if (!isOnMetaType)
340
+ if (!isOnMetaType && VD->isStatic ())
341
+ continue ;
342
+ if (isOnMetaType == VD->isStatic ())
340
343
declaredMemberType =
341
344
declaredMemberType->castTo <AnyFunctionType>()->getResult ();
342
345
} else if (isa<ConstructorDecl>(VD)) {
@@ -454,6 +457,31 @@ bool collectPossibleCalleesForSubscript(
454
457
return !candidates.empty ();
455
458
}
456
459
460
+ // / For the given \p unresolvedMemberExpr, collect possible callee types and
461
+ // / declarations.
462
+ static bool collectPossibleCalleesForUnresolvedMember (
463
+ DeclContext &DC, UnresolvedMemberExpr *unresolvedMemberExpr,
464
+ SmallVectorImpl<FunctionTypeAndDecl> &candidates) {
465
+ auto currModule = DC.getParentModule ();
466
+ auto baseName = unresolvedMemberExpr->getName ().getBaseName ();
467
+
468
+ // Get the context of the expression itself.
469
+ ExprContextInfo contextInfo (&DC, unresolvedMemberExpr);
470
+ for (auto expectedTy : contextInfo.getPossibleTypes ()) {
471
+ if (!expectedTy->mayHaveMembers ())
472
+ continue ;
473
+ SmallVector<FunctionTypeAndDecl, 2 > members;
474
+ collectPossibleCalleesByQualifiedLookup (DC, MetatypeType::get (expectedTy),
475
+ baseName, members);
476
+ for (auto member : members) {
477
+ if (isReferenceableByImplicitMemberExpr (currModule, &DC, expectedTy,
478
+ member.second ))
479
+ candidates.push_back (member);
480
+ }
481
+ }
482
+ return !candidates.empty ();
483
+ }
484
+
457
485
// / Get index of \p CCExpr in \p Args. \p Args is usually a \c TupleExpr,
458
486
// / \c ParenExpr, or a \c ArgumentShuffleExpr.
459
487
// / \returns \c true if success, \c false if \p CCExpr is not a part of \p Args.
@@ -552,6 +580,11 @@ class ExprContextAnalyzer {
552
580
if (!collectPossibleCalleesForSubscript (*DC, subscriptExpr, Candidates))
553
581
return false ;
554
582
Arg = subscriptExpr->getIndex ();
583
+ } else if (auto *unresolvedMemberExpr = dyn_cast<UnresolvedMemberExpr>(E)) {
584
+ if (!collectPossibleCalleesForUnresolvedMember (*DC, unresolvedMemberExpr,
585
+ Candidates))
586
+ return false ;
587
+ Arg = unresolvedMemberExpr->getArgument ();
555
588
} else {
556
589
llvm_unreachable (" unexpected expression kind" );
557
590
}
@@ -568,7 +601,8 @@ class ExprContextAnalyzer {
568
601
// Collect possible types (or labels) at the position.
569
602
{
570
603
bool MayNeedName = !HasName && !E->isImplicit () &&
571
- (isa<CallExpr>(E) | isa<SubscriptExpr>(E));
604
+ (isa<CallExpr>(E) | isa<SubscriptExpr>(E) ||
605
+ isa<UnresolvedMemberExpr>(E));
572
606
SmallPtrSet<TypeBase *, 4 > seenTypes;
573
607
SmallPtrSet<Identifier, 4 > seenNames;
574
608
for (auto &typeAndDecl : Candidates) {
@@ -577,18 +611,30 @@ class ExprContextAnalyzer {
577
611
memberDC = typeAndDecl.second ->getInnermostDeclContext ();
578
612
579
613
auto Params = typeAndDecl.first ->getParams ();
580
- if (Position >= Params.size ())
581
- continue ;
582
- const auto &Param = Params[Position];
583
- if (Param.hasLabel () && MayNeedName) {
584
- if (seenNames.insert (Param.getLabel ()).second )
585
- recordPossibleName (Param.getLabel ().str ());
586
- } else {
587
- Type ty = Param.getOldType ();
588
- if (memberDC && ty->hasTypeParameter ())
589
- ty = memberDC->mapTypeIntoContext (ty);
590
- if (seenTypes.insert (ty.getPointer ()).second )
591
- recordPossibleType (ty);
614
+ ParameterList *paramList = nullptr ;
615
+ if (auto VD = typeAndDecl.second ) {
616
+ if (auto FD = dyn_cast<AbstractFunctionDecl>(VD))
617
+ paramList = FD->getParameters ();
618
+ else if (auto SD = dyn_cast<SubscriptDecl>(VD))
619
+ paramList = SD->getIndices ();
620
+ if (paramList && paramList->size () != Params.size ())
621
+ paramList = nullptr ;
622
+ }
623
+ for (auto Pos = Position; Pos < Params.size (); ++Pos) {
624
+ const auto &Param = Params[Pos];
625
+ if (Param.hasLabel () && MayNeedName) {
626
+ if (seenNames.insert (Param.getLabel ()).second )
627
+ recordPossibleName (Param.getLabel ().str ());
628
+ if (paramList && paramList->get (Position)->isDefaultArgument ())
629
+ continue ;
630
+ } else {
631
+ Type ty = Param.getOldType ();
632
+ if (memberDC && ty->hasTypeParameter ())
633
+ ty = memberDC->mapTypeIntoContext (ty);
634
+ if (seenTypes.insert (ty.getPointer ()).second )
635
+ recordPossibleType (ty);
636
+ }
637
+ break ;
592
638
}
593
639
}
594
640
}
@@ -599,6 +645,7 @@ class ExprContextAnalyzer {
599
645
switch (Parent->getKind ()) {
600
646
case ExprKind::Call:
601
647
case ExprKind::Subscript:
648
+ case ExprKind::UnresolvedMember:
602
649
case ExprKind::Binary:
603
650
case ExprKind::PrefixUnary: {
604
651
analyzeApplyExpr (Parent);
@@ -783,11 +830,14 @@ class ExprContextAnalyzer {
783
830
case ExprKind::PrefixUnary:
784
831
case ExprKind::Assign:
785
832
return true ;
833
+ case ExprKind::UnresolvedMember:
834
+ return true ;
786
835
case ExprKind::Tuple: {
787
836
auto ParentE = Parent.getAsExpr ();
788
837
return !ParentE ||
789
838
(!isa<CallExpr>(ParentE) && !isa<SubscriptExpr>(ParentE) &&
790
- !isa<BinaryExpr>(ParentE) && !isa<ArgumentShuffleExpr>(ParentE));
839
+ !isa<BinaryExpr>(ParentE) && !isa<ArgumentShuffleExpr>(ParentE) &&
840
+ !isa<UnresolvedMemberExpr>(ParentE));
791
841
}
792
842
case ExprKind::Closure:
793
843
return isSingleExpressionBodyForCodeCompletion (
@@ -856,3 +906,75 @@ ExprContextInfo::ExprContextInfo(DeclContext *DC, Expr *TargetExpr) {
856
906
PossibleCallees, singleExpressionBody);
857
907
Analyzer.Analyze ();
858
908
}
909
+
910
+ // ===----------------------------------------------------------------------===//
911
+ // isReferenceableByImplicitMemberExpr(ModuleD, DeclContext, Type, ValueDecl)
912
+ // ===----------------------------------------------------------------------===//
913
+
914
+ bool swift::ide::isReferenceableByImplicitMemberExpr (
915
+ ModuleDecl *CurrModule, DeclContext *DC, Type T, ValueDecl *VD) {
916
+
917
+ if (VD->isOperator ())
918
+ return false ;
919
+
920
+ if (!VD->hasInterfaceType ())
921
+ return false ;
922
+
923
+ if (T->getOptionalObjectType () &&
924
+ VD->getModuleContext ()->isStdlibModule ()) {
925
+ // In optional context, ignore '.init(<some>)', 'init(nilLiteral:)',
926
+ if (isa<ConstructorDecl>(VD))
927
+ return false ;
928
+ // TODO: Ignore '.some(<Wrapped>)' and '.none' too *in expression
929
+ // context*. They are useful in pattern context though.
930
+ }
931
+
932
+ // Enum element decls can always be referenced by implicit member
933
+ // expression.
934
+ if (isa<EnumElementDecl>(VD))
935
+ return true ;
936
+
937
+ // Only non-failable constructors are implicitly referenceable.
938
+ if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
939
+ switch (CD->getFailability ()) {
940
+ case OTK_None:
941
+ case OTK_ImplicitlyUnwrappedOptional:
942
+ return true ;
943
+ case OTK_Optional:
944
+ return false ;
945
+ }
946
+ }
947
+
948
+ // Otherwise, check the result type matches the contextual type.
949
+ auto declTy = T->getTypeOfMember (CurrModule, VD);
950
+ if (declTy->is <ErrorType>())
951
+ return false ;
952
+
953
+ // Member types can also be implicitly referenceable as long as it's
954
+ // convertible to the contextual type.
955
+ if (auto CD = dyn_cast<TypeDecl>(VD)) {
956
+ declTy = declTy->getMetatypeInstanceType ();
957
+
958
+ // Emit construction for the same type via typealias doesn't make sense
959
+ // because we are emitting all `.init()`s.
960
+ if (declTy->isEqual (T))
961
+ return false ;
962
+ return swift::isConvertibleTo (declTy, T, *DC);
963
+ }
964
+
965
+ // Only static member can be referenced.
966
+ if (!VD->isStatic ())
967
+ return false ;
968
+
969
+ if (isa<FuncDecl>(VD)) {
970
+ // Strip '(Self.Type) ->' and parameters.
971
+ declTy = declTy->castTo <AnyFunctionType>()->getResult ();
972
+ declTy = declTy->castTo <AnyFunctionType>()->getResult ();
973
+ } else if (auto FT = declTy->getAs <AnyFunctionType>()) {
974
+ // The compiler accepts 'static var factory: () -> T' for implicit
975
+ // member expression.
976
+ // FIXME: This emits just 'factory'. We should emit 'factory()' instead.
977
+ declTy = FT->getResult ();
978
+ }
979
+ return declTy->isEqual (T) || swift::isConvertibleTo (declTy, T, *DC);
980
+ }
0 commit comments