[CodeCompletion] Fix crash when completing inside a protocol that inherits from other protocol with extension

rdar://119408961
This commit is contained in:
Alex Hoppen
2023-12-12 15:49:06 -08:00
parent 35eb5cb7f4
commit e56708c84f
3 changed files with 30 additions and 29 deletions

View File

@@ -30,35 +30,7 @@ bool CompletionOverrideLookup::addAccessControl(
if (AccessOfContext < AccessLevel::Public)
return false;
auto Access = VD->getFormalAccess();
// Use the greater access between the protocol requirement and the witness.
// In case of:
//
// public protocol P { func foo() }
// public class B { func foo() {} }
// public class C: B, P {
// <complete>
// }
//
// 'VD' is 'B.foo()' which is implicitly 'internal'. But as the overriding
// declaration, the user needs to write both 'public' and 'override':
//
// public class C: B {
// public override func foo() {}
// }
if (Access < AccessLevel::Public &&
!isa<ProtocolDecl>(VD->getDeclContext())) {
for (auto Conformance : CurrentNominal->getAllConformances()) {
Conformance->getRootConformance()->forEachValueWitness(
[&](ValueDecl *req, Witness witness) {
if (witness.getDecl() == VD)
Access = std::max(Access,
Conformance->getProtocol()->getFormalAccess());
});
}
}
Access = std::min(Access, AccessOfContext);
AccessLevel Access = std::min(VD->getFormalAccess(), AccessOfContext);
// Only emit 'public', not needed otherwise.
if (Access < AccessLevel::Public)
return false;

View File

@@ -0,0 +1,13 @@
// RUN: %batch-code-completion
// Use the greater access between the protocol requirement and the witness. In this test
// case the completed declaration is 'B.foo()' which is implicitly 'internal'.
// But as the overriding declaration, the user needs to write both 'public' and 'override'.
public protocol P { func foo() }
public class B { internal func foo() {} }
public class C: B, P {
#^COMPLETE^#
// COMPLETE-DAG: Decl[InstanceMethod]/Super: public override func foo() {|}; name=foo()
// COMPLETE-DAG: Decl[Constructor]/Super: override init() {|}; name=init()
}

View File

@@ -0,0 +1,16 @@
// RUN: %batch-code-completion
public protocol BaseProtocol {}
extension BaseProtocol {
var indexInParent: Int {
1
}
}
public protocol InheritedProtocol: BaseProtocol {}
extension InheritedProtocol {
#^COMPLETE^#
// COMPLETE: Decl[InstanceVar]/Super: var indexInParent: Int; name=indexInParent
}