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
This commit is contained in:
Denis Zharkov
2018-06-22 10:42:02 +03:00
parent 0fc9bb3f4a
commit 3b968351bb
24 changed files with 646 additions and 47 deletions
@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.topLevelClassAsmType import org.jetbrains.kotlin.codegen.topLevelClassAsmType
import org.jetbrains.kotlin.codegen.topLevelClassInternalName import org.jetbrains.kotlin.codegen.topLevelClassInternalName
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
@@ -240,7 +240,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
setReturnType(function.builtIns.nullableAnyType) setReturnType(function.builtIns.nullableAnyType)
setValueParameters(it.valueParameters + continuationParameter) setValueParameters(it.valueParameters + continuationParameter)
if (dropSuspend) { if (dropSuspend) {
setDropSuspend() setIsSuspend(false)
} }
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it) putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it)
} }
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.java.JavaClassesTracker
import org.jetbrains.kotlin.load.java.components.* 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.java.lazy.ModuleClassResolver
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
@@ -115,6 +116,9 @@ fun createContainerForLazyResolveWithJava(
} }
useInstance(javaClassTracker ?: JavaClassesTracker.Default) useInstance(javaClassTracker ?: JavaClassesTracker.Default)
useInstance(
JavaResolverSettings.create(isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines))
)
targetEnvironment.configure(this) targetEnvironment.configure(this)
@@ -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<? super String> continuation) {
return "O";
}
@Override
public Object bar(int x, COROUTINES_PACKAGE.Continuation<? super String> 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
}
@@ -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<? super String> 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
}
@@ -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<String> 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() {
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: Int, y: Continuation<String>): Any? = null
}
fun builder(<!UNUSED_PARAMETER!>block<!>: suspend () -> Unit) {}
fun main(x: Continuation<String>) {
JavaClass().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
builder {
JavaClass().foo(1)
K1().foo(2)
K2().foo(3)
K3().foo(4)
JavaClass().foo(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().foo(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().foo(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
}
}
@@ -0,0 +1,44 @@
package
public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit
public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation<kotlin.String>): 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.String>): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -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<String> 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() {
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: Int, y: Continuation<String>): Any? = null
}
fun builder(<!UNUSED_PARAMETER!>block<!>: suspend () -> Unit) {}
fun main(x: Continuation<String>) {
JavaClass().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
builder {
JavaClass().foo(1)
K1().foo(2)
K2().foo(3)
K3().foo(4)
JavaClass().foo(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().foo(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().foo(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
}
}
@@ -0,0 +1,52 @@
package
public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit
public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation<kotlin.String>): 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.String!>!): 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.String>): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -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<String> 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() {
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: Int, y: Continuation<String>): Any? = null
}
fun builder(<!UNUSED_PARAMETER!>block<!>: suspend () -> Unit) {}
fun main(x: Continuation<String>) {
JavaClass().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
builder {
JavaClass().foo(1)
K1().foo(2)
K2().foo(3)
K3().foo(4)
JavaClass().foo(5, <!TOO_MANY_ARGUMENTS!>x<!>)
K1().foo(6, <!TOO_MANY_ARGUMENTS!>x<!>)
K2().foo(7, <!TOO_MANY_ARGUMENTS!>x<!>)
K3().foo(8, x)
}
}
@@ -0,0 +1,44 @@
package
public fun builder(/*0*/ block: suspend () -> kotlin.Unit): kotlin.Unit
public fun main(/*0*/ x: COROUTINES_PACKAGE.Continuation<kotlin.String>): 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.String>): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -25,7 +25,7 @@ interface C : A {
} }
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class D<!> : J { <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class D<!> : J {
<!ACCIDENTAL_OVERRIDE!>suspend override fun foo()<!> { suspend override fun foo() {
} }
} }
@@ -29,7 +29,6 @@ public final class D : J {
public abstract override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit 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*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ suspend fun foo(): kotlin.Unit public open override /*1*/ suspend fun foo(): kotlin.Unit
public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ y: kotlin.coroutines.experimental.Continuation<kotlin.Unit!>!): kotlin.Any!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -37,8 +36,7 @@ public final class D : J {
public interface J : A { public interface J : A {
public abstract override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit 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*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ suspend /*fake_override*/ fun foo(): kotlin.Unit public abstract override /*1*/ suspend fun foo(): kotlin.Unit
public abstract fun foo(/*0*/ y: kotlin.coroutines.experimental.Continuation<kotlin.Unit!>!): kotlin.Any!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -5975,6 +5975,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspendDefaultImpl.kt")
public void testSuspendDefaultImpl_1_2() throws Exception { public void testSuspendDefaultImpl_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt");
@@ -6071,6 +6083,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspensionInsideSafeCallWithElvis.kt")
public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt");
@@ -1502,6 +1502,18 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithOldAPI.kt"); 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") @TestMetadata("suspendDestructuring.kt")
public void testSuspendDestructuring() throws Exception { public void testSuspendDestructuring() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt");
@@ -1524,6 +1536,30 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspendLambda.kt")
public void testSuspendLambda_1_2() throws Exception { public void testSuspendLambda_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt");
@@ -1502,6 +1502,18 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithOldAPI.kt"); 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") @TestMetadata("suspendDestructuring.kt")
public void testSuspendDestructuring() throws Exception { public void testSuspendDestructuring() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt");
@@ -1524,6 +1536,30 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspendLambda.kt")
public void testSuspendLambda_1_2() throws Exception { public void testSuspendLambda_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendLambda.kt");
@@ -5975,6 +5975,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspendDefaultImpl.kt")
public void testSuspendDefaultImpl_1_2() throws Exception { public void testSuspendDefaultImpl_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt");
@@ -6071,6 +6083,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspensionInsideSafeCallWithElvis.kt")
public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt");
@@ -5975,6 +5975,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspendDefaultImpl.kt")
public void testSuspendDefaultImpl_1_2() throws Exception { public void testSuspendDefaultImpl_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDefaultImpl.kt");
@@ -6071,6 +6083,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); 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") @TestMetadata("suspensionInsideSafeCallWithElvis.kt")
public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception { public void testSuspensionInsideSafeCallWithElvis_1_2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt");
@@ -59,7 +59,8 @@ class JavaResolverComponents(
val reflectionTypes: ReflectionTypes, val reflectionTypes: ReflectionTypes,
val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver, val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver,
val signatureEnhancement: SignatureEnhancement, val signatureEnhancement: SignatureEnhancement,
val javaClassesTracker: JavaClassesTracker val javaClassesTracker: JavaClassesTracker,
val settings: JavaResolverSettings
) { ) {
fun replace( fun replace(
javaResolverCache: JavaResolverCache = this.javaResolverCache javaResolverCache: JavaResolverCache = this.javaResolverCache
@@ -68,10 +69,27 @@ class JavaResolverComponents(
signaturePropagator, errorReporter, javaResolverCache, signaturePropagator, errorReporter, javaResolverCache,
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker, module, reflectionTypes, 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<AnnotationTypeQualifierResolver.QualifierApplicabilityType, NullabilityQualifierWithMigrationStatus?> private typealias QualifierByApplicabilityType = EnumMap<AnnotationTypeQualifierResolver.QualifierApplicabilityType, NullabilityQualifierWithMigrationStatus?>
class JavaTypeQualifiersByElementType( class JavaTypeQualifiersByElementType(
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.load.java.lazy.descriptors package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isContinuation
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl 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.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.descriptorUtil.classId 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.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.storage.NotNullLazyValue 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.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import org.jetbrains.kotlin.utils.ifEmpty import org.jetbrains.kotlin.utils.ifEmpty
import java.util.* import java.util.*
@@ -108,7 +111,9 @@ class LazyJavaClassMemberScope(
} }
}) return false }) 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 = private fun SimpleFunctionDescriptor.createRenamedCopy(builtinName: Name): SimpleFunctionDescriptor =
this.newCopyBuilder().apply { this.newCopyBuilder().apply {
setName(builtinName) setName(builtinName)
@@ -233,7 +261,9 @@ class LazyJavaClassMemberScope(
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) { override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val functionsFromSupertypes = getFunctionsFromSupertypes(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) // 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( addFunctionFromSupertypes(
result, name, result, name,
@@ -251,13 +281,13 @@ class LazyJavaClassMemberScope(
) )
// add declarations // add declarations
addOverriddenBuiltinMethods( addOverriddenSpecialMethods(
name, result, mergedFunctionFromSuperTypes, result, name, result, mergedFunctionFromSuperTypes, result,
this::searchMethodsByNameWithoutBuiltinMagic this::searchMethodsByNameWithoutBuiltinMagic
) )
// add from super types // add from super types
addOverriddenBuiltinMethods( addOverriddenSpecialMethods(
name, result, mergedFunctionFromSuperTypes, specialBuiltinsFromSuperTypes, name, result, mergedFunctionFromSuperTypes, specialBuiltinsFromSuperTypes,
this::searchMethodsInSupertypesWithoutBuiltinMagic 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, name: Name,
alreadyDeclaredFunctions: Collection<SimpleFunctionDescriptor>, alreadyDeclaredFunctions: Collection<SimpleFunctionDescriptor>,
candidatesForOverride: Collection<SimpleFunctionDescriptor>, candidatesForOverride: Collection<SimpleFunctionDescriptor>,
@@ -301,31 +333,59 @@ class LazyJavaClassMemberScope(
functions: (Name) -> Collection<SimpleFunctionDescriptor> functions: (Name) -> Collection<SimpleFunctionDescriptor>
) { ) {
for (descriptor in candidatesForOverride) { 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)!! result.addIfNotNull(obtainOverrideForSuspend(descriptor, functions))
for (method in functions(Name.identifier(nameInJava))) { }
val renamedCopy = method.createRenamedCopy(name) }
if (doesOverrideRenamedDescriptor(overriddenBuiltin, renamedCopy)) { private fun obtainOverrideForBuiltInWithErasedValueParametersInJava(
result.add( descriptor: SimpleFunctionDescriptor,
renamedCopy.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions) functions: (Name) -> Collection<SimpleFunctionDescriptor>,
) alreadyDeclaredFunctions: Collection<SimpleFunctionDescriptor>
break ): 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<SimpleFunctionDescriptor>,
name: Name,
alreadyDeclaredFunctions: Collection<SimpleFunctionDescriptor>
): 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) { return null
val overriddenBuiltin = }
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor)
?: continue
createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions)?.let { override -> private fun obtainOverrideForSuspend(
if (isVisibleAsFunctionInCurrentClass(override)) { descriptor: SimpleFunctionDescriptor,
result.add(override.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, alreadyDeclaredFunctions)) functions: (Name) -> Collection<SimpleFunctionDescriptor>
} ): SimpleFunctionDescriptor? {
} if (!descriptor.isSuspend) return null
return functions(descriptor.name).firstNotNullResult { overrideCandidate ->
overrideCandidate.createSuspendView()?.takeIf { suspendView -> suspendView.doesOverride(descriptor) }
} }
} }
@@ -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.SamConversionResolver
import org.jetbrains.kotlin.load.java.components.SignaturePropagator import org.jetbrains.kotlin.load.java.components.SignaturePropagator
import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents 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.LazyJavaPackageFragmentProvider
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
@@ -72,7 +73,8 @@ class RuntimeModuleData private constructor(
ReflectionTypes(module, notFoundClasses), ReflectionTypes(module, notFoundClasses),
annotationTypeQualifierResolver, annotationTypeQualifierResolver,
SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED),
JavaClassesTracker.Default JavaClassesTracker.Default,
JavaResolverSettings.Default
) )
val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext) val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext)
@@ -106,7 +106,7 @@ fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType, isRelease
).makeNullableAsSpecified(funType.isMarkedNullable) ).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 return if (isReleaseCoroutines) name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
} }
@@ -145,7 +145,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
CopyBuilder<D> setDropOriginalInContainingParts(); CopyBuilder<D> setDropOriginalInContainingParts();
@NotNull @NotNull
CopyBuilder<D> setDropSuspend(); CopyBuilder<D> setIsSuspend(boolean isSuspend);
@NotNull @NotNull
CopyBuilder<D> setHiddenToOvercomeSignatureClash(); CopyBuilder<D> setHiddenToOvercomeSignatureClash();
@@ -376,7 +376,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>(); private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
private Boolean newHasSynthesizedParameterNames = null; private Boolean newHasSynthesizedParameterNames = null;
protected boolean justForTypeSubstitution = false; protected boolean justForTypeSubstitution = false;
private boolean dropSuspend = false; private boolean isSuspend;
public CopyConfiguration( public CopyConfiguration(
@NotNull TypeSubstitution substitution, @NotNull TypeSubstitution substitution,
@@ -387,7 +387,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
@NotNull List<ValueParameterDescriptor> newValueParameterDescriptors, @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
@Nullable KotlinType newExtensionReceiverParameterType, @Nullable KotlinType newExtensionReceiverParameterType,
@NotNull KotlinType newReturnType, @NotNull KotlinType newReturnType,
@Nullable Name name @Nullable Name name,
boolean isSuspend
) { ) {
this.substitution = substitution; this.substitution = substitution;
this.newOwner = newOwner; this.newOwner = newOwner;
@@ -398,6 +399,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
this.newExtensionReceiverParameterType = newExtensionReceiverParameterType; this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
this.newReturnType = newReturnType; this.newReturnType = newReturnType;
this.name = name; this.name = name;
this.isSuspend = isSuspend;
} }
@Override @Override
@@ -507,8 +509,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
@Override @Override
@NotNull @NotNull
public CopyConfiguration setDropSuspend() { public CopyConfiguration setIsSuspend(boolean isSuspend) {
this.dropSuspend = true; this.isSuspend = isSuspend;
return this; return this;
} }
@@ -586,7 +588,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
return new CopyConfiguration( return new CopyConfiguration(
substitutor.getSubstitution(), substitutor.getSubstitution(),
getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(), getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
getExtensionReceiverParameterType(), getReturnType(), null); getExtensionReceiverParameterType(), getReturnType(), null, isSuspend);
} }
@Nullable @Nullable
@@ -676,11 +678,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
substitutedDescriptor.setExternal(isExternal); substitutedDescriptor.setExternal(isExternal);
substitutedDescriptor.setInline(isInline); substitutedDescriptor.setInline(isInline);
substitutedDescriptor.setTailrec(isTailrec); substitutedDescriptor.setTailrec(isTailrec);
if (configuration.dropSuspend) { substitutedDescriptor.setSuspend(configuration.isSuspend);
substitutedDescriptor.setSuspend(false);
} else {
substitutedDescriptor.setSuspend(isSuspend);
}
substitutedDescriptor.setExpect(isExpect); substitutedDescriptor.setExpect(isExpect);
substitutedDescriptor.setActual(isActual); substitutedDescriptor.setActual(isActual);
substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames); substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
@@ -170,7 +170,7 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
@NotNull @NotNull
@Override @Override
public CopyBuilder<SimpleFunctionDescriptor> setDropSuspend() { public CopyBuilder<SimpleFunctionDescriptor> setIsSuspend(boolean isSuspend) {
return this; return this;
} }