Move SuspendFunction{N} interfaces to kotlin.coroutines package

#KT-25824: Fixed
This commit is contained in:
Ilmir Usmanov
2018-08-16 20:44:09 +03:00
parent 4a7703ed66
commit 0559cfb724
26 changed files with 111 additions and 103 deletions
@@ -4605,7 +4605,8 @@ The "returned" value of try expression with no finally is either the last expres
return Unit.INSTANCE;
}
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs);
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs,
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
return Unit.INSTANCE;
});
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.JvmDefaultMode;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
@@ -431,7 +432,8 @@ public class FunctionCodegen {
}
if (!functionDescriptor.isExternal()) {
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode());
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode(),
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
}
else if (staticInCompanionObject) {
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
@@ -614,7 +616,8 @@ public class FunctionCodegen {
@NotNull JvmMethodSignature signature,
@NotNull FunctionGenerationStrategy strategy,
@NotNull MemberCodegen<?> parentCodegen,
@NotNull JvmDefaultMode jvmDefaultMode
@NotNull JvmDefaultMode jvmDefaultMode,
boolean isReleaseCoroutines
) {
mv.visitCode();
@@ -624,7 +627,8 @@ public class FunctionCodegen {
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, typeMapper::mapAsmMethod)) {
generateTypeCheckBarrierIfNeeded(
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper);
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper,
isReleaseCoroutines);
}
Label methodEnd;
@@ -1447,7 +1451,8 @@ public class FunctionCodegen {
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper);
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper,
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
}
iv.load(0, OBJECT_TYPE);
@@ -1492,7 +1497,8 @@ public class FunctionCodegen {
@NotNull FunctionDescriptor descriptor,
@NotNull Type returnType,
@Nullable Type[] delegateParameterTypes,
@NotNull KotlinTypeMapper typeMapper
@NotNull KotlinTypeMapper typeMapper,
boolean isReleaseCoroutines
) {
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription typeSafeBarrierDescription =
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor);
@@ -1526,7 +1532,7 @@ public class FunctionCodegen {
} else {
targetBoxedType = boxType(delegateParameterTypes[i]);
}
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType);
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType, isReleaseCoroutines);
iv.ifeq(defaultBranch);
}
}
@@ -59,12 +59,11 @@ import java.io.PrintWriter
import java.io.StringWriter
import java.util.*
@JvmOverloads
fun generateIsCheck(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type,
isReleaseCoroutines: Boolean = false
isReleaseCoroutines: Boolean
) {
if (TypeUtils.isNullableType(kotlinType)) {
val nope = Label()
@@ -90,13 +89,12 @@ fun generateIsCheck(
}
}
@JvmOverloads
fun generateAsCast(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type,
isSafe: Boolean,
isReleaseCoroutines: Boolean = false
isReleaseCoroutines: Boolean
) {
if (!isSafe) {
if (!TypeUtils.isNullableType(kotlinType)) {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.bytecode
import org.jetbrains.kotlin.codegen.intrinsics.classId
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
import org.jetbrains.kotlin.name.Name
@@ -74,7 +75,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
private val initialFrameSize = codegen.frameMap.currentSize
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings)
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings, state.languageVersionSettings.isReleaseCoroutines())
protected val functionDescriptor: FunctionDescriptor =
if (InlineUtil.isArrayConstructorWithLambda(function))
@@ -57,7 +57,7 @@ class ReificationArgument(
}
}
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) {
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?, private val isReleaseCoroutines: Boolean) {
enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED;
@@ -168,7 +168,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
if (stubCheckcast !is TypeInsnNode) return false
val newMethodNode = MethodNode(API)
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe, isReleaseCoroutines)
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubCheckcast)
@@ -188,7 +188,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
if (stubInstanceOf !is TypeInsnNode) return false
val newMethodNode = MethodNode(API)
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType, isReleaseCoroutines)
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubInstanceOf)
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.context.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -188,7 +189,10 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
else -> FunctionGenerationStrategy.FunctionDefault(state, expression as KtDeclarationWithBody)
}
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode)
FunctionCodegen.generateMethodBody(
adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode,
state.languageVersionSettings.isReleaseCoroutines()
)
if (isLambda) {
codegen.propagateChildReifiedTypeParametersUsages(parentCodegen.reifiedTypeParametersUsages)
@@ -164,8 +164,7 @@ object TypeIntrinsics {
}
private val KOTLIN_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.Function([0-9]+)$")
// TODO: move to correct package
private val KOTLIN_SUSPEND_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.SuspendFunction([0-9]+)$")
private val KOTLIN_SUSPEND_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.coroutines\\.SuspendFunction([0-9]+)$")
/**
* @return function type arity (non-negative), or -1 if the given type is not a function type
@@ -179,7 +178,7 @@ object TypeIntrinsics {
}
/**
* @return function type arity (non-negative, counting continuation), or -1 if the given type is not a function type
* @return function type arity (non-negative, not counting continuation), or -1 if the given type is not a function type
*/
private fun getSuspendFunctionTypeArity(kotlinType: KotlinType): Int =
getFunctionTypeArityByRegex(kotlinType, KOTLIN_SUSPEND_FUNCTION_INTERFACE_REGEX)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
@@ -650,14 +651,17 @@ class ExpressionCodegen(
StackValue.putUnitInstance(mv)
}
val boxedType = boxType(asmType)
generateAsCast(mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST)
generateAsCast(
mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST,
state.languageVersionSettings.isReleaseCoroutines()
)
return onStack(boxedType)
}
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> {
gen(expression.argument, OBJECT_TYPE, data)
val type = boxType(asmType)
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type)
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type, state.languageVersionSettings.isReleaseCoroutines())
if (IrTypeOperator.NOT_INSTANCEOF == expression.operator) {
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(Type.BOOLEAN_TYPE, mv)
}
@@ -7,6 +7,7 @@
// FILE: test.kt
import kotlin.reflect.KSuspendFunction0
import kotlin.coroutines.SuspendFunction0
class Test {
suspend fun o() = "O"
@@ -1,19 +0,0 @@
// IGNORE_BACKEND: JS_IR, JS
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// LANGUAGE_VERSION: 1.2
import helpers.*
import kotlin.coroutines.*
val lambda1 = { x: Any -> } as (Any) -> Unit
val suspendLambda0: suspend () -> Unit = {}
fun box(): String {
assert(lambda1 is SuspendFunction0<*>) { "Failed: lambda1 !is SuspendFunction0<*>" }
assert(suspendLambda0 is Function1<*, *>) { "Failed: suspendLambda0 is Function1<*, *>" }
assert(suspendLambda0 is SuspendFunction0<*>) { "Failed: suspendLambda0 is SuspendFunction0<*>" }
return "OK"
}
@@ -21,6 +21,10 @@ class A {
suspend fun suspendFoo() {}
}
inline fun <reified T : suspend () -> Unit> checkReified(noinline x: (Any?) -> Unit) {
if(x is T) throw IllegalStateException("x is T")
}
fun box(): String {
val f1 = ::fn1 as Any
val sf0 = ::suspendFn0 as Any
@@ -57,5 +61,7 @@ fun box(): String {
assert(safoo is Function2<*, *, *>) { "safoo is Function2<*, *, *>" }
assert(safoo is SuspendFunction1<*, *>) { "asfoo is SuspendFunction1<*, *>" }
checkReified<suspend () -> Unit> {}
return "OK"
}
@@ -0,0 +1,8 @@
// !LANGUAGE: +Coroutines
// !DIAGNOSTICS: -USELESS_IS_CHECK
// SKIP_TXT
fun test() {
suspend {} is <!UNRESOLVED_REFERENCE!>SuspendFunction0<!><*>
suspend {} is kotlin.coroutines.SuspendFunction0<*>
}
@@ -11,7 +11,7 @@ typealias Test4 = <!WRONG_MODIFIER_TARGET!>suspend<!> Action
typealias Test5 = List<suspend () -> Unit>
typealias Test6 = <!WRONG_MODIFIER_TARGET!>suspend<!> List<() -> Unit>
typealias Test7 = <!WRONG_MODIFIER_TARGET!>suspend<!> SAM
typealias Test8 = <!WRONG_MODIFIER_TARGET!>suspend<!> SuspendFunction0<Unit>
typealias Test8 = <!WRONG_MODIFIER_TARGET!>suspend<!> kotlin.coroutines.SuspendFunction0<Unit>
typealias Test9 = suspend (() -> Unit) -> Unit
typealias Test10 = suspend (suspend () -> Unit) -> Unit
typealias Test11 = suspend () -> (suspend () -> Unit)
@@ -1,4 +1,4 @@
// JAVAC_SKIP
typealias Test1 = SuspendFunction0<Unit>
typealias Test2 = kotlin.SuspendFunction0<Unit>
typealias Test3 = kotlin.coroutines.<!UNRESOLVED_REFERENCE!>SuspendFunction0<!><Unit>
typealias Test1 = <!UNRESOLVED_REFERENCE!>SuspendFunction0<!><Unit>
typealias Test2 = kotlin.<!UNRESOLVED_REFERENCE!>SuspendFunction0<!><Unit>
typealias Test3 = kotlin.coroutines.SuspendFunction0<Unit>
@@ -1,5 +1,5 @@
package
public typealias Test1 = suspend () -> kotlin.Unit
public typealias Test2 = suspend () -> kotlin.Unit
public typealias Test3 = [ERROR : kotlin.coroutines.SuspendFunction0<Unit>]<kotlin.Unit>
public typealias Test1 = [ERROR : SuspendFunction0<Unit>]<kotlin.Unit>
public typealias Test2 = [ERROR : kotlin.SuspendFunction0<Unit>]<kotlin.Unit>
public typealias Test3 = suspend () -> kotlin.Unit
@@ -1553,6 +1553,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendExternalFunctions.kt");
}
@TestMetadata("suspendFunctionN.kt")
public void testSuspendFunctionN() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionN.kt");
}
@TestMetadata("suspendFunctions.kt")
public void testSuspendFunctions_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctions.kt", "kotlin.coroutines.experimental");
@@ -1553,6 +1553,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendExternalFunctions.kt");
}
@TestMetadata("suspendFunctionN.kt")
public void testSuspendFunctionN() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionN.kt");
}
@TestMetadata("suspendFunctions.kt")
public void testSuspendFunctions_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctions.kt", "kotlin.coroutines.experimental");
@@ -6505,11 +6505,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/suspendDestructuringInLambdas.kt", "kotlin.coroutines");
}
@TestMetadata("suspendFunction12.kt")
public void testSuspendFunction12() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunction12.kt");
}
@TestMetadata("suspendFunctionIsAs.kt")
public void testSuspendFunctionIsAs() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionIsAs.kt");
@@ -6505,11 +6505,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/suspendDestructuringInLambdas.kt", "kotlin.coroutines");
}
@TestMetadata("suspendFunction12.kt")
public void testSuspendFunction12() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunction12.kt");
}
@TestMetadata("suspendFunctionIsAs.kt")
public void testSuspendFunctionIsAs() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionIsAs.kt");
@@ -6505,11 +6505,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/suspendDestructuringInLambdas.kt", "kotlin.coroutines");
}
@TestMetadata("suspendFunction12.kt")
public void testSuspendFunction12() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunction12.kt");
}
@TestMetadata("suspendFunctionIsAs.kt")
public void testSuspendFunctionIsAs() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/suspendFunctionIsAs.kt");