KT-8990: private member can't be overridden, even if it is visible in the current context

This commit is contained in:
Dmitry Petrov
2016-05-19 17:41:06 +03:00
parent 15c47ead97
commit dd12c018ca
5 changed files with 52 additions and 4 deletions
@@ -1080,7 +1080,7 @@ public class OverrideResolver {
all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
for (CallableMemberDescriptor fromSuper : all) {
if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
if (Visibilities.isVisibleIgnoringReceiver(fromSuper, declared)) {
if (OverridingUtil.isVisibleForOverride(declared, fromSuper)) {
throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
" and visible but does not appear in its getOverriddenDescriptors()");
}
+11
View File
@@ -0,0 +1,11 @@
open class A {
private fun foo() {}
inner class B : A() {
private fun foo() {}
}
}
class C : A() {
private fun foo() {}
}
+25
View File
@@ -0,0 +1,25 @@
package
public open class A {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
private final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final inner class B : A {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
private final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class C : A {
public constructor C()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
private final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -12264,6 +12264,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("kt8990.kt")
public void testKt8990() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/kt8990.kt");
doTest(fileName);
}
@TestMetadata("MissingDelegate.kt")
public void testMissingDelegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/MissingDelegate.kt");
@@ -321,6 +321,11 @@ public class OverridingUtil {
createAndBindFakeOverrides(current, notOverridden, strategy);
}
public static boolean isVisibleForOverride(@NotNull MemberDescriptor overriding, @NotNull MemberDescriptor fromSuper) {
return !Visibilities.isPrivate(fromSuper.getVisibility()) &&
Visibilities.isVisibleIgnoringReceiver(fromSuper, overriding);
}
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
@NotNull CallableMemberDescriptor fromCurrent,
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
@@ -332,16 +337,17 @@ public class OverridingUtil {
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult();
boolean isVisible = Visibilities.isVisibleIgnoringReceiver(fromSupertype, current);
boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype);
switch (result) {
case OVERRIDABLE:
if (isVisible) {
if (isVisibleForOverride) {
overridden.add(fromSupertype);
}
bound.add(fromSupertype);
break;
case CONFLICT:
if (isVisible) {
if (isVisibleForOverride) {
strategy.overrideConflict(fromSupertype, fromCurrent);
}
bound.add(fromSupertype);