diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmBridgesImpl.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmBridgesImpl.kt index 4eb043318d7..6d06dd6a7ee 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmBridgesImpl.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmBridgesImpl.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor +import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation @@ -42,18 +44,27 @@ class DescriptorBasedFunctionHandleForJvm( override val mightBeIncorrectCode: Boolean get() = state.classBuilderMode.mightBeIncorrectCode - override fun hashCode(): Int = descriptor.containerEntityForEqualityAndHashCode().hashCode() + 31 * asmMethod.hashCode() - override fun equals(other: Any?): Boolean { - if (other !is DescriptorBasedFunctionHandleForJvm) return false + override fun hashCode(): Int = + (descriptor.containerEntityForEqualityAndHashCode().hashCode() * 31 + + descriptor.isJavaForKotlinOverrideProperty.hashCode()) * 31 + + asmMethod.hashCode() - return asmMethod == other.asmMethod && - descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode() + override fun equals(other: Any?): Boolean { + if (this === other) return true + + return other is DescriptorBasedFunctionHandleForJvm && + asmMethod == other.asmMethod && + descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode() && + descriptor.isJavaForKotlinOverrideProperty == other.descriptor.isJavaForKotlinOverrideProperty } } private fun FunctionDescriptor.containerEntityForEqualityAndHashCode(): Any = (containingDeclaration as? ClassDescriptor)?.typeConstructor ?: containingDeclaration +private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean + get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor + private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent() = hasJvmDefaultAnnotation() || hasPlatformDependentAnnotation() diff --git a/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.kt b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.kt new file mode 100644 index 00000000000..05ace2ccc13 --- /dev/null +++ b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.kt @@ -0,0 +1,3 @@ +package test + +class C : B(), I diff --git a/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.txt b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.txt new file mode 100644 index 00000000000..700d49bd38a --- /dev/null +++ b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.txt @@ -0,0 +1,20 @@ +package test + +public abstract class A { + public constructor A() + public open fun getValue(): kotlin.String! +} + +public open class B : test.A, test.I { + public constructor B() + public open override /*2*/ /*fake_override*/ val value: kotlin.String? +} + +public final class C : test.B, test.I { + public constructor C() + public open override /*2*/ /*fake_override*/ val value: kotlin.String? +} + +public interface I { + public abstract val value: kotlin.String? +} diff --git a/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/A.java b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/A.java new file mode 100644 index 00000000000..06a9830bb98 --- /dev/null +++ b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/A.java @@ -0,0 +1,7 @@ +package test; + +public abstract class A { + public String getValue() { + return null; + } +} diff --git a/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/B.java b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/B.java new file mode 100644 index 00000000000..2f903c118b1 --- /dev/null +++ b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/B.java @@ -0,0 +1,4 @@ +package test; + +public class B extends A implements I { +} diff --git a/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/I.kt b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/I.kt new file mode 100644 index 00000000000..b0903af2fb5 --- /dev/null +++ b/compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty/I.kt @@ -0,0 +1,5 @@ +package test + +interface I { + val value: String? +} diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java index b5a9048d550..add20387aa8 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace; import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM; import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt; +import org.jetbrains.kotlin.codegen.GenerationUtils; import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.descriptors.ClassDescriptor; @@ -26,7 +27,6 @@ import org.jetbrains.kotlin.descriptors.PackageViewDescriptor; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorUtils; -import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor; import org.jetbrains.kotlin.test.*; import org.jetbrains.kotlin.test.util.DescriptorValidator; @@ -237,7 +237,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { configureEnvironment(environment); KtFile ktFile = KotlinTestUtils.createFile(kotlinSrc.getPath(), FileUtil.loadFile(kotlinSrc, true), environment.getProject()); - ModuleDescriptor module = JvmResolveUtil.analyzeAndCheckForErrors(Collections.singleton(ktFile), environment).getModuleDescriptor(); + ModuleDescriptor module = GenerationUtils.compileFiles(Collections.singletonList(ktFile), environment).getModule(); PackageViewDescriptor packageView = module.getPackage(TEST_PACKAGE_FQNAME); assertFalse(packageView.isEmpty()); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index 43d083d8374..810f774c0b4 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -5052,6 +5052,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/InheritParameterName.kt"); } + @TestMetadata("javaGetterImplementsKotlinProperty.kt") + public void testJavaGetterImplementsKotlinProperty() throws Exception { + runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.kt"); + } + @TestMetadata("javaRefersToKotlin.kt") public void testJavaRefersToKotlin() throws Exception { runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaRefersToKotlin.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java index d3b9e5c7474..cb537688623 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java @@ -5052,6 +5052,11 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/InheritParameterName.kt"); } + @TestMetadata("javaGetterImplementsKotlinProperty.kt") + public void testJavaGetterImplementsKotlinProperty() throws Exception { + runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaGetterImplementsKotlinProperty.kt"); + } + @TestMetadata("javaRefersToKotlin.kt") public void testJavaRefersToKotlin() throws Exception { runTest("compiler/testData/loadJava/kotlinAgainstCompiledJavaWithKotlin/javaRefersToKotlin.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaForKotlinOverridePropertyDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaForKotlinOverridePropertyDescriptor.kt new file mode 100644 index 00000000000..b17ef6e60be --- /dev/null +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaForKotlinOverridePropertyDescriptor.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.load.java.descriptors + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations + +class JavaForKotlinOverridePropertyDescriptor( + ownerDescriptor: ClassDescriptor, + getterMethod: SimpleFunctionDescriptor, + setterMethod: SimpleFunctionDescriptor?, + overriddenProperty: PropertyDescriptor +) : JavaPropertyDescriptor( + ownerDescriptor, + Annotations.EMPTY, + getterMethod.modality, + getterMethod.visibility, + setterMethod != null, + overriddenProperty.name, + getterMethod.source, + null, + CallableMemberDescriptor.Kind.DECLARATION, + false, + null +) diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java index fef7e46b4ef..a06efdf41db 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java @@ -37,7 +37,7 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja @Nullable private final Pair, ?> singleUserData; - private JavaPropertyDescriptor( + protected JavaPropertyDescriptor( @NotNull DeclarationDescriptor containingDeclaration, @NotNull Annotations annotations, @NotNull Modality modality, diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 82f60dd204a..d169aa75921 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -514,11 +514,7 @@ class LazyJavaClassMemberScope( "for getter is ${getterMethod.modality}, but for setter is ${setterMethod?.modality}" } - val propertyDescriptor = JavaPropertyDescriptor.create( - ownerDescriptor, Annotations.EMPTY, getterMethod.modality, getterMethod.visibility, - /* isVar = */ setterMethod != null, overriddenProperty.name, getterMethod.source, - /* isStaticFinal = */ false - ) + val propertyDescriptor = JavaForKotlinOverridePropertyDescriptor(ownerDescriptor, getterMethod, setterMethod, overriddenProperty) propertyDescriptor.setType(getterMethod.returnType!!, listOf(), getDispatchReceiverParameter(), null)