JVM_IR indy-SAM conversions: inline classes
KT-44278 KT-26060 KT-42621
This commit is contained in:
+82
@@ -18480,6 +18480,88 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testSimpleIndySam() throws Exception {
|
public void testSimpleIndySam() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class InlineClassInSignature extends AbstractFirBlackBoxCodegenTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNString.kt")
|
||||||
|
public void testFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineString.kt")
|
||||||
|
public void testFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ class JvmSymbols(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val receiverFieldName = Name.identifier("receiver")
|
val receiverFieldName = Name.identifier("receiver")
|
||||||
klass.addProperty() {
|
klass.addProperty {
|
||||||
name = receiverFieldName
|
name = receiverFieldName
|
||||||
}.apply {
|
}.apply {
|
||||||
backingField = irFactory.buildField {
|
backingField = irFactory.buildField {
|
||||||
@@ -658,7 +658,7 @@ class JvmSymbols(
|
|||||||
collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 2 }
|
collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 2 }
|
||||||
|
|
||||||
val kClassJava: IrPropertySymbol =
|
val kClassJava: IrPropertySymbol =
|
||||||
irFactory.buildProperty() {
|
irFactory.buildProperty {
|
||||||
name = Name.identifier("java")
|
name = Name.identifier("java")
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = kotlinJvmPackage
|
parent = kotlinJvmPackage
|
||||||
|
|||||||
+30
-24
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.overrides.buildFakeOverrideMember
|
import org.jetbrains.kotlin.ir.overrides.buildFakeOverrideMember
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.Handle
|
import org.jetbrains.org.objectweb.asm.Handle
|
||||||
@@ -136,38 +134,46 @@ object JvmInvokeDynamic : IntrinsicMethod() {
|
|||||||
?: fail("Argument in ${irCall.symbol.owner.name} call is expected to be a raw function reference")
|
?: fail("Argument in ${irCall.symbol.owner.name} call is expected to be a raw function reference")
|
||||||
val irOriginalFun = irRawFunRef.symbol.owner as? IrSimpleFunction
|
val irOriginalFun = irRawFunRef.symbol.owner as? IrSimpleFunction
|
||||||
?: fail("IrSimpleFunction expected: ${irRawFunRef.symbol.owner.render()}")
|
?: fail("IrSimpleFunction expected: ${irRawFunRef.symbol.owner.render()}")
|
||||||
val substitutedType = irCall.getTypeArgument(0) as? IrSimpleType
|
val superType = irCall.getTypeArgument(0) as? IrSimpleType
|
||||||
?: fail("Type argument expected")
|
?: fail("Type argument expected")
|
||||||
|
|
||||||
// Force boxing on primitive types, otherwise D8 fails to accept resulting MethodType in presence of primitive types in arguments
|
val patchedSuperType = replaceTypeArgumentsWithNullable(superType)
|
||||||
// (LambdaMetafactory is ok with such types, though).
|
|
||||||
val substitutedTypeWithNullableArgs =
|
|
||||||
substitutedType.classifier.typeWithArguments(
|
|
||||||
substitutedType.arguments.map {
|
|
||||||
when (it) {
|
|
||||||
is IrStarProjection -> it
|
|
||||||
is IrTypeProjection -> {
|
|
||||||
val type = it.type
|
|
||||||
if (type !is IrSimpleType || type.hasQuestionMark)
|
|
||||||
it
|
|
||||||
else
|
|
||||||
makeTypeProjection(type.withHasQuestionMark(true), it.variance)
|
|
||||||
}
|
|
||||||
else ->
|
|
||||||
fail("Unexpected type argument '${it}' :: ${it::class.simpleName}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val fakeClass = codegen.context.irFactory.buildClass { name = Name.special("<fake>") }
|
val fakeClass = codegen.context.irFactory.buildClass { name = Name.special("<fake>") }
|
||||||
fakeClass.parent = codegen.context.ir.symbols.kotlinJvmInternalInvokeDynamicPackage
|
fakeClass.parent = codegen.context.ir.symbols.kotlinJvmInternalInvokeDynamicPackage
|
||||||
val irFakeOverride = buildFakeOverrideMember(substitutedTypeWithNullableArgs, irOriginalFun, fakeClass) as IrSimpleFunction
|
val irFakeOverride = buildFakeOverrideMember(patchedSuperType, irOriginalFun, fakeClass) as IrSimpleFunction
|
||||||
irFakeOverride.overriddenSymbols = listOf(irOriginalFun.symbol)
|
irFakeOverride.overriddenSymbols = listOf(irOriginalFun.symbol)
|
||||||
|
|
||||||
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFakeOverride)
|
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFakeOverride)
|
||||||
return Type.getMethodType(asmMethod.descriptor)
|
return Type.getMethodType(asmMethod.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given the following functional interface
|
||||||
|
// fun interface IFoo<T> {
|
||||||
|
// fun foo(x: T): T
|
||||||
|
// }
|
||||||
|
// To comply with java.lang.invoke.LambdaMetafactory requirements, we need an instance method that accepts references
|
||||||
|
// (not primitives, and not unboxed inline classes).
|
||||||
|
// In order to do so, we replace type arguments with nullable types.
|
||||||
|
private fun replaceTypeArgumentsWithNullable(substitutedType: IrSimpleType) =
|
||||||
|
substitutedType.classifier.typeWithArguments(
|
||||||
|
substitutedType.arguments.map { typeArgument ->
|
||||||
|
when (typeArgument) {
|
||||||
|
is IrStarProjection -> typeArgument
|
||||||
|
is IrTypeProjection -> {
|
||||||
|
val type = typeArgument.type
|
||||||
|
if (type !is IrSimpleType || type.hasQuestionMark)
|
||||||
|
typeArgument
|
||||||
|
else {
|
||||||
|
makeTypeProjection(type.withHasQuestionMark(true), typeArgument.variance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected type argument '$typeArgument' :: ${typeArgument::class.simpleName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
private fun IrExpression.getIntConst() =
|
private fun IrExpression.getIntConst() =
|
||||||
if (this is IrConst<*> && kind == IrConstKind.Int)
|
if (this is IrConst<*> && kind == IrConstKind.Int)
|
||||||
this.value as Int
|
this.value as Int
|
||||||
|
|||||||
+81
-3
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.lower.SamEqualsHashCodeMethodsGenerat
|
|||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
|
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
|
||||||
import org.jetbrains.kotlin.config.JvmSamConversions
|
import org.jetbrains.kotlin.config.JvmSamConversions
|
||||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
internal val functionReferencePhase = makeIrFilePhase(
|
internal val functionReferencePhase = makeIrFilePhase(
|
||||||
::FunctionReferenceLowering,
|
::FunctionReferenceLowering,
|
||||||
@@ -115,21 +117,54 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
// TODO special mode that would generate indy everywhere?
|
// TODO special mode that would generate indy everywhere?
|
||||||
if (reference.origin != IrStatementOrigin.LAMBDA)
|
if (reference.origin != IrStatementOrigin.LAMBDA)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
// TODO wrap intrinsic function in lambda?
|
// TODO wrap intrinsic function in lambda?
|
||||||
if (context.irIntrinsics.getIntrinsic(reference.symbol) != null)
|
if (context.irIntrinsics.getIntrinsic(reference.symbol) != null)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
// Can't use JDK LambdaMetafactory if lambda signature contains an inline class mapped to a non-null reference type.
|
||||||
|
val target = reference.symbol.owner
|
||||||
|
if (target.extensionReceiverParameter?.run { type.isProhibitedTypeForIndySamConversion() } == true ||
|
||||||
|
target.valueParameters.any { it.type.isProhibitedTypeForIndySamConversion() } ||
|
||||||
|
target.returnType.isProhibitedTypeForIndySamConversion()
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrType.isProhibitedTypeForIndySamConversion(): Boolean {
|
||||||
|
if (this !is IrSimpleType) return false
|
||||||
|
|
||||||
|
val erasedType = when (val classifier = classifier.owner) {
|
||||||
|
is IrTypeParameter ->
|
||||||
|
classifier.representativeUpperBound.withHasQuestionMark(hasQuestionMark)
|
||||||
|
else ->
|
||||||
|
this
|
||||||
|
}
|
||||||
|
val erasedClass = erasedType.getClass() ?: return false
|
||||||
|
|
||||||
|
if (!erasedType.isInlined()) return false
|
||||||
|
|
||||||
|
val underlyingType = getInlineClassUnderlyingType(erasedClass) as? IrSimpleType
|
||||||
|
?: throw AssertionError("Underlying type for inline class should be a simple type: ${erasedClass.render()}")
|
||||||
|
return !underlyingType.hasQuestionMark && !underlyingType.isJvmPrimitiveType()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrType.isJvmPrimitiveType() =
|
||||||
|
isBoolean() || isChar() || isByte() || isShort() || isInt() || isLong() || isFloat() || isDouble()
|
||||||
|
|
||||||
private fun wrapSamConversionArgumentWithIndySamConversion(expression: IrTypeOperatorCall): IrExpression {
|
private fun wrapSamConversionArgumentWithIndySamConversion(expression: IrTypeOperatorCall): IrExpression {
|
||||||
|
val samType = expression.typeOperand
|
||||||
return when (val argument = expression.argument) {
|
return when (val argument = expression.argument) {
|
||||||
is IrFunctionReference ->
|
is IrFunctionReference -> {
|
||||||
wrapWithIndySamConversion(expression.typeOperand, argument)
|
wrapWithIndySamConversion(samType, argument)
|
||||||
|
}
|
||||||
is IrBlock -> {
|
is IrBlock -> {
|
||||||
val last = argument.statements.last()
|
val last = argument.statements.last()
|
||||||
val functionReference = last as? IrFunctionReference
|
val functionReference = last as? IrFunctionReference
|
||||||
?: throw AssertionError("Function reference expected: ${last.render()}")
|
?: throw AssertionError("Function reference expected: ${last.render()}")
|
||||||
argument.statements[argument.statements.size - 1] = wrapWithIndySamConversion(expression.typeOperand, functionReference)
|
argument.statements[argument.statements.size - 1] = wrapWithIndySamConversion(samType, functionReference)
|
||||||
return argument
|
return argument
|
||||||
}
|
}
|
||||||
else -> throw AssertionError("Block or function reference expected: ${expression.render()}")
|
else -> throw AssertionError("Block or function reference expected: ${expression.render()}")
|
||||||
@@ -145,6 +180,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun wrapWithIndySamConversion(samType: IrType, irFunRef: IrFunctionReference): IrCall {
|
private fun wrapWithIndySamConversion(samType: IrType, irFunRef: IrFunctionReference): IrCall {
|
||||||
|
patchSignatureForIndySamConversion(irFunRef.symbol.owner, samType)
|
||||||
val notNullSamType = samType.makeNotNull()
|
val notNullSamType = samType.makeNotNull()
|
||||||
.removeAnnotations { it.type.classFqName in specialNullabilityAnnotationsFqNames }
|
.removeAnnotations { it.type.classFqName in specialNullabilityAnnotationsFqNames }
|
||||||
return context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
|
return context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
|
||||||
@@ -161,6 +197,48 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun patchSignatureForIndySamConversion(irLambda: IrFunction, samType: IrType) {
|
||||||
|
if (irLambda.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA)
|
||||||
|
throw AssertionError("Can't patch a signature of a non-lambda: ${irLambda.render()}")
|
||||||
|
|
||||||
|
val samClass = samType.classOrNull?.owner
|
||||||
|
?: throw AssertionError("SAM type should be a class type: '${samType.render()}'")
|
||||||
|
val samMethod = samClass.functions.singleOrNull { it.modality == Modality.ABSTRACT }
|
||||||
|
?: throw AssertionError("SAM method not found:\n${samClass.dump()}")
|
||||||
|
|
||||||
|
val samMethodParameters = collectValueParameters(samMethod)
|
||||||
|
val irLambdaParameters = collectValueParameters(irLambda)
|
||||||
|
if (samMethodParameters.size != irLambdaParameters.size) {
|
||||||
|
throw AssertionError(
|
||||||
|
"SAM method and implementing lambda have mismatching value parameters " +
|
||||||
|
"(${samMethodParameters.size} != ${irLambdaParameters.size}:\n" +
|
||||||
|
"samMethod: ${samMethod.render()}\n" +
|
||||||
|
"lambda: ${irLambda.render()}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((irLambdaParameter, samMethodParameter) in irLambdaParameters.zip(samMethodParameters)) {
|
||||||
|
irLambdaParameter.type = patchTypeForIndySamConversion(irLambdaParameter.type, samMethodParameter.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
irLambda.returnType = patchTypeForIndySamConversion(irLambda.returnType, samMethod.returnType)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectValueParameters(irFunction: IrFunction): List<IrValueParameter> =
|
||||||
|
ArrayList<IrValueParameter>().apply {
|
||||||
|
addIfNotNull(irFunction.extensionReceiverParameter)
|
||||||
|
addAll(irFunction.valueParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun patchTypeForIndySamConversion(originalType: IrType, targetType: IrType): IrType {
|
||||||
|
if (originalType.isUnboxedInlineClassType() && !targetType.isUnboxedInlineClassType())
|
||||||
|
return targetType
|
||||||
|
return originalType
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrType.isUnboxedInlineClassType() =
|
||||||
|
this is IrSimpleType && isInlined() && !hasQuestionMark
|
||||||
|
|
||||||
private inner class FunctionReferenceBuilder(val irFunctionReference: IrFunctionReference, val samSuperType: IrType? = null) {
|
private inner class FunctionReferenceBuilder(val irFunctionReference: IrFunctionReference, val samSuperType: IrType? = null) {
|
||||||
private val isLambda = irFunctionReference.origin.isLambda
|
private val isLambda = irFunctionReference.origin.isLambda
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -6,11 +6,21 @@ fun interface IFoo<T> {
|
|||||||
fun foo(x: T): T
|
fun foo(x: T): T
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo1(fs: IFoo<Int>) = fs.foo(1)
|
fun interface IBar<T : Any> {
|
||||||
|
fun bar(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun foo1(foo: IFoo<Int>) = foo.foo(1)
|
||||||
|
|
||||||
|
fun bar1(bar: IBar<Int>) = bar.bar(1)
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val t = foo1 { it + 41 }
|
val t = foo1 { it + 41 }
|
||||||
if (t != 42) return "Failed: t=$t"
|
if (t != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
val tt = bar1 { it + 41 }
|
||||||
|
if (tt != 42) return "Failed: tt=$tt"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Any)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z((it.value as Int) + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Int)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNAny.kt
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Any?)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z((it.value as Int) + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNInt.kt
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Int?)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value!! + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: String?)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z("O"))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value!! + "K") }
|
||||||
|
if (t.value != "OK") return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: String)
|
||||||
|
|
||||||
|
fun interface IFooZ {
|
||||||
|
fun foo(x: Z): Z
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFooZ) = fs.foo(Z("O"))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value + "K") }
|
||||||
|
if (t.value != "OK") return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Any)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z((it.value as Int) + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Int)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Any?)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z((it.value as Int) + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: Int?)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z(1))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value!! + 41) }
|
||||||
|
if (t.value != 42) return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: String?)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z("O"))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value!! + "K") }
|
||||||
|
if (t.value != "OK") return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
inline class Z(val value: String)
|
||||||
|
|
||||||
|
fun interface IFoo<T> {
|
||||||
|
fun foo(x: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo1(fs: IFoo<Z>) = fs.foo(Z("O"))
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val t = foo1 { Z(it.value + "K") }
|
||||||
|
if (t.value != "OK") return "Failed: t=$t"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+82
@@ -18480,6 +18480,88 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
public void testSimpleIndySam() throws Exception {
|
public void testSimpleIndySam() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class InlineClassInSignature extends AbstractBlackBoxCodegenTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNString.kt")
|
||||||
|
public void testFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineString.kt")
|
||||||
|
public void testFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+82
@@ -18480,6 +18480,88 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testSimpleIndySam() throws Exception {
|
public void testSimpleIndySam() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class InlineClassInSignature extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineNString.kt")
|
||||||
|
public void testFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceWithInlineString.kt")
|
||||||
|
public void testFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-3
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.directives
|
package org.jetbrains.kotlin.test.directives
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.JvmSamConversions
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
|
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
|
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
|
||||||
@@ -91,6 +90,4 @@ object CodegenTestDirectives : SimpleDirectivesContainer() {
|
|||||||
val TREAT_AS_ONE_FILE by directive(
|
val TREAT_AS_ONE_FILE by directive(
|
||||||
description = "Treat bytecode from all files as one in ${BytecodeTextHandler::class}"
|
description = "Treat bytecode from all files as one in ${BytecodeTextHandler::class}"
|
||||||
)
|
)
|
||||||
|
|
||||||
val SAM_CONVERSIONS by enumDirective<JvmSamConversions>("SAM conversion code generation scheme")
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.directives
|
package org.jetbrains.kotlin.test.directives
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.JVMAssertionsMode
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
|
||||||
import org.jetbrains.kotlin.config.JvmStringConcat
|
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||||
|
|
||||||
@@ -56,4 +53,9 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
description = "Configure jvm constructor call normalization mode",
|
description = "Configure jvm constructor call normalization mode",
|
||||||
additionalParser = JVMConstructorCallNormalizationMode.Companion::fromStringOrNull
|
additionalParser = JVMConstructorCallNormalizationMode.Companion::fromStringOrNull
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val SAM_CONVERSIONS by enumDirective<JvmSamConversions>(
|
||||||
|
description = "SAM conversion code generation scheme",
|
||||||
|
additionalParser = JvmSamConversions.Companion::fromString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
-10
@@ -40,13 +40,3 @@ abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.Frontend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class configures various JVM-specific codegen minutiae.
|
|
||||||
// Ideally, test directives could take care of such things themselves.
|
|
||||||
class JvmCodegenEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
|
|
||||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) {
|
|
||||||
val samConversions = module.directives[CodegenTestDirectives.SAM_CONVERSIONS].lastOrNull()
|
|
||||||
if (samConversions != null) {
|
|
||||||
configuration.put(JVMConfigurationKeys.SAM_CONVERSIONS, samConversions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-3
@@ -18,10 +18,10 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ASSERTIONS_MODE
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ASSERTIONS_MODE
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.CONSTRUCTOR_CALL_NORMALIZATION_MODE
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.CONSTRUCTOR_CALL_NORMALIZATION_MODE
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.SAM_CONVERSIONS
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STRING_CONCAT
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STRING_CONCAT
|
||||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||||
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.test.model.DependencyDescription
|
|||||||
import org.jetbrains.kotlin.test.model.DependencyKind
|
import org.jetbrains.kotlin.test.model.DependencyKind
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
import org.jetbrains.kotlin.test.services.DirectiveToConfigurationKeyExtractor
|
|
||||||
import org.jetbrains.kotlin.test.services.jvm.CompiledClassesManager
|
import org.jetbrains.kotlin.test.services.jvm.CompiledClassesManager
|
||||||
import org.jetbrains.kotlin.test.services.jvm.compiledClassesManager
|
import org.jetbrains.kotlin.test.services.jvm.compiledClassesManager
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||||
@@ -53,6 +52,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
|||||||
register(STRING_CONCAT, JVMConfigurationKeys.STRING_CONCAT)
|
register(STRING_CONCAT, JVMConfigurationKeys.STRING_CONCAT)
|
||||||
register(ASSERTIONS_MODE, JVMConfigurationKeys.ASSERTIONS_MODE)
|
register(ASSERTIONS_MODE, JVMConfigurationKeys.ASSERTIONS_MODE)
|
||||||
register(CONSTRUCTOR_CALL_NORMALIZATION_MODE, JVMConfigurationKeys.CONSTRUCTOR_CALL_NORMALIZATION_MODE)
|
register(CONSTRUCTOR_CALL_NORMALIZATION_MODE, JVMConfigurationKeys.CONSTRUCTOR_CALL_NORMALIZATION_MODE)
|
||||||
|
register(SAM_CONVERSIONS, JVMConfigurationKeys.SAM_CONVERSIONS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) {
|
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) {
|
||||||
@@ -162,7 +162,8 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind {
|
private fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind {
|
||||||
val withRuntime = JvmEnvironmentConfigurationDirectives.WITH_RUNTIME in registeredDirectives || JvmEnvironmentConfigurationDirectives.WITH_STDLIB in registeredDirectives
|
val withRuntime = JvmEnvironmentConfigurationDirectives.WITH_RUNTIME in registeredDirectives ||
|
||||||
|
JvmEnvironmentConfigurationDirectives.WITH_STDLIB in registeredDirectives
|
||||||
val withReflect = JvmEnvironmentConfigurationDirectives.WITH_REFLECT in registeredDirectives
|
val withReflect = JvmEnvironmentConfigurationDirectives.WITH_REFLECT in registeredDirectives
|
||||||
val noRuntime = JvmEnvironmentConfigurationDirectives.NO_RUNTIME in registeredDirectives
|
val noRuntime = JvmEnvironmentConfigurationDirectives.NO_RUNTIME in registeredDirectives
|
||||||
if (noRuntime && withRuntime) {
|
if (noRuntime && withRuntime) {
|
||||||
|
|||||||
+73
@@ -16202,6 +16202,79 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testSimpleIndySam() throws Exception {
|
public void testSimpleIndySam() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndySam.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class InlineClassInSignature extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineNAny.kt")
|
||||||
|
public void testFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineNInt.kt")
|
||||||
|
public void testFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineNString.kt")
|
||||||
|
public void testFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceWithInlineString.kt")
|
||||||
|
public void testFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/funInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNAny.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNAny() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNAny.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNInt.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNInt() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNInt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineNString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineNString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineNString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericFunInterfaceWithInlineString.kt")
|
||||||
|
public void testGenericFunInterfaceWithInlineString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature/genericFunInterfaceWithInlineString.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+13
@@ -13902,6 +13902,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
public void testAllFilesPresentInSam() throws Exception {
|
public void testAllFilesPresentInSam() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class InlineClassInSignature extends AbstractIrJsCodegenBoxES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+13
@@ -13902,6 +13902,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInSam() throws Exception {
|
public void testAllFilesPresentInSam() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class InlineClassInSignature extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+13
@@ -13967,6 +13967,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInSam() throws Exception {
|
public void testAllFilesPresentInSam() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class InlineClassInSignature extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+13
@@ -8063,6 +8063,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
public void testAllFilesPresentInSam() throws Exception {
|
public void testAllFilesPresentInSam() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class InlineClassInSignature extends AbstractIrCodegenBoxWasmTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInlineClassInSignature() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user