diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp index df3aa5e61ae67..9cb021bdef15a 100644 --- a/lib/Index/Index.cpp +++ b/lib/Index/Index.cpp @@ -1056,6 +1056,26 @@ class IndexSwiftASTWalker : public SourceEntityWalker { return {{line, col, inGeneratedBuffer}}; } + bool shouldIndexImplicitDecl(const ValueDecl *D, bool IsRef) const { + // We index implicit constructors. + if (isa(D)) + return true; + + // Allow references to implicit getter & setter AccessorDecls on + // non-implicit storage, these are "pseudo accessors". + if (auto *AD = dyn_cast(D)) { + if (!IsRef) + return false; + + auto Kind = AD->getAccessorKind(); + if (Kind != AccessorKind::Get && Kind != AccessorKind::Set) + return false; + + return shouldIndex(AD->getStorage(), IsRef); + } + return false; + } + bool shouldIndex(const ValueDecl *D, bool IsRef) const { if (D->isImplicit() && isa(D) && IsRef) { // Bypass the implicit VarDecls introduced in CaseStmt bodies by using the @@ -1063,7 +1083,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker { D = cast(D)->getCanonicalVarDecl(); } - if (D->isImplicit() && !isa(D)) + if (D->isImplicit() && !shouldIndexImplicitDecl(D, IsRef)) return false; // Do not handle non-public imported decls. diff --git a/test/Index/roles.swift b/test/Index/roles.swift index 9b48816d26a82..067b8faa7b6e8 100644 --- a/test/Index/roles.swift +++ b/test/Index/roles.swift @@ -539,3 +539,28 @@ func containerFunc() { // CHECK: [[@LINE-16]]:15 | function/acc-get/Swift | getter:y | {{.*}} | Ref,Call,Impl,RelCall,RelCont | rel: 1 // CHECK-NEXT: RelCall,RelCont | function/Swift | containerFunc() } + +// rdar://131749546 - Make sure we record the override relation for the +// pseudo accessor for 'x'. +class BaseClass { + var x = 0 + // CHECK: [[@LINE-1]]:7 | instance-property/Swift | x | s:14swift_ide_test9BaseClassC1xSivp | Def,RelChild | rel: 1 + // CHECK: [[@LINE-2]]:7 | instance-method/acc-get/Swift | getter:x | s:14swift_ide_test9BaseClassC1xSivg | Def,Dyn,Impl,RelChild,RelAcc | rel: 1 + // CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | x | s:14swift_ide_test9BaseClassC1xSivp + // CHECK: [[@LINE-4]]:7 | instance-method/acc-set/Swift | setter:x | s:14swift_ide_test9BaseClassC1xSivs | Def,Dyn,Impl,RelChild,RelAcc | rel: 1 + // CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | x | s:14swift_ide_test9BaseClassC1xSivp +} +class Subclass: BaseClass { + override var x: Int { + // CHECK: [[@LINE-1]]:16 | instance-property/Swift | x | s:14swift_ide_test8SubclassC1xSivp | Def,RelChild,RelOver | rel: 2 + // CHECK-NEXT: RelOver | instance-property/Swift | x | s:14swift_ide_test9BaseClassC1xSivp + get { 0 } + // CHECK: [[@LINE-1]]:5 | instance-method/acc-get/Swift | getter:x | s:14swift_ide_test8SubclassC1xSivg | Def,Dyn,RelChild,RelOver,RelAcc | rel: 2 + // CHECK-NEXT: RelOver | instance-method/acc-get/Swift | getter:x | s:14swift_ide_test9BaseClassC1xSivg + // CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | x | s:14swift_ide_test8SubclassC1xSivp + set {} + // CHECK: [[@LINE-1]]:5 | instance-method/acc-set/Swift | setter:x | s:14swift_ide_test8SubclassC1xSivs | Def,Dyn,RelChild,RelOver,RelAcc | rel: 2 + // CHECK-NEXT: RelOver | instance-method/acc-set/Swift | setter:x | s:14swift_ide_test9BaseClassC1xSivs + // CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | x | s:14swift_ide_test8SubclassC1xSivp + } +}