diff --git a/include/swift/AST/ASTWalker.h b/include/swift/AST/ASTWalker.h index 94a84d9606fb0..92a71ee354e4a 100644 --- a/include/swift/AST/ASTWalker.h +++ b/include/swift/AST/ASTWalker.h @@ -48,6 +48,7 @@ struct ReferenceMetaData { SemaReferenceKind Kind; llvm::Optional AccKind; bool isImplicit = false; + bool isImplicitCtorType = false; /// When non-none, this is a custom attribute reference. Optional> CustomAttrRef; diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index 751113b7e5d06..be89d93cd47a3 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -633,6 +633,18 @@ ASTWalker::PreWalkAction SemaAnnotator::walkToTypeReprPre(TypeRepr *T) { ReferenceMetaData(SemaReferenceKind::TypeRef, None)); return Action::StopIf(!Continue); } + } else if (auto FT = dyn_cast(T)) { + ValueDecl *VD = FT->getType()->getAnyGeneric(); + if (auto DT = FT->getType()->getAs()) + VD = DT->getSelfType()->getAnyGeneric(); + + if (VD) { + auto Data = ReferenceMetaData(SemaReferenceKind::TypeRef, None); + Data.isImplicitCtorType = true; + auto Continue = passReference(VD, FT->getType(), FT->getLoc(), + FT->getSourceRange(), Data); + return Action::StopIf(!Continue); + } } return Action::Continue(); diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp index b84048a083d40..776f6a9e54450 100644 --- a/lib/IDE/Utils.cpp +++ b/lib/IDE/Utils.cpp @@ -849,8 +849,11 @@ bool swift::ide::isBeingCalled(ArrayRef ExprStack) { auto *AE = dyn_cast(E); if (!AE || AE->isImplicit()) continue; - if (auto *CRCE = dyn_cast(AE)) { - if (CRCE->getBase() == Target) + if (auto *CRCE = dyn_cast(AE->getFn())) { + auto *Base = CRCE->getBase(); + while (auto *ICE = dyn_cast(Base)) + Base = ICE->getSubExpr(); + if (Base == Target) return true; } if (isa(AE)) diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp index 74084d5059f14..254b802b22802 100644 --- a/lib/Index/Index.cpp +++ b/lib/Index/Index.cpp @@ -857,9 +857,13 @@ class IndexSwiftASTWalker : public SourceEntityWalker { if (Data.isImplicit) Info.roles |= (unsigned)SymbolRole::Implicit; - if (CtorTyRef) - if (!reportRef(CtorTyRef, Loc, Info, Data.AccKind)) + if (CtorTyRef) { + IndexSymbol CtorInfo(Info); + if (Data.isImplicitCtorType) + CtorInfo.roles |= (unsigned)SymbolRole::Implicit; + if (!reportRef(CtorTyRef, Loc, CtorInfo, Data.AccKind)) return false; + } if (auto *GenParam = dyn_cast(D)) { D = canonicalizeGenericTypeParamDeclForIndex(GenParam); diff --git a/test/Index/index_self.swift b/test/Index/index_self.swift new file mode 100644 index 0000000000000..e336f2f01d504 --- /dev/null +++ b/test/Index/index_self.swift @@ -0,0 +1,57 @@ +// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s + +struct Foo { // CHECK: [[@LINE]]:8 | struct/Swift | Foo | [[Foo_USR:.*]] | Def | rel: 0 + init() {} // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Foo_init_USR:.*]] | Def,RelChild | rel: 1 + + static func bar() -> Self { + .init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Foo_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } + + static func baz() -> Self { + Self() + // CHECK: [[@LINE-1]]:5 | struct/Swift | Foo | [[Foo_USR]] | Ref,Impl,RelCont | rel: 1 + // CHECK: [[@LINE-2]]:5 | constructor/Swift | init() | [[Foo_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } +} + +final class Final { // CHECK: [[@LINE]]:13 | class/Swift | Final | [[Final_USR:.*]] | Def | rel: 0 + init() {} // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Final_init_USR:.*]] | Def,RelChild | rel: 1 + + static func foo() -> Self { + .init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Final_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } + + static func baz() -> Self { + Self() + // CHECK: [[@LINE-1]]:5 | class/Swift | Final | [[Final_USR]] | Ref,Impl,RelCont | rel: 1 + // CHECK: [[@LINE-2]]:5 | constructor/Swift | init() | [[Final_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } +} + +class Bar { // CHECK: [[@LINE]]:7 | class/Swift | Bar | [[Bar_USR:.*]] | Def | rel: 0 + required init() {} // CHECK: [[@LINE]]:12 | constructor/Swift | init() | [[Bar_init_USR:.*]] | Def,RelChild | rel: 1 + + static func foo() -> Self { + .init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Bar_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } + + static func baz() -> Self { + Self() + // CHECK: [[@LINE-1]]:5 | class/Swift | Bar | [[Bar_USR]] | Ref,Impl,RelCont | rel: 1 + // TODO: This reference should be dynamic + // CHECK: [[@LINE-3]]:5 | constructor/Swift | init() | [[Bar_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } +} + +class Baz: Bar {} + +protocol Proto { // CHECK: [[@LINE]]:10 | protocol/Swift | Proto | [[Proto_USR:.*]] | Def | rel: 0 + init() // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Proto_init_USR:.*]] | Def,RelChild | rel: 1 +} + +extension Proto { + func foo() -> Self { + // TODO: This reference should be dynamic + Self() // CHECK: [[@LINE]]:5 | constructor/Swift | init() | [[Proto_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1 + } +}