From 3b968351bb46654221b5dc6c2bcb6bedb69ff6b3 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 22 Jun 2018 10:42:02 +0300 Subject: [PATCH] Load Java overrides of Kotlin suspend functions as suspend, too There's still some blind spots: - Covariant overrides in Java (KT-25036) - Current implementation assumes that when language version is 1.3 every suspend function reference only release-coroutines-package Continuation (we need to check if it's a correct statement) #KT-24848 Fixed #KT-25036 Open --- .../coroutines/coroutineCodegenUtil.kt | 6 +- .../kotlin/frontend/java/di/injection.kt | 4 + .../suspendCovariantJavaOverrides.kt | 49 ++++++++ .../box/coroutines/suspendJavaOverrides.kt | 39 +++++++ .../coroutines/suspendCovarianJavaOverride.kt | 48 ++++++++ .../suspendCovarianJavaOverride.txt | 44 +++++++ ...endJavaImplementationFromDifferentClass.kt | 51 +++++++++ ...ndJavaImplementationFromDifferentClass.txt | 52 +++++++++ .../coroutines/suspendJavaOverrides.kt | 48 ++++++++ .../coroutines/suspendJavaOverrides.txt | 44 +++++++ .../coroutines/suspendOverridability.kt | 2 +- .../coroutines/suspendOverridability.txt | 4 +- .../ir/IrBlackBoxCodegenTestGenerated.java | 24 ++++ .../DiagnosticsTestWithStdLibGenerated.java | 36 ++++++ ...ticsTestWithStdLibUsingJavacGenerated.java | 36 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 24 ++++ .../LightAnalysisModeTestGenerated.java | 24 ++++ .../kotlin/load/java/lazy/context.kt | 22 +++- .../descriptors/LazyJavaClassMemberScope.kt | 108 ++++++++++++++---- .../internal/components/RuntimeModuleData.kt | 4 +- .../kotlin/builtins/suspendFunctionTypes.kt | 2 +- .../descriptors/FunctionDescriptor.java | 2 +- .../impl/FunctionDescriptorImpl.java | 18 ++- .../ErrorSimpleFunctionDescriptorImpl.java | 2 +- 24 files changed, 646 insertions(+), 47 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt create mode 100644 compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt index 4aeba843c98..9debd265add 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -19,8 +19,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.topLevelClassAsmType import org.jetbrains.kotlin.codegen.topLevelClassInternalName -import org.jetbrains.kotlin.coroutines.isSuspendLambda import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.coroutines.isSuspendLambda import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor @@ -240,7 +240,7 @@ fun getOrCreateJvmSuspendFunctionView( setReturnType(function.builtIns.nullableAnyType) setValueParameters(it.valueParameters + continuationParameter) if (dropSuspend) { - setDropSuspend() + setIsSuspend(false) } putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it) } @@ -475,4 +475,4 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when is AnonymousFunctionDescriptor -> this.isSuspendLambda is SimpleFunctionDescriptor -> this.visibility == Visibilities.LOCAL else -> false -} \ No newline at end of file +} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index bc5fbe27510..d87bc4a4e23 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer import org.jetbrains.kotlin.load.java.JavaClassFinderImpl import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.java.components.* +import org.jetbrains.kotlin.load.java.lazy.JavaResolverSettings import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory @@ -115,6 +116,9 @@ fun createContainerForLazyResolveWithJava( } useInstance(javaClassTracker ?: JavaClassesTracker.Default) + useInstance( + JavaResolverSettings.create(isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) + ) targetEnvironment.configure(this) diff --git a/compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt b/compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt new file mode 100644 index 00000000000..d7efa8ea2e6 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt @@ -0,0 +1,49 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST + +// FILE: I.kt + +interface I { + suspend fun foo(x: Int): String + suspend fun bar(x: Int): String +} + +// FILE: JavaClass.java + +public class JavaClass implements I { + @Override + public String foo(int x, COROUTINES_PACKAGE.Continuation continuation) { + return "O"; + } + + @Override + public Object bar(int x, COROUTINES_PACKAGE.Continuation continuation) { + return foo(x, continuation); + } +} + +// FILE: main.kt +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +class K : JavaClass() { + override suspend fun foo(x: Int): String = super.foo(x) + suspendCoroutine { it.resume("K") } +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "fail" + + builder { + // Changing the call to 'K().bar(1)' doesn't work because of KT-25036 + result = K().foo(1) + } + + return result +} diff --git a/compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt b/compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt new file mode 100644 index 00000000000..3c1dbc25ab0 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt @@ -0,0 +1,39 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST + +// FILE: I.kt + +interface I { + suspend fun foo(x: Int): String +} + +// FILE: JavaClass.java + +public class JavaClass implements I { + @Override + public Object foo(int x, COROUTINES_PACKAGE.Continuation continuation) { + continuation.resume("OK"); + return COROUTINES_PACKAGE.intrinsics.IntrinsicsKt.getCOROUTINE_SUSPENDED(); + } +} + +// FILE: main.kt +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "fail" + + builder { + result = JavaClass().foo(1) + } + + return result +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt new file mode 100644 index 00000000000..6f88bff7f1b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt @@ -0,0 +1,48 @@ +// COMMON_COROUTINES_TEST +// FILE: I.kt + +interface I { + suspend fun foo(x: Int): String +} + +// FILE: JavaClass.java +public class JavaClass implements I { + @Override + public String foo(int x, COROUTINES_PACKAGE.Continuation continuation) { + return null; + } +} + +// FILE: main.kt + +import COROUTINES_PACKAGE.Continuation +class K1 : JavaClass() + +class K2 : JavaClass() { + override suspend fun foo(x: Int): String = "" +} + +class K3 : JavaClass() { + override fun foo(x: Int, y: Continuation): Any? = null +} + +fun builder(block: suspend () -> Unit) {} + +fun main(x: Continuation) { + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + + builder { + JavaClass().foo(1) + K1().foo(2) + K2().foo(3) + K3().foo(4) + + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.txt new file mode 100644 index 00000000000..01ec7dd2996 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.txt @@ -0,0 +1,44 @@ +package + +public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit +public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation): kotlin.Unit + +public interface I { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class JavaClass : I { + public constructor JavaClass() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K1 : JavaClass { + public constructor K1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K2 : JavaClass { + public constructor K2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K3 : JavaClass { + public constructor K3() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open fun foo(/*0*/ x: kotlin.Int, /*1*/ y: COROUTINES_PACKAGE.Continuation): kotlin.Any? + 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/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt new file mode 100644 index 00000000000..dee8b5cf90c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt @@ -0,0 +1,51 @@ +// COMMON_COROUTINES_TEST +// FILE: I.kt + +interface I { + suspend fun foo(x: Int): String +} + +// FILE: BaseJavaClass.java +public class BaseJavaClass { + public Object foo(int x, COROUTINES_PACKAGE.Continuation continuation) { + return null; + } +} + +// FILE: JavaClass.java +public class JavaClass extends BaseJavaClass implements I { +} + +// FILE: main.kt + +import COROUTINES_PACKAGE.Continuation +class K1 : JavaClass() + +class K2 : JavaClass() { + override suspend fun foo(x: Int): String = "" +} + +class K3 : JavaClass() { + override fun foo(x: Int, y: Continuation): Any? = null +} + +fun builder(block: suspend () -> Unit) {} + +fun main(x: Continuation) { + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + + builder { + JavaClass().foo(1) + K1().foo(2) + K2().foo(3) + K3().foo(4) + + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.txt new file mode 100644 index 00000000000..b18d4f3710b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.txt @@ -0,0 +1,52 @@ +package + +public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit +public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation): kotlin.Unit + +public open class BaseJavaClass { + public constructor BaseJavaClass() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(/*0*/ x: kotlin.Int, /*1*/ continuation: COROUTINES_PACKAGE.Continuation!): kotlin.Any! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface I { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class JavaClass : BaseJavaClass, I { + public constructor JavaClass() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K1 : JavaClass { + public constructor K1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K2 : JavaClass { + public constructor K2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K3 : JavaClass { + public constructor K3() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open fun foo(/*0*/ x: kotlin.Int, /*1*/ y: COROUTINES_PACKAGE.Continuation): kotlin.Any? + 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/testsWithStdLib/coroutines/suspendJavaOverrides.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt new file mode 100644 index 00000000000..8ba2a503022 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt @@ -0,0 +1,48 @@ +// COMMON_COROUTINES_TEST +// FILE: I.kt + +interface I { + suspend fun foo(x: Int): String +} + +// FILE: JavaClass.java +public class JavaClass implements I { + @Override + public Object foo(int x, COROUTINES_PACKAGE.Continuation continuation) { + return null; + } +} + +// FILE: main.kt + +import COROUTINES_PACKAGE.Continuation +class K1 : JavaClass() + +class K2 : JavaClass() { + override suspend fun foo(x: Int): String = "" +} + +class K3 : JavaClass() { + override fun foo(x: Int, y: Continuation): Any? = null +} + +fun builder(block: suspend () -> Unit) {} + +fun main(x: Continuation) { + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + + builder { + JavaClass().foo(1) + K1().foo(2) + K2().foo(3) + K3().foo(4) + + JavaClass().foo(5, x) + K1().foo(6, x) + K2().foo(7, x) + K3().foo(8, x) + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.txt new file mode 100644 index 00000000000..01ec7dd2996 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.txt @@ -0,0 +1,44 @@ +package + +public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit +public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation): kotlin.Unit + +public interface I { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class JavaClass : I { + public constructor JavaClass() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K1 : JavaClass { + public constructor K1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K2 : JavaClass { + public constructor K2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ suspend fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class K3 : JavaClass { + public constructor K3() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*1*/ suspend /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.String + public open fun foo(/*0*/ x: kotlin.Int, /*1*/ y: COROUTINES_PACKAGE.Continuation): kotlin.Any? + 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/testsWithStdLib/coroutines/suspendOverridability.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.kt index c5681b61af4..86a522aaa43 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.kt @@ -25,7 +25,7 @@ interface C : A { } class D : J { - suspend override fun foo() { + suspend override fun foo() { } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.txt index 2e59d7b322f..1005723b8a6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendOverridability.txt @@ -29,7 +29,6 @@ public final class D : J { public abstract override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ suspend fun foo(): kotlin.Unit - public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ y: kotlin.coroutines.experimental.Continuation!): kotlin.Any! public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } @@ -37,8 +36,7 @@ public final class D : J { public interface J : A { public abstract override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public abstract override /*1*/ suspend /*fake_override*/ fun foo(): kotlin.Unit - public abstract fun foo(/*0*/ y: kotlin.coroutines.experimental.Continuation!): kotlin.Any! + public abstract override /*1*/ suspend 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-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index acb3582cbc8..bef7361c6e0 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5975,6 +5975,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendDefaultImpl.kt") public void testSuspendDefaultImpl_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); @@ -6071,6 +6083,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspensionInsideSafeCallWithElvis.kt") public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 31b731aab0a..1bc0723f03b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -1502,6 +1502,18 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithOldAPI.kt"); } + @TestMetadata("suspendCovarianJavaOverride.kt") + public void testSuspendCovarianJavaOverride_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendCovarianJavaOverride.kt") + public void testSuspendCovarianJavaOverride_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendDestructuring.kt") public void testSuspendDestructuring() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt"); @@ -1524,6 +1536,30 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendJavaImplementationFromDifferentClass.kt") + public void testSuspendJavaImplementationFromDifferentClass_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaImplementationFromDifferentClass.kt") + public void testSuspendJavaImplementationFromDifferentClass_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendLambda.kt") public void testSuspendLambda_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 77c9541633b..3eba860e4ad 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -1502,6 +1502,18 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithOldAPI.kt"); } + @TestMetadata("suspendCovarianJavaOverride.kt") + public void testSuspendCovarianJavaOverride_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendCovarianJavaOverride.kt") + public void testSuspendCovarianJavaOverride_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCovarianJavaOverride.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendDestructuring.kt") public void testSuspendDestructuring() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt"); @@ -1524,6 +1536,30 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendJavaImplementationFromDifferentClass.kt") + public void testSuspendJavaImplementationFromDifferentClass_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaImplementationFromDifferentClass.kt") + public void testSuspendJavaImplementationFromDifferentClass_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaImplementationFromDifferentClass.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendLambda.kt") public void testSuspendLambda_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 5b4916d4408..79d461c738e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5975,6 +5975,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendDefaultImpl.kt") public void testSuspendDefaultImpl_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); @@ -6071,6 +6083,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspensionInsideSafeCallWithElvis.kt") public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index cc234803da4..058b07957a7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5975,6 +5975,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendCovariantJavaOverrides.kt") + public void testSuspendCovariantJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspendDefaultImpl.kt") public void testSuspendDefaultImpl_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); @@ -6071,6 +6083,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendJavaOverrides.kt") + public void testSuspendJavaOverrides_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("suspensionInsideSafeCallWithElvis.kt") public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt index 43fe48a1d4b..f2d48af354a 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -59,7 +59,8 @@ class JavaResolverComponents( val reflectionTypes: ReflectionTypes, val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver, val signatureEnhancement: SignatureEnhancement, - val javaClassesTracker: JavaClassesTracker + val javaClassesTracker: JavaClassesTracker, + val settings: JavaResolverSettings ) { fun replace( javaResolverCache: JavaResolverCache = this.javaResolverCache @@ -68,10 +69,27 @@ class JavaResolverComponents( signaturePropagator, errorReporter, javaResolverCache, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker, module, reflectionTypes, - annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker + annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, + settings ) } +interface JavaResolverSettings { + val isReleaseCoroutines: Boolean + + object Default : JavaResolverSettings { + override val isReleaseCoroutines: Boolean + get() = false + } + + companion object { + fun create(isReleaseCoroutines: Boolean): JavaResolverSettings = + object : JavaResolverSettings { + override val isReleaseCoroutines get() = isReleaseCoroutines + } + } +} + private typealias QualifierByApplicabilityType = EnumMap class JavaTypeQualifiersByElementType( 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 63833307cc5..68f5f35158e 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 @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.isContinuation import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl @@ -47,6 +48,7 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.descriptorUtil.classId +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.NotNullLazyValue @@ -54,6 +56,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.utils.SmartSet +import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.ifEmpty import java.util.* @@ -108,7 +111,9 @@ class LazyJavaClassMemberScope( } }) return false - return !function.doesOverrideRenamedBuiltins() && !function.shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters() + return !function.doesOverrideRenamedBuiltins() && + !function.shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters() && + !function.doesOverrideSuspendFunction() } /** @@ -153,6 +158,29 @@ class LazyJavaClassMemberScope( } } + private fun SimpleFunctionDescriptor.doesOverrideSuspendFunction(): Boolean { + val suspendView = this.createSuspendView() ?: return false + + return getFunctionsFromSupertypes(name).any { overriddenCandidate -> + overriddenCandidate.isSuspend && suspendView.doesOverride(overriddenCandidate) + } + } + + private fun SimpleFunctionDescriptor.createSuspendView(): SimpleFunctionDescriptor? { + val continuationParameter = valueParameters.lastOrNull()?.takeIf { + isContinuation( + it.type.constructor.declarationDescriptor?.fqNameUnsafe?.takeIf { it.isSafe }?.toSafe(), + c.components.settings.isReleaseCoroutines + ) + } ?: return null + + return newCopyBuilder() + .setIsSuspend(true) + .setValueParameters(valueParameters.dropLast(1)) + .setReturnType(continuationParameter.type.arguments[0].type) + .build() + } + private fun SimpleFunctionDescriptor.createRenamedCopy(builtinName: Name): SimpleFunctionDescriptor = this.newCopyBuilder().apply { setName(builtinName) @@ -233,7 +261,9 @@ class LazyJavaClassMemberScope( override fun computeNonDeclaredFunctions(result: MutableCollection, name: Name) { val functionsFromSupertypes = getFunctionsFromSupertypes(name) - if (!name.sameAsRenamedInJvmBuiltin && !name.sameAsBuiltinMethodWithErasedValueParameters) { + if (!name.sameAsRenamedInJvmBuiltin && !name.sameAsBuiltinMethodWithErasedValueParameters + && functionsFromSupertypes.none(FunctionDescriptor::isSuspend) + ) { // Simple fast path in case of name is not suspicious (i.e. name is not one of builtins that have different signature in Java) addFunctionFromSupertypes( result, name, @@ -251,13 +281,13 @@ class LazyJavaClassMemberScope( ) // add declarations - addOverriddenBuiltinMethods( + addOverriddenSpecialMethods( name, result, mergedFunctionFromSuperTypes, result, this::searchMethodsByNameWithoutBuiltinMagic ) // add from super types - addOverriddenBuiltinMethods( + addOverriddenSpecialMethods( name, result, mergedFunctionFromSuperTypes, specialBuiltinsFromSuperTypes, this::searchMethodsInSupertypesWithoutBuiltinMagic ) @@ -293,7 +323,9 @@ class LazyJavaClassMemberScope( } } - private fun addOverriddenBuiltinMethods( + // - Built-in (collections) methods with different signature in JDK + // - Suspend functions + private fun addOverriddenSpecialMethods( name: Name, alreadyDeclaredFunctions: Collection, candidatesForOverride: Collection, @@ -301,31 +333,59 @@ class LazyJavaClassMemberScope( functions: (Name) -> Collection ) { for (descriptor in candidatesForOverride) { - val overriddenBuiltin = descriptor.getOverriddenBuiltinWithDifferentJvmName() ?: continue + result.addIfNotNull( + obtainOverrideForBuiltinWithDifferentJvmName(descriptor, functions, name, alreadyDeclaredFunctions) + ) + result.addIfNotNull( + obtainOverrideForBuiltInWithErasedValueParametersInJava(descriptor, functions, alreadyDeclaredFunctions) + ) - val nameInJava = getJvmMethodNameIfSpecial(overriddenBuiltin)!! - for (method in functions(Name.identifier(nameInJava))) { - val renamedCopy = method.createRenamedCopy(name) + result.addIfNotNull(obtainOverrideForSuspend(descriptor, functions)) + } + } - if (doesOverrideRenamedDescriptor(overriddenBuiltin, renamedCopy)) { - result.add( - renamedCopy.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions) - ) - break - } + private fun obtainOverrideForBuiltInWithErasedValueParametersInJava( + descriptor: SimpleFunctionDescriptor, + functions: (Name) -> Collection, + alreadyDeclaredFunctions: Collection + ): SimpleFunctionDescriptor? { + val overriddenBuiltin = + BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) + ?: return null + + return createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions) + ?.takeIf(this::isVisibleAsFunctionInCurrentClass) + ?.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions) + } + + private fun obtainOverrideForBuiltinWithDifferentJvmName( + descriptor: SimpleFunctionDescriptor, + functions: (Name) -> Collection, + name: Name, + alreadyDeclaredFunctions: Collection + ): SimpleFunctionDescriptor? { + val overriddenBuiltin = descriptor.getOverriddenBuiltinWithDifferentJvmName() ?: return null + + val nameInJava = getJvmMethodNameIfSpecial(overriddenBuiltin)!! + for (method in functions(Name.identifier(nameInJava))) { + val renamedCopy = method.createRenamedCopy(name) + + if (doesOverrideRenamedDescriptor(overriddenBuiltin, renamedCopy)) { + return renamedCopy.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions) } } - for (descriptor in candidatesForOverride) { - val overriddenBuiltin = - BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) - ?: continue + return null + } - createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions)?.let { override -> - if (isVisibleAsFunctionInCurrentClass(override)) { - result.add(override.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions)) - } - } + private fun obtainOverrideForSuspend( + descriptor: SimpleFunctionDescriptor, + functions: (Name) -> Collection + ): SimpleFunctionDescriptor? { + if (!descriptor.isSuspend) return null + + return functions(descriptor.name).firstNotNullResult { overrideCandidate -> + overrideCandidate.createSuspendView()?.takeIf { suspendView -> suspendView.doesOverride(descriptor) } } } diff --git a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt index 2c7dc892561..15b64b547e5 100644 --- a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.java.components.JavaResolverCache import org.jetbrains.kotlin.load.java.components.SamConversionResolver import org.jetbrains.kotlin.load.java.components.SignaturePropagator import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents +import org.jetbrains.kotlin.load.java.lazy.JavaResolverSettings import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement @@ -72,7 +73,8 @@ class RuntimeModuleData private constructor( ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver, SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), - JavaClassesTracker.Default + JavaClassesTracker.Default, + JavaResolverSettings.Default ) val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt index dbab6a8ed71..90b3e45aa0f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt @@ -106,7 +106,7 @@ fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType, isRelease ).makeNullableAsSpecified(funType.isMarkedNullable) } -private fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean { +fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean { return if (isReleaseCoroutines) name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java index bb0af3e2fc3..4c2b8cbff19 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java @@ -145,7 +145,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor { CopyBuilder setDropOriginalInContainingParts(); @NotNull - CopyBuilder setDropSuspend(); + CopyBuilder setIsSuspend(boolean isSuspend); @NotNull CopyBuilder setHiddenToOvercomeSignatureClash(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index c33577da6f4..5f0a439d4c0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -376,7 +376,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo private Map, Object> userDataMap = new LinkedHashMap, Object>(); private Boolean newHasSynthesizedParameterNames = null; protected boolean justForTypeSubstitution = false; - private boolean dropSuspend = false; + private boolean isSuspend; public CopyConfiguration( @NotNull TypeSubstitution substitution, @@ -387,7 +387,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo @NotNull List newValueParameterDescriptors, @Nullable KotlinType newExtensionReceiverParameterType, @NotNull KotlinType newReturnType, - @Nullable Name name + @Nullable Name name, + boolean isSuspend ) { this.substitution = substitution; this.newOwner = newOwner; @@ -398,6 +399,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo this.newExtensionReceiverParameterType = newExtensionReceiverParameterType; this.newReturnType = newReturnType; this.name = name; + this.isSuspend = isSuspend; } @Override @@ -507,8 +509,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo @Override @NotNull - public CopyConfiguration setDropSuspend() { - this.dropSuspend = true; + public CopyConfiguration setIsSuspend(boolean isSuspend) { + this.isSuspend = isSuspend; return this; } @@ -586,7 +588,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo return new CopyConfiguration( substitutor.getSubstitution(), getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(), - getExtensionReceiverParameterType(), getReturnType(), null); + getExtensionReceiverParameterType(), getReturnType(), null, isSuspend); } @Nullable @@ -676,11 +678,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo substitutedDescriptor.setExternal(isExternal); substitutedDescriptor.setInline(isInline); substitutedDescriptor.setTailrec(isTailrec); - if (configuration.dropSuspend) { - substitutedDescriptor.setSuspend(false); - } else { - substitutedDescriptor.setSuspend(isSuspend); - } + substitutedDescriptor.setSuspend(configuration.isSuspend); substitutedDescriptor.setExpect(isExpect); substitutedDescriptor.setActual(isActual); substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorSimpleFunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorSimpleFunctionDescriptorImpl.java index 7ffc1929afd..2af3aa23a9e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorSimpleFunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorSimpleFunctionDescriptorImpl.java @@ -170,7 +170,7 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI @NotNull @Override - public CopyBuilder setDropSuspend() { + public CopyBuilder setIsSuspend(boolean isSuspend) { return this; }