JVM_IR indy-SAM on functional expression

This commit is contained in:
Dmitry Petrov
2021-02-17 13:44:33 +03:00
parent 134fda8bad
commit 6d019d9544
29 changed files with 634 additions and 8 deletions
@@ -20035,6 +20035,58 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
@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);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@@ -13,6 +13,10 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.lower.indy.LambdaMetafactoryArguments
import org.jetbrains.kotlin.backend.jvm.lower.indy.LambdaMetafactoryArgumentsBuilder
import org.jetbrains.kotlin.backend.jvm.lower.indy.SamDelegatingLambdaBlock
import org.jetbrains.kotlin.backend.jvm.lower.indy.SamDelegatingLambdaBuilder
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
import org.jetbrains.kotlin.config.JvmClosureGenerationScheme
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -142,6 +146,14 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
} else if (invokable is IrBlock && invokable.origin.isLambda && invokable.statements.last() is IrFunctionReference) {
invokable.statements.dropLast(1).forEach { it.transform(this, null) }
invokable.statements.last() as IrFunctionReference
} else if (shouldGenerateIndySamConversions && canGenerateIndySamConversionOnFunctionalExpression(samSuperType, invokable)) {
val lambdaBlock = SamDelegatingLambdaBuilder(context)
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol)
val lambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArgumentsOrNull(lambdaBlock.ref, samSuperType, false)
?: return super.visitTypeOperator(expression)
invokable.transformChildrenVoid()
return wrapSamDelegatingLambdaWithIndySamConversion(samSuperType, lambdaBlock, lambdaMetafactoryArguments)
} else {
return super.visitTypeOperator(expression)
}
@@ -159,18 +171,36 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
return FunctionReferenceBuilder(reference, samSuperType).build()
}
private fun canGenerateIndySamConversionOnFunctionalExpression(samSuperType: IrType, expression: IrExpression): Boolean {
val samClass = samSuperType.classOrNull
?: throw AssertionError("Class type expected: ${samSuperType.render()}")
if (!samClass.owner.isFromJava())
return false
if (expression is IrBlock && expression.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
return false
return true
}
private fun wrapSamDelegatingLambdaWithIndySamConversion(
samSuperType: IrType,
lambdaBlock: SamDelegatingLambdaBlock,
lambdaMetafactoryArguments: LambdaMetafactoryArguments
): IrExpression {
val indySamConversion = wrapWithIndySamConversion(samSuperType, lambdaMetafactoryArguments)
lambdaBlock.replaceRefWith(indySamConversion)
return lambdaBlock.block
}
private fun wrapSamConversionArgumentWithIndySamConversion(
expression: IrTypeOperatorCall,
lambdaMetafactoryArguments: LambdaMetafactoryArguments
): IrExpression {
val samType = expression.typeOperand
return when (val argument = expression.argument) {
is IrFunctionReference -> {
is IrFunctionReference ->
wrapWithIndySamConversion(samType, lambdaMetafactoryArguments)
}
is IrBlock -> {
is IrBlock ->
wrapFunctionReferenceInsideBlockWithIndySamConversion(samType, lambdaMetafactoryArguments, argument)
}
else -> throw AssertionError("Block or function reference expected: ${expression.render()}")
}
}
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.lower
package org.jetbrains.kotlin.backend.jvm.lower.indy
import org.jetbrains.kotlin.backend.common.ir.allOverridden
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
@@ -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.lower.findInterfaceImplementation
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
@@ -30,14 +31,14 @@ import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
class LambdaMetafactoryArguments(
internal class LambdaMetafactoryArguments(
val samMethod: IrSimpleFunction,
val fakeInstanceMethod: IrSimpleFunction,
val implMethodReference: IrFunctionReference,
val extraOverriddenMethods: List<IrSimpleFunction>
)
class LambdaMetafactoryArgumentsBuilder(
internal class LambdaMetafactoryArgumentsBuilder(
private val context: JvmBackendContext,
private val crossinlineLambdas: Set<IrSimpleFunction>
) {
@@ -0,0 +1,234 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.lower.indy
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.JvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
internal sealed class SamDelegatingLambdaBlock {
abstract val block: IrContainerExpression
abstract val ref: IrFunctionReference
abstract fun replaceRefWith(expression: IrExpression)
}
internal class RegularDelegatingLambdaBlock(
override val block: IrContainerExpression,
override val ref: IrFunctionReference
) : SamDelegatingLambdaBlock() {
override fun replaceRefWith(expression: IrExpression) {
block.statements[block.statements.size - 1] = expression
block.type = expression.type
}
}
internal class NullableDelegatingLambdaBlock(
override val block: IrContainerExpression,
override val ref: IrFunctionReference,
private val ifExpr: IrExpression,
private val ifNotNullBlock: IrContainerExpression
) : SamDelegatingLambdaBlock() {
override fun replaceRefWith(expression: IrExpression) {
ifNotNullBlock.statements[ifNotNullBlock.statements.size - 1] = expression
ifNotNullBlock.type = expression.type
ifExpr.type = expression.type
block.type = expression.type
}
}
internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendContext) {
fun build(expression: IrExpression, superType: IrType, scopeSymbol: IrSymbol): SamDelegatingLambdaBlock {
return if (superType.isNullable() && expression.type.isNullable())
buildNullableDelegatingLambda(expression, superType, scopeSymbol)
else
buildRegularDelegatingLambda(expression, superType, scopeSymbol)
}
private fun buildRegularDelegatingLambda(
expression: IrExpression,
superType: IrType,
scopeSymbol: IrSymbol
): SamDelegatingLambdaBlock {
lateinit var ref: IrFunctionReference
val block = jvmContext.createJvmIrBuilder(scopeSymbol, expression.startOffset, expression.endOffset).run {
// {
// val tmp = <expression>
// fun `<anonymous>`(p1: T1, ..., pN: TN): R =
// tmp.invoke(p1, ..., pN)
// ::`<anonymous>`
// }
irBlock(origin = IrStatementOrigin.LAMBDA) {
val tmp = irTemporary(expression)
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
.also { +it }
ref = createDelegatingLambdaReference(expression, lambda)
.also { +it }
}
}
block.type = expression.type
return RegularDelegatingLambdaBlock(block, ref)
}
private fun buildNullableDelegatingLambda(
expression: IrExpression,
superType: IrType,
scopeSymbol: IrSymbol
): SamDelegatingLambdaBlock {
lateinit var ref: IrFunctionReference
lateinit var ifExpr: IrExpression
lateinit var ifNotNullBlock: IrContainerExpression
val block = jvmContext.createJvmIrBuilder(scopeSymbol, expression.startOffset, expression.endOffset).run {
// {
// val tmp = <expression>
// if (tmp == null)
// null
// else {
// fun `<anonymous>`(p1: T1, ..., pN: TN): R =
// tmp.invoke(p1, ..., pN)
// ::`<anonymous>`
// }
// }
irBlock(origin = IrStatementOrigin.LAMBDA) {
val tmp = irTemporary(expression)
ifNotNullBlock = irBlock {
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
.also { +it }
ref = createDelegatingLambdaReference(expression, lambda)
.also { +it }
}
ifExpr = irIfNull(expression.type, irGet(tmp), irNull(), ifNotNullBlock)
.also { +it }
}
}
block.type = expression.type
return NullableDelegatingLambdaBlock(block, ref, ifExpr, ifNotNullBlock)
}
private fun createDelegatingLambda(
scopeSymbol: IrSymbol,
expression: IrExpression,
superType: IrType,
tmp: IrVariable
): IrSimpleFunction {
val superMethod = superType.getSingleAbstractMethod()
?: throw AssertionError("SAM type expected: ${superType.render()}")
val effectiveValueParametersCount = superMethod.valueParameters.size +
if (superMethod.extensionReceiverParameter == null) 0 else 1
val invocableFunctionClass =
if (superMethod.isSuspend)
jvmContext.ir.symbols.suspendFunctionN(effectiveValueParametersCount).owner
else
jvmContext.ir.symbols.functionN(effectiveValueParametersCount).owner
val invokeFunction = invocableFunctionClass.functions.single { it.name == OperatorNameConventions.INVOKE }
val typeSubstitutor = createTypeSubstitutor(superType)
return jvmContext.irFactory.buildFun {
name = Name.special("<anonymous>")
returnType = typeSubstitutor.substitute(superMethod.returnType)
visibility = DescriptorVisibilities.LOCAL
modality = Modality.FINAL
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
isSuspend = superMethod.isSuspend
}.also { lambda ->
lambda.dispatchReceiverParameter = null
lambda.extensionReceiverParameter = null
lambda.valueParameters = createLambdaValueParameters(superMethod, lambda, typeSubstitutor)
lambda.body = jvmContext.createJvmIrBuilder(lambda.symbol, expression.startOffset, expression.endOffset)
.irBlockBody {
+irReturn(
irCall(invokeFunction).also { invokeCall ->
invokeCall.dispatchReceiver = irGet(tmp)
var parameterIndex = 0
invokeFunction.extensionReceiverParameter?.let {
invokeCall.extensionReceiver = irGet(lambda.valueParameters[parameterIndex++])
}
for (argumentIndex in invokeFunction.valueParameters.indices) {
invokeCall.putValueArgument(argumentIndex, irGet(lambda.valueParameters[parameterIndex++]))
}
}
)
}
lambda.parent = scopeSymbol.owner as IrDeclarationParent
}
}
private fun createLambdaValueParameters(
superMethod: IrSimpleFunction,
lambda: IrSimpleFunction,
typeSubstitutor: IrTypeSubstitutor
): List<IrValueParameter> {
val lambdaParameters = ArrayList<IrValueParameter>()
var index = 0
superMethod.extensionReceiverParameter?.let { superExtensionReceiver ->
lambdaParameters.add(superExtensionReceiver.copySubstituted(lambda, typeSubstitutor, index++, Name.identifier("\$receiver")))
}
superMethod.valueParameters.mapTo(lambdaParameters) { superValueParameter ->
superValueParameter.copySubstituted(lambda, typeSubstitutor, index++)
}
return lambdaParameters
}
private fun IrValueParameter.copySubstituted(
function: IrSimpleFunction,
substitutor: IrTypeSubstitutor,
newIndex: Int,
newName: Name = name
) =
buildValueParameter(function) {
name = newName
index = newIndex
type = substitutor.substitute(this@copySubstituted.type)
}
private fun JvmIrBuilder.createDelegatingLambdaReference(expression: IrExpression, lambda: IrSimpleFunction): IrFunctionReference {
return IrFunctionReferenceImpl(
startOffset, endOffset,
expression.type,
lambda.symbol,
typeArgumentsCount = 0,
valueArgumentsCount = lambda.valueParameters.size,
reflectionTarget = null,
origin = IrStatementOrigin.LAMBDA
)
}
private fun createTypeSubstitutor(irType: IrType): IrTypeSubstitutor {
if (irType !is IrSimpleType)
throw AssertionError("Simple type expected: ${irType.render()}")
val irClassSymbol = irType.classOrNull
?: throw AssertionError("Class type expected: ${irType.render()}")
return IrTypeSubstitutor(
irClassSymbol.owner.typeParameters.map { it.symbol },
irType.arguments,
jvmContext.irBuiltIns
)
}
}
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM
// SAM_CONVERSIONS: CLASS
// WITH_RUNTIME
// FILE: Test.java
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: capturedSamArgument.kt
fun box(): String {
var lambda = { "OK" }
val sam = Sam(lambda)
lambda = { "Failed" }
return sam.get()
}
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: capturingLambda.kt
fun box(): String {
val co = 'O'
val lambda = { co.toString() + "K" }
return Sam(lambda).get()
}
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: extensionLambda1.kt
fun samExtLambda(ext: String.() -> String) = Sam(ext)
fun box(): String {
val oChar = 'O'
return samExtLambda { oChar.toString() + this }.get("K")
}
// FILE: Sam.java
public interface Sam {
String get(String s);
}
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: extensionLambda2.kt
fun samExtLambda(ext: String.(String) -> String) = Sam(ext)
fun box(): String {
val oChar = 'O'
return samExtLambda { oChar.toString() + this + it }.get("", "K")
}
// FILE: Sam.java
public interface Sam {
String get(String s1, String s2);
}
@@ -0,0 +1,11 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: genericSam1.kt
fun box(): String = Sam<String, String> { "O" + it }.get("K")
// FILE: Sam.java
public interface Sam<T, R> {
R get(T x);
}
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: genericSam2.kt
fun <FT, FR> test(lambda: (FT) -> FR) = Sam(lambda)
fun box(): String = test<String, String> { "O" + it }.get("K")
// FILE: Sam.java
public interface Sam<T, R> {
R get(T x);
}
@@ -0,0 +1,12 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: simple.kt
val lambda = { "OK" }
fun box() = Sam(lambda).get()
// FILE: Sam.java
public interface Sam {
String get();
}
@@ -4,6 +4,7 @@
// IGNORE_BACKEND: JS_IR_ES6
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// SAM_CONVERSIONS: CLASS
fun box(): String {
val f = { }
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: MyRunnable.java
public interface MyRunnable {
public void run();
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: Foo.kt
package foo
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: Foo.kt
@file:JvmName("testXX")
package test
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: Foo.kt
@file:JvmMultifileClass
@file:JvmName("testX")
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: Foo.kt
@file:JvmMultifileClass
@file:JvmName("testX")
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: kt22906_1.kt
package test
+1
View File
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// SAM_CONVERSIONS: CLASS
// FILE: kt22906_1.kt
package test
@@ -2,6 +2,7 @@
// WITH_RUNTIME
// FULL_JDK
// SKIP_JDK6
// SAM_CONVERSIONS: CLASS
// FILE: test.kt
// Test that SAM wrappers with type parameters are cached properly.
class A {
@@ -26,7 +26,7 @@ fun test() {
// JVM_IR_TEMPLATES
// @TestKt.class
// 1 NEW
// 0 NEW
// 1 IFNONNULL
// 0 IFNULL
// 2 ACONST_NULL
@@ -20035,6 +20035,58 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
@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);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@@ -20035,6 +20035,58 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestDataPath("$PROJECT_ROOT")
public class FunctionExpressionArgument {
@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);
}
@Test
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
}
@Test
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
}
@Test
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
}
@Test
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
}
@Test
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@@ -16793,6 +16793,54 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt");
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument 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);
}
@TestMetadata("capturedSamArgument.kt")
public void testCapturedSamArgument() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturedSamArgument.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/capturingLambda.kt");
}
@TestMetadata("extensionLambda1.kt")
public void testExtensionLambda1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda1.kt");
}
@TestMetadata("extensionLambda2.kt")
public void testExtensionLambda2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/extensionLambda2.kt");
}
@TestMetadata("genericSam1.kt")
public void testGenericSam1() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam1.kt");
}
@TestMetadata("genericSam2.kt")
public void testGenericSam2() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/genericSam2.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionExpressionArgument/simple.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -14578,6 +14578,19 @@ 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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument 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);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -14063,6 +14063,19 @@ 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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument 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);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -14128,6 +14128,19 @@ 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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument 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);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8164,6 +8164,19 @@ 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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpressionArgument 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);
}
}
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)