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