From dd12c018ca57ef4723bedcfbfd37b821c170e02a Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 19 May 2016 17:41:06 +0300 Subject: [PATCH] KT-8990: private member can't be overridden, even if it is visible in the current context --- .../kotlin/resolve/OverrideResolver.java | 2 +- .../diagnostics/tests/override/kt8990.kt | 11 ++++++++ .../diagnostics/tests/override/kt8990.txt | 25 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++++ .../kotlin/resolve/OverridingUtil.java | 12 ++++++--- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/override/kt8990.kt create mode 100644 compiler/testData/diagnostics/tests/override/kt8990.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.java index 15ef93fc318..e3d9374af1a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.java @@ -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()"); } diff --git a/compiler/testData/diagnostics/tests/override/kt8990.kt b/compiler/testData/diagnostics/tests/override/kt8990.kt new file mode 100644 index 00000000000..ca218fc52c8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/kt8990.kt @@ -0,0 +1,11 @@ +open class A { + private fun foo() {} + + inner class B : A() { + private fun foo() {} + } +} + +class C : A() { + private fun foo() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/kt8990.txt b/compiler/testData/diagnostics/tests/override/kt8990.txt new file mode 100644 index 00000000000..d471531f550 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/kt8990.txt @@ -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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 4e06aac98a9..2168ad977ef 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index ddc432a4fce..3700b4044a1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -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 extractAndBindOverridesForMember( @NotNull CallableMemberDescriptor fromCurrent, @NotNull Collection 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);