From a02b64f0e37ffb695745ae52c00b72c28f19c411 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 2 Oct 2015 16:17:40 +0300 Subject: [PATCH] Setup overridability rules for properties built on Java fields - They overrides each other - They do not overrides Kotlin propeties and vice versa --- .../tests/j+k/fieldOverridesField.kt | 17 ++++++++++ .../tests/j+k/fieldOverridesField.txt | 19 +++++++++++ .../tests/j+k/fieldOverridesNothing.kt | 19 +++++++++++ .../tests/j+k/fieldOverridesNothing.txt | 28 ++++++++++++++++ .../tests/j+k/privateFieldOverridesNothing.kt | 19 +++++++++++ .../j+k/privateFieldOverridesNothing.txt | 28 ++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 18 ++++++++++ ...in.resolve.ExternalOverridabilityCondition | 1 + .../load/java/FieldOverridabilityCondition.kt | 33 +++++++++++++++++++ 9 files changed, 182 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/j+k/fieldOverridesField.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/fieldOverridesField.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.txt create mode 100644 core/descriptor.loader.java/src/META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition create mode 100644 core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt diff --git a/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.kt b/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.kt new file mode 100644 index 00000000000..d337ec5e367 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.kt @@ -0,0 +1,17 @@ +// FILE: A.java + +public class A { + public int size = 1; +} + +// FILE: B.java + +public class B implements A { + public int size = 1; +} + +// FILE: main.kt + +fun foo() { + B().size +} diff --git a/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.txt b/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.txt new file mode 100644 index 00000000000..bcf7dde194b --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/fieldOverridesField.txt @@ -0,0 +1,19 @@ +package + +public fun foo(): kotlin.Unit + +public open class A { + public constructor A() + public final var size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B : A { + public constructor B() + public final override /*1*/ var size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.kt b/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.kt new file mode 100644 index 00000000000..283dabc65d9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.kt @@ -0,0 +1,19 @@ +// FILE: B.java + +abstract class B implements A { + public int size = 1; +} + +// FILE: main.kt + +interface A { + val size: Int +} + +class C : B() { + override val size: Int get() = 1 +} + +fun foo() { + C().size +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.txt b/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.txt new file mode 100644 index 00000000000..ad11dfc984d --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.txt @@ -0,0 +1,28 @@ +package + +public fun foo(): kotlin.Unit + +public interface A { + public abstract val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ abstract class B : A { + public/*package*/ constructor B() + public final var size: kotlin.Int + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C : B { + public constructor C() + public open override /*1*/ val size: kotlin.Int + public final override /*1*/ /*fake_override*/ var size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.kt b/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.kt new file mode 100644 index 00000000000..29b81383f80 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.kt @@ -0,0 +1,19 @@ +// FILE: B.java + +abstract class B implements A { + private int size = 1; +} + +// FILE: main.kt + +interface A { + val size: Int +} + +class C : B() { + override val size: Int get() = 1 +} + +fun foo() { + C().size +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.txt b/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.txt new file mode 100644 index 00000000000..1a1c35f11aa --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.txt @@ -0,0 +1,28 @@ +package + +public fun foo(): kotlin.Unit + +public interface A { + public abstract val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ abstract class B : A { + public/*package*/ constructor B() + private final var size: kotlin.Int + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C : B { + public constructor C() + public open override /*1*/ val size: kotlin.Int + invisible_fake final override /*1*/ /*fake_override*/ var size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + 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/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 21de1c6441e..849dd09ce02 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -8694,6 +8694,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("fieldOverridesField.kt") + public void testFieldOverridesField() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/fieldOverridesField.kt"); + doTest(fileName); + } + + @TestMetadata("fieldOverridesNothing.kt") + public void testFieldOverridesNothing() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/fieldOverridesNothing.kt"); + doTest(fileName); + } + @TestMetadata("GenericsInSupertypes.kt") public void testGenericsInSupertypes() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/GenericsInSupertypes.kt"); @@ -8856,6 +8868,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("privateFieldOverridesNothing.kt") + public void testPrivateFieldOverridesNothing() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/privateFieldOverridesNothing.kt"); + doTest(fileName); + } + @TestMetadata("privateNestedClassStaticMember.kt") public void testPrivateNestedClassStaticMember() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/privateNestedClassStaticMember.kt"); diff --git a/core/descriptor.loader.java/src/META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition b/core/descriptor.loader.java/src/META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition new file mode 100644 index 00000000000..8ee85f170c9 --- /dev/null +++ b/core/descriptor.loader.java/src/META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition @@ -0,0 +1 @@ +org.jetbrains.kotlin.load.java.FieldOverridabilityCondition \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt new file mode 100644 index 00000000000..34638f58832 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/FieldOverridabilityCondition.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.load.java + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition + +class FieldOverridabilityCondition : ExternalOverridabilityCondition { + override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor): Boolean { + if (subDescriptor !is PropertyDescriptor || superDescriptor !is PropertyDescriptor) return true + + return subDescriptor.isJavaField == superDescriptor.isJavaField + } + + // Currently getter is null iff it's loaded from Java field + private val PropertyDescriptor.isJavaField: Boolean + get() = getter == null +}