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"
@@ -289,7 +290,9 @@ static void collectPossibleCalleesByQualifiedLookup(
289
290
Type declaredMemberType = VD->getInterfaceType ();
290
291
if (VD->getDeclContext ()->isTypeContext ()) {
291
292
if (isa<FuncDecl>(VD)) {
292
- if (!isOnMetaType)
293
+ if (!isOnMetaType && VD->isStatic ())
294
+ continue ;
295
+ if (isOnMetaType == VD->isStatic ())
293
296
declaredMemberType =
294
297
declaredMemberType->castTo <AnyFunctionType>()->getResult ();
295
298
} else if (isa<ConstructorDecl>(VD)) {
@@ -349,8 +352,13 @@ static bool collectPossibleCalleesForApply(
349
352
auto *fnExpr = callExpr->getFn ();
350
353
351
354
if (auto type = fnExpr->getType ()) {
352
- if (auto *funcType = type->getAs <AnyFunctionType>())
353
- candidates.emplace_back (funcType, fnExpr->getReferencedDecl ().getDecl ());
355
+ if (auto *funcType = type->getAs <AnyFunctionType>()) {
356
+ auto refDecl = fnExpr->getReferencedDecl ();
357
+ if (!refDecl)
358
+ if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
359
+ refDecl = apply->getFn ()->getReferencedDecl ();
360
+ candidates.emplace_back (funcType, refDecl.getDecl ());
361
+ }
354
362
} else if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
355
363
if (auto *decl = DRE->getDecl ()) {
356
364
auto declType = decl->getInterfaceType ();
@@ -407,6 +415,31 @@ static bool collectPossibleCalleesForSubscript(
407
415
return !candidates.empty ();
408
416
}
409
417
418
+ // / For the given \p unresolvedMemberExpr, collect possible callee types and
419
+ // / declarations.
420
+ static bool collectPossibleCalleesForUnresolvedMember (
421
+ DeclContext &DC, UnresolvedMemberExpr *unresolvedMemberExpr,
422
+ SmallVectorImpl<FunctionTypeAndDecl> &candidates) {
423
+ auto currModule = DC.getParentModule ();
424
+ auto baseName = unresolvedMemberExpr->getName ().getBaseName ();
425
+
426
+ // Get the context of the expression itself.
427
+ ExprContextInfo contextInfo (&DC, unresolvedMemberExpr);
428
+ for (auto expectedTy : contextInfo.getPossibleTypes ()) {
429
+ if (!expectedTy->mayHaveMembers ())
430
+ continue ;
431
+ SmallVector<FunctionTypeAndDecl, 2 > members;
432
+ collectPossibleCalleesByQualifiedLookup (DC, MetatypeType::get (expectedTy),
433
+ baseName, members);
434
+ for (auto member : members) {
435
+ if (isReferenceableByImplicitMemberExpr (currModule, &DC, expectedTy,
436
+ member.second ))
437
+ candidates.push_back (member);
438
+ }
439
+ }
440
+ return !candidates.empty ();
441
+ }
442
+
410
443
// / Get index of \p CCExpr in \p Args. \p Args is usually a \c TupleExpr
411
444
// / or \c ParenExpr.
412
445
// / \returns \c true if success, \c false if \p CCExpr is not a part of \p Args.
@@ -470,6 +503,11 @@ class ExprContextAnalyzer {
470
503
if (!collectPossibleCalleesForSubscript (*DC, subscriptExpr, Candidates))
471
504
return false ;
472
505
Arg = subscriptExpr->getIndex ();
506
+ } else if (auto *unresolvedMemberExpr = dyn_cast<UnresolvedMemberExpr>(E)) {
507
+ if (!collectPossibleCalleesForUnresolvedMember (*DC, unresolvedMemberExpr,
508
+ Candidates))
509
+ return false ;
510
+ Arg = unresolvedMemberExpr->getArgument ();
473
511
} else {
474
512
llvm_unreachable (" unexpected expression kind" );
475
513
}
@@ -484,7 +522,8 @@ class ExprContextAnalyzer {
484
522
// Collect possible types (or labels) at the position.
485
523
{
486
524
bool MayNeedName = !HasName && !E->isImplicit () &&
487
- (isa<CallExpr>(E) | isa<SubscriptExpr>(E));
525
+ (isa<CallExpr>(E) | isa<SubscriptExpr>(E) ||
526
+ isa<UnresolvedMemberExpr>(E));
488
527
SmallPtrSet<TypeBase *, 4 > seenTypes;
489
528
SmallPtrSet<Identifier, 4 > seenNames;
490
529
for (auto &typeAndDecl : Candidates) {
@@ -493,18 +532,30 @@ class ExprContextAnalyzer {
493
532
memberDC = typeAndDecl.second ->getInnermostDeclContext ();
494
533
495
534
auto Params = typeAndDecl.first ->getParams ();
496
- if (Position >= Params.size ())
497
- continue ;
498
- const auto &Param = Params[Position];
499
- if (Param.hasLabel () && MayNeedName) {
500
- if (seenNames.insert (Param.getLabel ()).second )
501
- recordPossibleName (Param.getLabel ().str ());
502
- } else {
503
- Type ty = Param.getOldType ();
504
- if (memberDC && ty->hasTypeParameter ())
505
- ty = memberDC->mapTypeIntoContext (ty);
506
- if (seenTypes.insert (ty.getPointer ()).second )
507
- recordPossibleType (ty);
535
+ ParameterList *paramList = nullptr ;
536
+ if (auto VD = typeAndDecl.second ) {
537
+ if (auto FD = dyn_cast<AbstractFunctionDecl>(VD))
538
+ paramList = FD->getParameters ();
539
+ else if (auto SD = dyn_cast<SubscriptDecl>(VD))
540
+ paramList = SD->getIndices ();
541
+ if (paramList && paramList->size () != Params.size ())
542
+ paramList = nullptr ;
543
+ }
544
+ for (auto Pos = Position; Pos < Params.size (); ++Pos) {
545
+ const auto &Param = Params[Pos];
546
+ if (Param.hasLabel () && MayNeedName) {
547
+ if (seenNames.insert (Param.getLabel ()).second )
548
+ recordPossibleName (Param.getLabel ().str ());
549
+ if (paramList && paramList->get (Position)->isDefaultArgument ())
550
+ continue ;
551
+ } else {
552
+ Type ty = Param.getOldType ();
553
+ if (memberDC && ty->hasTypeParameter ())
554
+ ty = memberDC->mapTypeIntoContext (ty);
555
+ if (seenTypes.insert (ty.getPointer ()).second )
556
+ recordPossibleType (ty);
557
+ }
558
+ break ;
508
559
}
509
560
}
510
561
}
@@ -515,6 +566,7 @@ class ExprContextAnalyzer {
515
566
switch (Parent->getKind ()) {
516
567
case ExprKind::Call:
517
568
case ExprKind::Subscript:
569
+ case ExprKind::UnresolvedMember:
518
570
case ExprKind::Binary:
519
571
case ExprKind::PrefixUnary: {
520
572
analyzeApplyExpr (Parent);
@@ -706,11 +758,14 @@ class ExprContextAnalyzer {
706
758
case ExprKind::Assign:
707
759
case ExprKind::Array:
708
760
return true ;
761
+ case ExprKind::UnresolvedMember:
762
+ return true ;
709
763
case ExprKind::Tuple: {
710
764
auto ParentE = Parent.getAsExpr ();
711
765
return !ParentE ||
712
766
(!isa<CallExpr>(ParentE) && !isa<SubscriptExpr>(ParentE) &&
713
- !isa<BinaryExpr>(ParentE));
767
+ !isa<BinaryExpr>(ParentE) &&
768
+ !isa<UnresolvedMemberExpr>(ParentE));
714
769
}
715
770
case ExprKind::Closure:
716
771
return isSingleExpressionBodyForCodeCompletion (
@@ -779,3 +834,75 @@ ExprContextInfo::ExprContextInfo(DeclContext *DC, Expr *TargetExpr) {
779
834
PossibleCallees, singleExpressionBody);
780
835
Analyzer.Analyze ();
781
836
}
837
+
838
+ // ===----------------------------------------------------------------------===//
839
+ // isReferenceableByImplicitMemberExpr(ModuleD, DeclContext, Type, ValueDecl)
840
+ // ===----------------------------------------------------------------------===//
841
+
842
+ bool swift::ide::isReferenceableByImplicitMemberExpr (
843
+ ModuleDecl *CurrModule, DeclContext *DC, Type T, ValueDecl *VD) {
844
+
845
+ if (VD->isOperator ())
846
+ return false ;
847
+
848
+ if (!VD->hasInterfaceType ())
849
+ return false ;
850
+
851
+ if (T->getOptionalObjectType () &&
852
+ VD->getModuleContext ()->isStdlibModule ()) {
853
+ // In optional context, ignore '.init(<some>)', 'init(nilLiteral:)',
854
+ if (isa<ConstructorDecl>(VD))
855
+ return false ;
856
+ // TODO: Ignore '.some(<Wrapped>)' and '.none' too *in expression
857
+ // context*. They are useful in pattern context though.
858
+ }
859
+
860
+ // Enum element decls can always be referenced by implicit member
861
+ // expression.
862
+ if (isa<EnumElementDecl>(VD))
863
+ return true ;
864
+
865
+ // Only non-failable constructors are implicitly referenceable.
866
+ if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
867
+ switch (CD->getFailability ()) {
868
+ case OTK_None:
869
+ case OTK_ImplicitlyUnwrappedOptional:
870
+ return true ;
871
+ case OTK_Optional:
872
+ return false ;
873
+ }
874
+ }
875
+
876
+ // Otherwise, check the result type matches the contextual type.
877
+ auto declTy = T->getTypeOfMember (CurrModule, VD);
878
+ if (declTy->is <ErrorType>())
879
+ return false ;
880
+
881
+ // Member types can also be implicitly referenceable as long as it's
882
+ // convertible to the contextual type.
883
+ if (auto CD = dyn_cast<TypeDecl>(VD)) {
884
+ declTy = declTy->getMetatypeInstanceType ();
885
+
886
+ // Emit construction for the same type via typealias doesn't make sense
887
+ // because we are emitting all `.init()`s.
888
+ if (declTy->isEqual (T))
889
+ return false ;
890
+ return swift::isConvertibleTo (declTy, T, *DC);
891
+ }
892
+
893
+ // Only static member can be referenced.
894
+ if (!VD->isStatic ())
895
+ return false ;
896
+
897
+ if (isa<FuncDecl>(VD)) {
898
+ // Strip '(Self.Type) ->' and parameters.
899
+ declTy = declTy->castTo <AnyFunctionType>()->getResult ();
900
+ declTy = declTy->castTo <AnyFunctionType>()->getResult ();
901
+ } else if (auto FT = declTy->getAs <AnyFunctionType>()) {
902
+ // The compiler accepts 'static var factory: () -> T' for implicit
903
+ // member expression.
904
+ // FIXME: This emits just 'factory'. We should emit 'factory()' instead.
905
+ declTy = FT->getResult ();
906
+ }
907
+ return declTy->isEqual (T) || swift::isConvertibleTo (declTy, T, *DC);
908
+ }
0 commit comments