JVM_IR indy-SAM: function reference to Java interface

This commit is contained in:
Dmitry Petrov
2021-02-18 13:57:40 +03:00
parent 357a7907a3
commit c629ba5a3c
39 changed files with 1005 additions and 135 deletions
@@ -19997,6 +19997,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/covariantOverrideWithPrimitive.kt");
}
@Test
@TestMetadata("enhancedNullabilityMix.kt")
public void testEnhancedNullabilityMix() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/enhancedNullabilityMix.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
@@ -20088,54 +20094,154 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
public class FunctionExprToJavaInterface {
@Test
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionRefToJavaInterface {
@Test
@TestMetadata("adaptedFunRefWithCoercionToUnit.kt")
public void testAdaptedFunRefWithCoercionToUnit() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithCoercionToUnit.kt");
}
@Test
@TestMetadata("adaptedFunRefWithDefaultParameters.kt")
public void testAdaptedFunRefWithDefaultParameters() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithDefaultParameters.kt");
}
@Test
@TestMetadata("adaptedFunRefWithVararg.kt")
public void testAdaptedFunRefWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithVararg.kt");
}
@Test
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("boundExtFun.kt")
public void testBoundExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundExtFun.kt");
}
@Test
@TestMetadata("boundInnerConstructorRef.kt")
public void testBoundInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundInnerConstructorRef.kt");
}
@Test
@TestMetadata("boundLocalExtFun.kt")
public void testBoundLocalExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundLocalExtFun.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundMemberRef.kt");
}
@Test
@TestMetadata("constructorRef.kt")
public void testConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/constructorRef.kt");
}
@Test
@TestMetadata("enhancedNullability.kt")
public void testEnhancedNullability() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/enhancedNullability.kt");
}
@Test
@TestMetadata("innerConstructorRef.kt")
public void testInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/innerConstructorRef.kt");
}
@Test
@TestMetadata("localFunction1.kt")
public void testLocalFunction1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
}
@Test
@TestMetadata("localFunction2.kt")
public void testLocalFunction2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction2.kt");
}
@Test
@TestMetadata("memberRef.kt")
public void testMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/memberRef.kt");
}
@Test
@TestMetadata("nonTrivialReceiver.kt")
public void testNonTrivialReceiver() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/nonTrivialReceiver.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/simple.kt");
}
}
@@ -3944,6 +3944,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("functionRefToJavaInterface.kt")
public void testFunctionRefToJavaInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/invokedynamic/functionRefToJavaInterface.kt");
}
@Test
@TestMetadata("lambdas.kt")
public void testLambdas() throws Exception {
@@ -157,6 +157,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
} else {
return super.visitTypeOperator(expression)
}
reference.transformChildrenVoid()
if (shouldGenerateIndySamConversions) {
@@ -174,7 +174,10 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
override fun visitCall(expression: IrCall): IrExpression {
return when (expression.symbol) {
jvmIndyLambdaMetafactoryIntrinsic -> rewriteIndyLambdaMetafactoryCall(expression)
jvmIndyLambdaMetafactoryIntrinsic -> {
expression.transformChildrenVoid()
rewriteIndyLambdaMetafactoryCall(expression)
}
else -> super.visitCall(expression)
}
}
@@ -267,10 +270,10 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
private fun wrapClosureInDynamicCall(
erasedSamType: IrSimpleType,
samMethod: IrSimpleFunction,
irFunRef: IrFunctionReference
targetRef: IrFunctionReference
): IrCall {
fun fail(message: String): Nothing =
throw AssertionError("$message, irFunRef:\n${irFunRef.dump()}")
throw AssertionError("$message, irFunRef:\n${targetRef.dump()}")
val dynamicCallArguments = ArrayList<IrExpression>()
@@ -281,32 +284,45 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
}.apply {
parent = context.ir.symbols.kotlinJvmInternalInvokeDynamicPackage
val targetFun = targetRef.symbol.owner
val refDispatchReceiver = targetRef.dispatchReceiver
val refExtensionReceiver = targetRef.extensionReceiver
var syntheticParameterIndex = 0
val targetFun = irFunRef.symbol.owner
val targetDispatchReceiverParameter = targetFun.dispatchReceiverParameter
if (targetDispatchReceiverParameter != null) {
addValueParameter("p${syntheticParameterIndex++}", targetDispatchReceiverParameter.type)
val dispatchReceiver = irFunRef.dispatchReceiver
?: fail("Captured dispatch receiver is not provided")
dynamicCallArguments.add(dispatchReceiver)
}
val targetExtensionReceiverParameter = targetFun.extensionReceiverParameter
if (targetExtensionReceiverParameter != null && irFunRef.extensionReceiver != null) {
addValueParameter("p${syntheticParameterIndex++}", targetExtensionReceiverParameter.type)
val extensionReceiver = irFunRef.extensionReceiver!!
dynamicCallArguments.add(extensionReceiver)
var argumentStart = 0
when (targetFun) {
is IrSimpleFunction -> {
if (refDispatchReceiver != null) {
addValueParameter("p${syntheticParameterIndex++}", targetFun.dispatchReceiverParameter!!.type)
dynamicCallArguments.add(refDispatchReceiver)
}
if (refExtensionReceiver != null) {
addValueParameter("p${syntheticParameterIndex++}", targetFun.extensionReceiverParameter!!.type)
dynamicCallArguments.add(refExtensionReceiver)
}
}
is IrConstructor -> {
// At this point, outer class instances in inner class constructors are represented as regular value parameters.
// However, in a function reference to such constructors, bound receiver value is stored as a dispatch receiver.
if (refDispatchReceiver != null) {
addValueParameter("p${syntheticParameterIndex++}", targetFun.valueParameters[0].type)
dynamicCallArguments.add(refDispatchReceiver)
argumentStart++
}
}
else -> {
throw AssertionError("Unexpected function: ${targetFun.render()}")
}
}
val samMethodValueParametersCount = samMethod.valueParameters.size +
if (samMethod.extensionReceiverParameter != null && irFunRef.extensionReceiver == null) 1 else 0
if (samMethod.extensionReceiverParameter != null && refExtensionReceiver == null) 1 else 0
val targetFunValueParametersCount = targetFun.valueParameters.size
for (i in 0 until targetFunValueParametersCount - samMethodValueParametersCount) {
for (i in argumentStart until targetFunValueParametersCount - samMethodValueParametersCount) {
val targetFunValueParameter = targetFun.valueParameters[i]
addValueParameter("p${syntheticParameterIndex++}", targetFunValueParameter.type)
val capturedValueArgument = irFunRef.getValueArgument(i)
?: fail("Captured value argument #$i (${targetFunValueParameter.name}) not provided")
val capturedValueArgument = targetRef.getValueArgument(i)
?: fail("Captured value argument #$i (${targetFunValueParameter.render()}) not provided")
dynamicCallArguments.add(capturedValueArgument)
}
}
@@ -320,7 +336,7 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
"dynamicCallArguments:\n" +
dynamicCallArguments
.withIndex()
.joinToString(separator = "\n ", prefix = "[\n ", postfix = "\n]") { (index, irArg) ->
.joinToString(separator = "\n ", prefix = "[\n ", postfix = "\n]") { (index, irArg) ->
"#$index: ${irArg.dump()}"
}
)
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
import org.jetbrains.kotlin.backend.jvm.lower.findInterfaceImplementation
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
import org.jetbrains.kotlin.descriptors.Modality
@@ -24,12 +25,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.overrides.buildFakeOverrideMember
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addIfNotNull
internal class LambdaMetafactoryArguments(
val samMethod: IrSimpleFunction,
@@ -50,13 +49,14 @@ internal class LambdaMetafactoryArgumentsBuilder(
samType: IrType,
plainLambda: Boolean
): LambdaMetafactoryArguments? {
// Can't use JDK LambdaMetafactory for function references by default (because of 'equals').
// TODO special mode that would generate indy everywhere?
if (reference.origin != IrStatementOrigin.LAMBDA)
return null
val samClass = samType.getClass()
?: throw AssertionError("SAM type is not a class: ${samType.render()}")
// Can't use JDK LambdaMetafactory for function references by default (because of 'equals').
// TODO special mode that would generate indy everywhere?
if (reference.origin != IrStatementOrigin.LAMBDA && !samClass.isFromJava())
return null
val samMethod = samClass.getSingleAbstractMethod()
?: throw AssertionError("SAM class has no single abstract method: ${samClass.render()}")
@@ -68,32 +68,31 @@ internal class LambdaMetafactoryArgumentsBuilder(
if (samClass.requiresDelegationToDefaultImpls())
return null
val target = reference.symbol.owner as? IrSimpleFunction
?: throw AssertionError("Simple function expected: ${reference.symbol.owner.render()}")
val implFun = reference.symbol.owner
// Can't use JDK LambdaMetafactory for annotated lambdas.
// JDK LambdaMetafactory doesn't copy annotations from implementation method to an instance method in a
// corresponding synthetic class, which doesn't look like a binary compatible change.
// TODO relaxed mode?
if (target.annotations.isNotEmpty())
if (implFun.annotations.isNotEmpty())
return null
// Don't use JDK LambdaMetafactory for big arity lambdas.
if (plainLambda) {
var parametersCount = target.valueParameters.size
if (target.extensionReceiverParameter != null) ++parametersCount
var parametersCount = implFun.valueParameters.size
if (implFun.extensionReceiverParameter != null) ++parametersCount
if (parametersCount >= BuiltInFunctionArity.BIG_ARITY)
return null
}
// Can't use indy-based SAM conversion inside inline fun (Ok in inline lambda).
if (target.parents.any { it.isInlineFunction() || it.isCrossinlineLambda() })
if (implFun.parents.any { it.isInlineFunction() || it.isCrossinlineLambda() })
return null
// Do the hard work of matching Kotlin functional interface hierarchy against LambdaMetafactory constraints.
// Briefly: sometimes we have to force boxing on the primitive and inline class values, sometimes we have to keep them unboxed.
// If this results in conflicting requirements, we can't use INVOKEDYNAMIC with LambdaMetafactory for creating a closure.
return getLambdaMetafactoryArgsOrNullInner(reference, samMethod, samType, target)
return getLambdaMetafactoryArgsOrNullInner(reference, samMethod, samType, implFun)
}
private fun IrClass.requiresDelegationToDefaultImpls(): Boolean {
@@ -118,7 +117,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
reference: IrFunctionReference,
samMethod: IrSimpleFunction,
samType: IrType,
implLambda: IrSimpleFunction
implFun: IrFunction
): LambdaMetafactoryArguments? {
val nonFakeOverriddenFuns = samMethod.allOverridden().filterNot { it.isFakeOverride }
val relevantOverriddenFuns = if (samMethod.isFakeOverride) nonFakeOverriddenFuns else nonFakeOverriddenFuns + samMethod
@@ -191,16 +190,23 @@ internal class LambdaMetafactoryArgumentsBuilder(
// We should have bailed out before if we encountered any kind of type adaptation conflict.
// Still, check that we are fine - just in case.
if (signatureAdaptationConstraints.returnType == TypeAdaptationConstraint.CONFLICT ||
signatureAdaptationConstraints.valueParameters.values.any { it == TypeAdaptationConstraint.CONFLICT }
)
if (signatureAdaptationConstraints.hasConflicts())
return null
adaptFakeInstanceMethodSignature(fakeInstanceMethod, signatureAdaptationConstraints)
if (implFun.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) {
adaptLambdaSignature(implFun as IrSimpleFunction, fakeInstanceMethod, signatureAdaptationConstraints)
} else if (
!checkMethodSignatureCompliance(implFun, fakeInstanceMethod, signatureAdaptationConstraints, reference)
) {
return null
}
adaptLambdaSignature(implLambda, fakeInstanceMethod, signatureAdaptationConstraints)
val newReference = remapExtensionLambda(implLambda, reference)
val newReference =
if (implFun.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA)
remapExtensionLambda(implFun as IrSimpleFunction, reference)
else
reference
if (samMethod.isFakeOverride && nonFakeOverriddenFuns.size == 1) {
return LambdaMetafactoryArguments(nonFakeOverriddenFuns.single(), fakeInstanceMethod, newReference, listOf())
@@ -208,32 +214,73 @@ internal class LambdaMetafactoryArgumentsBuilder(
return LambdaMetafactoryArguments(samMethod, fakeInstanceMethod, newReference, nonFakeOverriddenFuns)
}
private fun adaptLambdaSignature(
lambda: IrSimpleFunction,
private fun checkMethodSignatureCompliance(
implFun: IrFunction,
fakeInstanceMethod: IrSimpleFunction,
constraints: SignatureAdaptationConstraints
) {
val lambdaParameters = collectValueParameters(lambda)
constraints: SignatureAdaptationConstraints,
reference: IrFunctionReference
): Boolean {
val implParameters = collectValueParameters(
implFun,
withDispatchReceiver = reference.dispatchReceiver == null,
withExtensionReceiver = reference.extensionReceiver == null
)
val methodParameters = collectValueParameters(fakeInstanceMethod)
if (lambdaParameters.size != methodParameters.size)
if (implParameters.size != methodParameters.size)
throw AssertionError(
"Mismatching lambda and instance method parameters:\n" +
"lambda: ${lambda.render()}\n" +
" (${lambdaParameters.size} parameters)\n" +
"implFun: ${implFun.render()}\n" +
" (${implParameters.size} parameters)\n" +
"instance method: ${fakeInstanceMethod.render()}\n" +
" (${methodParameters.size} parameters)"
)
for ((lambdaParameter, methodParameter) in lambdaParameters.zip(methodParameters)) {
// TODO box inline class parameters only?
val parameterConstraint = constraints.valueParameters[methodParameter]
if (parameterConstraint == TypeAdaptationConstraint.FORCE_BOXING) {
lambdaParameter.type = lambdaParameter.type.makeNullable()
}
for ((implParameter, methodParameter) in implParameters.zip(methodParameters)) {
val constraint = constraints.valueParameters[methodParameter]
if (!checkTypeCompliesWithConstraint(implParameter.type, constraint))
return false
}
if (constraints.returnType == TypeAdaptationConstraint.FORCE_BOXING) {
lambda.returnType = lambda.returnType.makeNullable()
if (!checkTypeCompliesWithConstraint(implFun.returnType, constraints.returnType))
return false
return true
}
private fun checkTypeCompliesWithConstraint(irType: IrType, constraint: TypeAdaptationConstraint?): Boolean =
when (constraint) {
null -> true
TypeAdaptationConstraint.FORCE_BOXING -> irType.isNullable()
TypeAdaptationConstraint.KEEP_UNBOXED -> !irType.isNullable()
TypeAdaptationConstraint.BOX_PRIMITIVE -> irType.isJvmPrimitiveOrNullable()
TypeAdaptationConstraint.CONFLICT -> false
}
private fun adaptLambdaSignature(
implFun: IrSimpleFunction,
fakeInstanceMethod: IrSimpleFunction,
constraints: SignatureAdaptationConstraints
) {
if (implFun.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) {
throw AssertionError("Can't adapt non-lambda function signature: ${implFun.render()}")
}
val implParameters = collectValueParameters(implFun)
val methodParameters = collectValueParameters(fakeInstanceMethod)
if (implParameters.size != methodParameters.size)
throw AssertionError(
"Mismatching lambda and instance method parameters:\n" +
"implFun: ${implFun.render()}\n" +
" (${implParameters.size} parameters)\n" +
"instance method: ${fakeInstanceMethod.render()}\n" +
" (${methodParameters.size} parameters)"
)
for ((implParameter, methodParameter) in implParameters.zip(methodParameters)) {
val parameterConstraint = constraints.valueParameters[methodParameter]
if (parameterConstraint.requiresImplLambdaBoxing()) {
implParameter.type = implParameter.type.makeNullable()
}
}
if (constraints.returnType.requiresImplLambdaBoxing()) {
implFun.returnType = implFun.returnType.makeNullable()
}
}
private fun remapExtensionLambda(lambda: IrSimpleFunction, reference: IrFunctionReference): IrFunctionReference {
@@ -285,25 +332,36 @@ internal class LambdaMetafactoryArgumentsBuilder(
"Unexpected value parameter: ${valueParameter.render()}; fakeInstanceMethod:\n" +
fakeInstanceMethod.dump()
)
if (constraint == TypeAdaptationConstraint.FORCE_BOXING) {
if (constraint.requiresInstanceMethodBoxing()) {
valueParameter.type = valueParameter.type.makeNullable()
}
}
if (constraints.returnType == TypeAdaptationConstraint.FORCE_BOXING) {
if (constraints.returnType.requiresInstanceMethodBoxing()) {
fakeInstanceMethod.returnType = fakeInstanceMethod.returnType.makeNullable()
}
}
private enum class TypeAdaptationConstraint {
FORCE_BOXING,
BOX_PRIMITIVE,
KEEP_UNBOXED,
CONFLICT
}
private fun TypeAdaptationConstraint?.requiresInstanceMethodBoxing() =
this == TypeAdaptationConstraint.FORCE_BOXING || this == TypeAdaptationConstraint.BOX_PRIMITIVE
private fun TypeAdaptationConstraint?.requiresImplLambdaBoxing() =
this == TypeAdaptationConstraint.FORCE_BOXING
private class SignatureAdaptationConstraints(
val valueParameters: Map<IrValueParameter, TypeAdaptationConstraint>,
val returnType: TypeAdaptationConstraint?
)
) {
fun hasConflicts() =
returnType == TypeAdaptationConstraint.CONFLICT ||
TypeAdaptationConstraint.CONFLICT in valueParameters.values
}
private fun computeSignatureAdaptationConstraints(
adapteeFun: IrSimpleFunction,
@@ -353,10 +411,13 @@ internal class LambdaMetafactoryArgumentsBuilder(
// All Kotlin types mapped to JVM primitive are final,
// and their supertypes are trivially mapped reference types.
if (adapteeType.isJvmPrimitiveType()) {
return if (expectedType.isJvmPrimitiveType())
return if (
expectedType.isJvmPrimitiveType() &&
!expectedType.hasAnnotation(context.ir.symbols.enhancedNullabilityAnnotationFqName)
)
TypeAdaptationConstraint.KEEP_UNBOXED
else
TypeAdaptationConstraint.FORCE_BOXING
TypeAdaptationConstraint.BOX_PRIMITIVE
}
// ** Inline classes **
@@ -459,13 +520,29 @@ internal class LambdaMetafactoryArgumentsBuilder(
private fun IrType.isJvmPrimitiveType() =
isBoolean() || isChar() || isByte() || isShort() || isInt() || isLong() || isFloat() || isDouble()
}
fun collectValueParameters(irFun: IrFunction): List<IrValueParameter> {
if (irFun.extensionReceiverParameter == null)
return irFun.valueParameters
return ArrayList<IrValueParameter>().apply {
add(irFun.extensionReceiverParameter!!)
addAll(irFun.valueParameters)
private fun IrType.isJvmPrimitiveOrNullable() =
isBooleanOrNullable() || isCharOrNullable() ||
isByteOrNullable() || isShortOrNullable() || isIntOrNullable() || isLongOrNullable() ||
isFloatOrNullable() || isDoubleOrNullable()
fun collectValueParameters(
irFun: IrFunction,
withDispatchReceiver: Boolean = false,
withExtensionReceiver: Boolean = true
): List<IrValueParameter> {
if ((!withDispatchReceiver || irFun.dispatchReceiverParameter == null) &&
(!withExtensionReceiver || irFun.extensionReceiverParameter == null)
)
return irFun.valueParameters
return ArrayList<IrValueParameter>().apply {
if (withDispatchReceiver) {
addIfNotNull(irFun.dispatchReceiverParameter)
}
if (withExtensionReceiver) {
addIfNotNull(irFun.extensionReceiverParameter)
}
addAll(irFun.valueParameters)
}
}
}
}
@@ -109,17 +109,25 @@ fun IrType.isMarkedNullable() = (this as? IrSimpleType)?.hasQuestionMark ?: fals
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
fun IrType.isBoolean(): Boolean = isNotNullClassType(IdSignatureValues._boolean)
fun IrType.isBooleanOrNullable(): Boolean = isClassType(IdSignatureValues._boolean)
fun IrType.isChar(): Boolean = isNotNullClassType(IdSignatureValues._char)
fun IrType.isCharOrNullable(): Boolean = isClassType(IdSignatureValues._char)
fun IrType.isByte(): Boolean = isNotNullClassType(IdSignatureValues._byte)
fun IrType.isByteOrNullable(): Boolean = isClassType(IdSignatureValues._byte)
fun IrType.isShort(): Boolean = isNotNullClassType(IdSignatureValues._short)
fun IrType.isShortOrNullable(): Boolean = isClassType(IdSignatureValues._short)
fun IrType.isInt(): Boolean = isNotNullClassType(IdSignatureValues._int)
fun IrType.isIntOrNullable(): Boolean = isClassType(IdSignatureValues._int)
fun IrType.isLong(): Boolean = isNotNullClassType(IdSignatureValues._long)
fun IrType.isLongOrNullable(): Boolean = isClassType(IdSignatureValues._long)
fun IrType.isUByte(): Boolean = isNotNullClassType(IdSignatureValues.uByte)
fun IrType.isUShort(): Boolean = isNotNullClassType(IdSignatureValues.uShort)
fun IrType.isUInt(): Boolean = isNotNullClassType(IdSignatureValues.uInt)
fun IrType.isULong(): Boolean = isNotNullClassType(IdSignatureValues.uLong)
fun IrType.isFloat(): Boolean = isNotNullClassType(IdSignatureValues._float)
fun IrType.isFloatOrNullable(): Boolean = isClassType(IdSignatureValues._float)
fun IrType.isDouble(): Boolean = isNotNullClassType(IdSignatureValues._double)
fun IrType.isDoubleOrNullable(): Boolean = isClassType(IdSignatureValues._double)
fun IrType.isNumber(): Boolean = isNotNullClassType(IdSignatureValues.number)
fun IrType.isComparable(): Boolean = isNotNullClassType(IdSignatureValues.comparable)
@@ -0,0 +1,29 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: enhancedNullability.kt
fun interface IGetInt {
fun get(x: Int): Int
}
// fun interface IGetIntMix0 : IGetInt, Sam
// ^ Error: [FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS] Fun interfaces must have exactly one abstract method
fun interface IGetIntMix1 : IGetInt, Sam {
override fun get(x: Int): Int
}
fun box(): String {
val t1 = IGetIntMix1 { it: Int -> it * 2 }.get(21)
if (t1 != 42)
return "Failed: t1=$t1"
return "OK"
}
// FILE: Sam.java
import org.jetbrains.annotations.*;
public interface Sam {
@NotNull Integer get(@NotNull Integer arg);
}
@@ -0,0 +1,20 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: adaptedFunRefWithCoercionToUnit.kt
var ok = "Failed"
fun test(s: String): Int {
ok = s
return 42
}
fun box(): String {
Sam(::test).foo("OK")
return ok
}
// FILE: Sam.java
public interface Sam {
void foo(String s);
}
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: adaptedFunRefWithDefaultParameters.kt
var ok = "Failed"
fun test(s1: String, s2: String = "K") {
ok = s1 + s2
}
fun box(): String {
Sam(::test).foo("O")
return ok
}
// FILE: Sam.java
public interface Sam {
void foo(String s);
}
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: adaptedFunRefWithVararg.kt
var ok = "Failed"
fun test(vararg ss: String) {
ok = ss[0]
}
fun box(): String {
Sam(::test).foo("OK")
return ok
}
// FILE: Sam.java
public interface Sam {
void foo(String s);
}
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: boundExtFun.kt
fun String.k(s: String) = this + s + "K"
fun box() = Sam("O"::k).get("")
// NB simply '::k' is a compilation error
// FILE: Sam.java
public interface Sam {
String get(String s);
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: boundInnerConstructorRef.kt
class Outer(val s1: String) {
inner class Inner(val s2: String) {
fun t() = s1 + s2
}
}
fun box() = Sam(Outer("O")::Inner).get("K").t()
// FILE: Sam.java
public interface Sam {
Outer.Inner get(String s);
}
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: boundLocalExtFun.kt
fun box(): String {
fun String.k(s: String) = this + s + "K"
return Sam("O"::k).get("")
// NB simply '::k' is a compilation error
}
// FILE: Sam.java
public interface Sam {
String get(String s);
}
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: boundMemberRef.kt
class C(val t: String) {
fun test() = t
}
fun box() = Sam(C("OK")::test).get()
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,12 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: constructorRef.kt
class C(val t: String)
fun box() = Sam(::C).get("OK").t
// FILE: Sam.java
public interface Sam {
C get(String s);
}
@@ -0,0 +1,20 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: enhancedNullability.kt
fun mul2(x: Int) = x * 2
fun box(): String {
val t = Sam(::mul2).get(21)
if (t != 42)
return "Failed: t=$t"
return "OK"
}
// FILE: Sam.java
import org.jetbrains.annotations.*;
public interface Sam {
@NotNull Integer get(@NotNull Integer arg);
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: innerConstructorRef.kt
class Outer(val s1: String) {
inner class Inner(val s2: String) {
fun t() = s1 + s2
}
}
fun box() = Sam(Outer::Inner).get(Outer("O"), "K").t()
// FILE: Sam.java
public interface Sam {
Outer.Inner get(Outer outer, String s);
}
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: localFunction1.kt
fun box(): String {
fun ok() = "OK"
return Sam(::ok).get()
}
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: localFunction2.kt
fun box(): String {
val t = "O"
fun ok() = t + "K"
return Sam(::ok).get()
}
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: memberRef.kt
class C(val t: String) {
fun test() = t
}
fun box() = Sam(C::test).get(C("OK"))
// FILE: Sam.java
public interface Sam {
String get(C c);
}
@@ -0,0 +1,23 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// WITH_RUNTIME
// FILE: JavaRunner.java
public class JavaRunner {
public static void runTwice(Runnable runnable) {
runnable.run();
runnable.run();
}
}
// FILE: nonTrivialReceiver.kt
class A() {
fun f() {}
}
fun box(): String {
var x = 0
JavaRunner.runTwice({ x++; A() }()::f)
if (x != 1) return "Fail"
return "OK"
}
@@ -0,0 +1,12 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: simple.kt
fun ok() = "OK"
fun box() = Sam(::ok).get()
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// WITH_RUNTIME
// FULL_JDK
fun hello() { println("Hello, world!") }
val test = Runnable(::hello)
// JVM_TEMPLATES:
// 1 public final class FunctionRefToJavaInterfaceKt
// 1 final synthetic class FunctionRefToJavaInterfaceKt\$sam\$java_lang_Runnable\$0
// 1 final synthetic class FunctionRefToJavaInterfaceKt\$test\$1
// JVM_IR_TEMPLATES:
// 1 INVOKEDYNAMIC
// 1 class FunctionRefToJavaInterfaceKt
@@ -19997,6 +19997,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/invokedynamic/sam/covariantOverrideWithPrimitive.kt");
}
@Test
@TestMetadata("enhancedNullabilityMix.kt")
public void testEnhancedNullabilityMix() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/enhancedNullabilityMix.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
@@ -20088,54 +20094,154 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
public class FunctionExprToJavaInterface {
@Test
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionRefToJavaInterface {
@Test
@TestMetadata("adaptedFunRefWithCoercionToUnit.kt")
public void testAdaptedFunRefWithCoercionToUnit() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithCoercionToUnit.kt");
}
@Test
@TestMetadata("adaptedFunRefWithDefaultParameters.kt")
public void testAdaptedFunRefWithDefaultParameters() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithDefaultParameters.kt");
}
@Test
@TestMetadata("adaptedFunRefWithVararg.kt")
public void testAdaptedFunRefWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithVararg.kt");
}
@Test
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("boundExtFun.kt")
public void testBoundExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundExtFun.kt");
}
@Test
@TestMetadata("boundInnerConstructorRef.kt")
public void testBoundInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundInnerConstructorRef.kt");
}
@Test
@TestMetadata("boundLocalExtFun.kt")
public void testBoundLocalExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundLocalExtFun.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundMemberRef.kt");
}
@Test
@TestMetadata("constructorRef.kt")
public void testConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/constructorRef.kt");
}
@Test
@TestMetadata("enhancedNullability.kt")
public void testEnhancedNullability() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/enhancedNullability.kt");
}
@Test
@TestMetadata("innerConstructorRef.kt")
public void testInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/innerConstructorRef.kt");
}
@Test
@TestMetadata("localFunction1.kt")
public void testLocalFunction1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
}
@Test
@TestMetadata("localFunction2.kt")
public void testLocalFunction2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction2.kt");
}
@Test
@TestMetadata("memberRef.kt")
public void testMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/memberRef.kt");
}
@Test
@TestMetadata("nonTrivialReceiver.kt")
public void testNonTrivialReceiver() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/nonTrivialReceiver.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/simple.kt");
}
}
@@ -3812,6 +3812,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("functionRefToJavaInterface.kt")
public void testFunctionRefToJavaInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/invokedynamic/functionRefToJavaInterface.kt");
}
@Test
@TestMetadata("lambdas.kt")
public void testLambdas() throws Exception {
@@ -19997,6 +19997,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/covariantOverrideWithPrimitive.kt");
}
@Test
@TestMetadata("enhancedNullabilityMix.kt")
public void testEnhancedNullabilityMix() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/enhancedNullabilityMix.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
@@ -20088,54 +20094,154 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
public class FunctionExprToJavaInterface {
@Test
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
public class FunctionRefToJavaInterface {
@Test
@TestMetadata("adaptedFunRefWithCoercionToUnit.kt")
public void testAdaptedFunRefWithCoercionToUnit() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithCoercionToUnit.kt");
}
@Test
@TestMetadata("adaptedFunRefWithDefaultParameters.kt")
public void testAdaptedFunRefWithDefaultParameters() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithDefaultParameters.kt");
}
@Test
@TestMetadata("adaptedFunRefWithVararg.kt")
public void testAdaptedFunRefWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithVararg.kt");
}
@Test
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("boundExtFun.kt")
public void testBoundExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundExtFun.kt");
}
@Test
@TestMetadata("boundInnerConstructorRef.kt")
public void testBoundInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundInnerConstructorRef.kt");
}
@Test
@TestMetadata("boundLocalExtFun.kt")
public void testBoundLocalExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundLocalExtFun.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundMemberRef.kt");
}
@Test
@TestMetadata("constructorRef.kt")
public void testConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/constructorRef.kt");
}
@Test
@TestMetadata("enhancedNullability.kt")
public void testEnhancedNullability() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/enhancedNullability.kt");
}
@Test
@TestMetadata("innerConstructorRef.kt")
public void testInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/innerConstructorRef.kt");
}
@Test
@TestMetadata("localFunction1.kt")
public void testLocalFunction1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
}
@Test
@TestMetadata("localFunction2.kt")
public void testLocalFunction2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction2.kt");
}
@Test
@TestMetadata("memberRef.kt")
public void testMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/memberRef.kt");
}
@Test
@TestMetadata("nonTrivialReceiver.kt")
public void testNonTrivialReceiver() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/nonTrivialReceiver.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/simple.kt");
}
}
@@ -3944,6 +3944,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("functionRefToJavaInterface.kt")
public void testFunctionRefToJavaInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/invokedynamic/functionRefToJavaInterface.kt");
}
@Test
@TestMetadata("lambdas.kt")
public void testLambdas() throws Exception {
@@ -16771,6 +16771,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/covariantOverrideWithPrimitive.kt");
}
@TestMetadata("enhancedNullabilityMix.kt")
public void testEnhancedNullabilityMix() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/enhancedNullabilityMix.kt");
}
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterface.kt");
@@ -16841,51 +16846,139 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt");
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument extends AbstractLightAnalysisModeTest {
public static class FunctionExprToJavaInterface extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturedSamArgument.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/capturingLambda.kt");
}
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda1.kt");
}
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/extensionLambda2.kt");
}
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam1.kt");
}
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/genericSam2.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface/simple.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionRefToJavaInterface extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@TestMetadata("adaptedFunRefWithCoercionToUnit.kt")
public void testAdaptedFunRefWithCoercionToUnit() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithCoercionToUnit.kt");
}
@TestMetadata("adaptedFunRefWithDefaultParameters.kt")
public void testAdaptedFunRefWithDefaultParameters() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithDefaultParameters.kt");
}
@TestMetadata("adaptedFunRefWithVararg.kt")
public void testAdaptedFunRefWithVararg() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/adaptedFunRefWithVararg.kt");
}
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("boundExtFun.kt")
public void testBoundExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundExtFun.kt");
}
@TestMetadata("boundInnerConstructorRef.kt")
public void testBoundInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundInnerConstructorRef.kt");
}
@TestMetadata("boundLocalExtFun.kt")
public void testBoundLocalExtFun() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundLocalExtFun.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/boundMemberRef.kt");
}
@TestMetadata("constructorRef.kt")
public void testConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/constructorRef.kt");
}
@TestMetadata("enhancedNullability.kt")
public void testEnhancedNullability() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/enhancedNullability.kt");
}
@TestMetadata("innerConstructorRef.kt")
public void testInnerConstructorRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/innerConstructorRef.kt");
}
@TestMetadata("localFunction1.kt")
public void testLocalFunction1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
}
@TestMetadata("localFunction2.kt")
public void testLocalFunction2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction2.kt");
}
@TestMetadata("memberRef.kt")
public void testMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/memberRef.kt");
}
@TestMetadata("nonTrivialReceiver.kt")
public void testNonTrivialReceiver() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/nonTrivialReceiver.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/simple.kt");
}
}
@@ -14626,16 +14626,29 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
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/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument extends AbstractIrJsCodegenBoxES6Test {
public static class FunctionExprToJavaInterface extends AbstractIrJsCodegenBoxES6Test {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
}
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionRefToJavaInterface extends AbstractIrJsCodegenBoxES6Test {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
}
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
}
@@ -14111,16 +14111,29 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
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/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument extends AbstractIrJsCodegenBoxTest {
public static class FunctionExprToJavaInterface extends AbstractIrJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionRefToJavaInterface extends AbstractIrJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
}
@@ -14176,16 +14176,29 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
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/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument extends AbstractJsCodegenBoxTest {
public static class FunctionExprToJavaInterface extends AbstractJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionRefToJavaInterface extends AbstractJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
}
@@ -8212,16 +8212,29 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
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/functionExpressionArgument")
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument extends AbstractIrCodegenBoxWasmTest {
public static class FunctionExprToJavaInterface extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInFunctionExpressionArgument() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
public void testAllFilesPresentInFunctionExprToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionExprToJavaInterface"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionRefToJavaInterface extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
}