KT-8990: private member can't be overridden, even if it is visible in the current context
This commit is contained in:
@@ -1080,7 +1080,7 @@ public class OverrideResolver {
|
|||||||
all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
|
all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
|
||||||
for (CallableMemberDescriptor fromSuper : all) {
|
for (CallableMemberDescriptor fromSuper : all) {
|
||||||
if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
|
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 +
|
throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
|
||||||
" and visible but does not appear in its getOverriddenDescriptors()");
|
" and visible but does not appear in its getOverriddenDescriptors()");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
open class A {
|
||||||
|
private fun foo() {}
|
||||||
|
|
||||||
|
inner class B : A() {
|
||||||
|
private fun foo() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : A() {
|
||||||
|
private fun foo() {}
|
||||||
|
}
|
||||||
@@ -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);
|
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")
|
@TestMetadata("MissingDelegate.kt")
|
||||||
public void testMissingDelegate() throws Exception {
|
public void testMissingDelegate() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/MissingDelegate.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/MissingDelegate.kt");
|
||||||
|
|||||||
@@ -321,6 +321,11 @@ public class OverridingUtil {
|
|||||||
createAndBindFakeOverrides(current, notOverridden, strategy);
|
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(
|
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
|
||||||
@NotNull CallableMemberDescriptor fromCurrent,
|
@NotNull CallableMemberDescriptor fromCurrent,
|
||||||
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
|
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
|
||||||
@@ -332,16 +337,17 @@ public class OverridingUtil {
|
|||||||
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
|
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
|
||||||
OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult();
|
OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult();
|
||||||
|
|
||||||
boolean isVisible = Visibilities.isVisibleIgnoringReceiver(fromSupertype, current);
|
boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case OVERRIDABLE:
|
case OVERRIDABLE:
|
||||||
if (isVisible) {
|
if (isVisibleForOverride) {
|
||||||
overridden.add(fromSupertype);
|
overridden.add(fromSupertype);
|
||||||
}
|
}
|
||||||
bound.add(fromSupertype);
|
bound.add(fromSupertype);
|
||||||
break;
|
break;
|
||||||
case CONFLICT:
|
case CONFLICT:
|
||||||
if (isVisible) {
|
if (isVisibleForOverride) {
|
||||||
strategy.overrideConflict(fromSupertype, fromCurrent);
|
strategy.overrideConflict(fromSupertype, fromCurrent);
|
||||||
}
|
}
|
||||||
bound.add(fromSupertype);
|
bound.add(fromSupertype);
|
||||||
|
|||||||
Reference in New Issue
Block a user