diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index 40dacd93193bc..a3d324bf44f09 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -362,11 +362,24 @@ ASTWalker::PreWalkResult SemaAnnotator::walkToExprPre(Expr *E) { } } + // Check if this is an implicit DeclRefExpr to a constructor - we should + // NOT skip these as they need to be indexed for Self.NestedType() calls. + // However, only do this when we're NOT inside a ConstructorRefCallExpr + // (tracked by CtorRefs), as that case is already handled and we'd create + // duplicate references. + bool isImplicitCtorRef = false; + if (CtorRefs.empty()) { + if (auto *DRE = dyn_cast(E)) { + if (isa(DRE->getDecl())) + isImplicitCtorRef = true; + } + } + if (!isa(E) && !isa(E) && !isa(E) && !isa(E) && !isa(E) && !isa(E) && !isa(E) && !isa(E) && !isa(E) && - !isa(E) && E->isImplicit()) + !isa(E) && E->isImplicit() && !isImplicitCtorRef) return Action::Continue(E); if (auto LE = dyn_cast(E)) { diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp index 9e6721b5f9c5d..b7a7b1f084b48 100644 --- a/lib/IDE/Utils.cpp +++ b/lib/IDE/Utils.cpp @@ -963,7 +963,22 @@ bool swift::ide::isBeingCalled(ArrayRef ExprStack) { } if (isa(AE)) continue; - if (getReferencedDecl(AE->getFn()).second == UnderlyingDecl) + Expr *Fn = AE->getFn(); + // Unwrap AutoClosureExpr and nested CallExpr to get the actual function + // expression. This handles cases like Self.NestedType() where the + // constructor call is wrapped in an autoclosure containing another call. + while (true) { + if (auto *ACE = dyn_cast(Fn)) { + Fn = ACE->getSingleExpressionBody(); + continue; + } + if (auto *InnerCall = dyn_cast(Fn)) { + Fn = InnerCall->getFn(); + continue; + } + break; + } + if (getReferencedDecl(Fn).second == UnderlyingDecl) return true; } return false; diff --git a/test/Index/expressions.swift b/test/Index/expressions.swift index 9d92a191757f7..cca28f55d0de1 100644 --- a/test/Index/expressions.swift +++ b/test/Index/expressions.swift @@ -57,3 +57,20 @@ func castExpr(x: Any) { // CHECK: [[@LINE+1]]:15 | struct/Swift | S1 | [[S1_USR]] | Ref _ = x as? S1 } + +// Test that initializers are indexed when called through Self.NestedType +// CHECK: [[@LINE+1]]:7 | class(internal)/Swift | Container | [[Container_USR:.*]] | Def +class Container { + // CHECK: [[@LINE+1]]:11 | class(internal)/Swift | NestedType | [[NestedType_USR:.*]] | Def + class NestedType { + // CHECK: [[@LINE+1]]:9 | constructor(internal)/Swift | init(value:) | [[NestedType_init_USR:.*]] | Def + init(value: Int) {} + } + + func someFunc() { + // CHECK: [[@LINE+3]]:13 | class/Swift | Container | [[Container_USR]] | Ref + // CHECK: [[@LINE+2]]:18 | class/Swift | NestedType | [[NestedType_USR]] | Ref + // CHECK: [[@LINE+1]]:18 | constructor/Swift | init(value:) | [[NestedType_init_USR]] | Ref,Call + _ = Self.NestedType(value: 1) + } +}