Fix missing indexing data when using Self initializer

Fixes: https://github.com/apple/swift/issues/64686
This commit is contained in:
Keith Smiley
2023-04-28 14:26:01 -07:00
parent bfe975d5f8
commit 1d3a9baed2
5 changed files with 81 additions and 4 deletions

View File

@@ -48,6 +48,7 @@ struct ReferenceMetaData {
SemaReferenceKind Kind; SemaReferenceKind Kind;
llvm::Optional<AccessKind> AccKind; llvm::Optional<AccessKind> AccKind;
bool isImplicit = false; bool isImplicit = false;
bool isImplicitCtorType = false;
/// When non-none, this is a custom attribute reference. /// When non-none, this is a custom attribute reference.
Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef; Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef;

View File

@@ -633,6 +633,18 @@ ASTWalker::PreWalkAction SemaAnnotator::walkToTypeReprPre(TypeRepr *T) {
ReferenceMetaData(SemaReferenceKind::TypeRef, None)); ReferenceMetaData(SemaReferenceKind::TypeRef, None));
return Action::StopIf(!Continue); return Action::StopIf(!Continue);
} }
} else if (auto FT = dyn_cast<FixedTypeRepr>(T)) {
ValueDecl *VD = FT->getType()->getAnyGeneric();
if (auto DT = FT->getType()->getAs<DynamicSelfType>())
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(); return Action::Continue();

View File

@@ -849,8 +849,11 @@ bool swift::ide::isBeingCalled(ArrayRef<Expr *> ExprStack) {
auto *AE = dyn_cast<ApplyExpr>(E); auto *AE = dyn_cast<ApplyExpr>(E);
if (!AE || AE->isImplicit()) if (!AE || AE->isImplicit())
continue; continue;
if (auto *CRCE = dyn_cast<ConstructorRefCallExpr>(AE)) { if (auto *CRCE = dyn_cast<ConstructorRefCallExpr>(AE->getFn())) {
if (CRCE->getBase() == Target) auto *Base = CRCE->getBase();
while (auto *ICE = dyn_cast<ImplicitConversionExpr>(Base))
Base = ICE->getSubExpr();
if (Base == Target)
return true; return true;
} }
if (isa<SelfApplyExpr>(AE)) if (isa<SelfApplyExpr>(AE))

View File

@@ -857,9 +857,13 @@ private:
if (Data.isImplicit) if (Data.isImplicit)
Info.roles |= (unsigned)SymbolRole::Implicit; Info.roles |= (unsigned)SymbolRole::Implicit;
if (CtorTyRef) if (CtorTyRef) {
if (!reportRef(CtorTyRef, Loc, Info, Data.AccKind)) IndexSymbol CtorInfo(Info);
if (Data.isImplicitCtorType)
CtorInfo.roles |= (unsigned)SymbolRole::Implicit;
if (!reportRef(CtorTyRef, Loc, CtorInfo, Data.AccKind))
return false; return false;
}
if (auto *GenParam = dyn_cast<GenericTypeParamDecl>(D)) { if (auto *GenParam = dyn_cast<GenericTypeParamDecl>(D)) {
D = canonicalizeGenericTypeParamDeclForIndex(GenParam); D = canonicalizeGenericTypeParamDeclForIndex(GenParam);

View File

@@ -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
}
}