diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index ae7ffae8b83..92239187b51 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -208,11 +208,21 @@ class GenerationState private constructor( else JvmStringConcat.INLINE val samConversionsScheme = run { - val fromConfig = configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS) ?: JvmSamConversions.DEFAULT + val fromConfig = configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS) + ?: JvmClosureGenerationScheme.DEFAULT if (target >= fromConfig.minJvmTarget) fromConfig else - JvmSamConversions.DEFAULT + JvmClosureGenerationScheme.DEFAULT + } + + val lambdasScheme = run { + val fromConfig = configuration.get(JVMConfigurationKeys.LAMBDAS) + ?: JvmClosureGenerationScheme.DEFAULT + if (target >= fromConfig.minJvmTarget) + fromConfig + else + JvmClosureGenerationScheme.DEFAULT } val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 4cb5d5804ec..5d3f559f4c3 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -355,10 +355,10 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { @Argument( value = "-Xstring-concat", valueDescription = "{indy-with-constants|indy|inline}", - description = """Switch a way in which string concatenation is performed. --Xstring-concat=indy-with-constants Performs string concatenation via `invokedynamic` 'makeConcatWithConstants'. Works only with `-jvm-target 9` or greater --Xstring-concat=indy Performs string concatenation via `invokedynamic` 'makeConcat'. Works only with `-jvm-target 9` or greater --Xstring-concat=inline Performs string concatenation via `StringBuilder`""" + description = """Select code generation scheme for string concatenation. +-Xstring-concat=indy-with-constants Concatenate strings using `invokedynamic` ` makeConcatWithConstants`. Requires `-jvm-target 9` or greater. +-Xstring-concat=indy Concatenate strings using `invokedynamic` `makeConcat`. Requires `-jvm-target 9` or greater. +-Xstring-concat=inline Concatenate strings using `StringBuilder`""" ) var stringConcat: String? by NullableStringFreezableVar(JvmStringConcat.INLINE.description) @@ -366,10 +366,20 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { value = "-Xsam-conversions", valueDescription = "{class|indy}", description = """Select code generation scheme for SAM conversions. --Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 8` or greater. +-Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater. -Xsam-conversions=class Generate SAM conversions as explicit classes""" ) - var samConversions: String? by NullableStringFreezableVar(JvmSamConversions.CLASS.description) + var samConversions: String? by NullableStringFreezableVar(null) + + @Argument( + value = "-Xlambdas", + valueDescription = "{class|indy}", + description = """Select code generation scheme for lambdas. +-Xlambdas=indy Generate lambdas using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater. + Lambda objects created using `LambdaMetafactory.metafactory` will have different `toString()`. +-Xlambdas=class Generate lambdas as explicit classes""" + ) + var lambdas: String? by NullableStringFreezableVar(null) @Argument( value = "-Xklib", diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index f48a1ed5811..c7aad2ada45 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -66,27 +66,37 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu } } - if (arguments.samConversions != null) { - val samConversions = JvmSamConversions.fromString(arguments.samConversions) - if (samConversions != null) { - put(JVMConfigurationKeys.SAM_CONVERSIONS, samConversions) - if (jvmTarget < samConversions.minJvmTarget) { + handleClosureGenerationSchemeArgument("-Xsam-conversions", arguments.samConversions, JVMConfigurationKeys.SAM_CONVERSIONS, jvmTarget) + handleClosureGenerationSchemeArgument("-Xlambdas", arguments.lambdas, JVMConfigurationKeys.LAMBDAS, jvmTarget) + + addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList()) +} + +private fun CompilerConfiguration.handleClosureGenerationSchemeArgument( + flag: String, + value: String?, + key: CompilerConfigurationKey, + jvmTarget: JvmTarget +) { + if (value != null) { + val parsedValue = JvmClosureGenerationScheme.fromString(value) + if (parsedValue != null) { + put(key, parsedValue) + if (jvmTarget < parsedValue.minJvmTarget) { messageCollector.report( WARNING, - "`-Xsam-conversions=${arguments.samConversions}` requires JVM target at least " + - "${samConversions.minJvmTarget.description} and is ignored." + "`$flag=$value` requires JVM target at least " + + "${parsedValue.minJvmTarget.description} and is ignored." ) } } else { messageCollector.report( ERROR, - "Unknown `-Xsam-conversions` argument: ${arguments.samConversions}\n" + - "Supported arguments: ${JvmSamConversions.values().joinToString { it.description }}" + "Unknown `$flag` argument: ${value}\n." + + "Supported arguments: ${JvmClosureGenerationScheme.values().joinToString { it.description }}" ) } } - - addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList()) } fun CompilerConfiguration.configureJdkHome(arguments: K2JVMCompilerArguments): Boolean { diff --git a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index 97e60e10235..ed8f37de4af 100644 --- a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -114,9 +114,12 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey STRING_CONCAT = CompilerConfigurationKey.create("Specifies string concatenation scheme"); - public static final CompilerConfigurationKey SAM_CONVERSIONS = + public static final CompilerConfigurationKey SAM_CONVERSIONS = CompilerConfigurationKey.create("SAM conversions code generation scheme"); + public static final CompilerConfigurationKey LAMBDAS = + CompilerConfigurationKey.create("Lambdas code generation scheme"); + public static final CompilerConfigurationKey> KLIB_PATHS = CompilerConfigurationKey.create("Paths to .klib libraries"); diff --git a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmSamConversions.kt b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmClosureGenerationScheme.kt similarity index 93% rename from compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmSamConversions.kt rename to compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmClosureGenerationScheme.kt index 3ed25ea0b7f..70d950979a5 100644 --- a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmSamConversions.kt +++ b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JvmClosureGenerationScheme.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.config -enum class JvmSamConversions( +enum class JvmClosureGenerationScheme( val description: String, val minJvmTarget: JvmTarget ) { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index 8fb88500225..57a684cefb8 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -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("lambdas.kt") + public void testLambdas() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt"); + } + @Test @TestMetadata("streamApi.kt") public void testStreamApi() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JvmInvokeDynamic.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JvmInvokeDynamic.kt index a7911e1bd52..5593a189ee2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JvmInvokeDynamic.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/JvmInvokeDynamic.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.* import org.jetbrains.kotlin.codegen.inline.v import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.* @@ -101,7 +102,8 @@ object JvmInvokeDynamic : IntrinsicMethod() { private fun generateMethodHandle(irRawFunctionReference: IrRawFunctionReference, codegen: ExpressionCodegen): Handle { val irFun = irRawFunctionReference.symbol.owner - val irParentClass = irFun.parentAsClass + val irParentClass = irFun.parent as? IrClass + ?: throw AssertionError("Unexpected parent: ${irFun.parent.render()}") val owner = codegen.typeMapper.mapOwner(irParentClass) val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun) val handleTag = when { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt index 3f06295dccd..b04375dce84 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt @@ -15,7 +15,7 @@ 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.inlineclasses.InlineClassAbi -import org.jetbrains.kotlin.config.JvmSamConversions +import org.jetbrains.kotlin.config.JvmClosureGenerationScheme import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET @@ -74,6 +74,12 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) irFile.transformChildrenVoid(this) } + private val shouldGenerateIndySamConversions = + context.state.samConversionsScheme == JvmClosureGenerationScheme.INDY + + private val shouldGenerateIndyLambdas = + context.state.lambdasScheme == JvmClosureGenerationScheme.INDY + override fun visitBlock(expression: IrBlock): IrExpression { if (!expression.origin.isLambda) return super.visitBlock(expression) @@ -84,9 +90,24 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) expression.statements.dropLast(1).forEach { it.transform(this, null) } reference.transformChildrenVoid(this) + + if (shouldGenerateIndyLambdas && canUseIndySamConversion(reference, reference.type)) { + return wrapLambdaReferenceWithIndySamConversion(expression, reference) + } + return FunctionReferenceBuilder(reference).build() } + private fun wrapLambdaReferenceWithIndySamConversion(expression: IrBlock, reference: IrFunctionReference): IrBlock { + expression.statements[expression.statements.size - 1] = wrapWithIndySamConversion(reference.type, reference) + val irLambda = reference.symbol.owner + // JDK LambdaMetafactory can't adapt '(...)V' tp '(...)Lkotlin/Unit;'. + if (irLambda.returnType.isUnit()) { + irLambda.returnType = irLambda.returnType.makeNullable() + } + return expression + } + override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { expression.transformChildrenVoid(this) return if (expression.isIgnored) @@ -95,9 +116,6 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) FunctionReferenceBuilder(expression).build() } - private val shouldUseIndySamConversions = - context.state.samConversionsScheme == JvmSamConversions.INDY - // Handle SAM conversions which wrap a function reference: // class sam$n(private val receiver: R) : Interface { override fun method(...) = receiver.target(...) } // @@ -121,7 +139,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) reference.transformChildrenVoid() val samSuperType = expression.typeOperand - return if (shouldUseIndySamConversions && canUseIndySamConversion(reference, samSuperType)) { + return if (shouldGenerateIndySamConversions && canUseIndySamConversion(reference, samSuperType)) { wrapSamConversionArgumentWithIndySamConversion(expression) } else { FunctionReferenceBuilder(reference, samSuperType).build() @@ -129,7 +147,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) } private fun canUseIndySamConversion(reference: IrFunctionReference, samSuperType: IrType): Boolean { - // Can't use indy for regular function references by default (because of 'equals'). + // 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 false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt index 44e90ea38ea..04f6a0f3af8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt @@ -231,10 +231,9 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil } val targetExtensionReceiverParameter = targetFun.extensionReceiverParameter - if (targetExtensionReceiverParameter != null) { + if (targetExtensionReceiverParameter != null && irFunRef.extensionReceiver != null) { addValueParameter("p${syntheticParameterIndex++}", targetExtensionReceiverParameter.type) - val extensionReceiver = irFunRef.extensionReceiver - ?: fail("Captured extension receiver is not provided") + val extensionReceiver = irFunRef.extensionReceiver!! dynamicCallArguments.add(extensionReceiver) } diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 9d5a61915f4..549cb5dee9f 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -74,6 +74,10 @@ where advanced options include: -Xjvm-default=compatibility Allow usages of @JvmDefault; generate a compatibility accessor in the 'DefaultImpls' class in addition to the default interface method -Xklib= Paths to cross-platform libraries in .klib format + -Xlambdas={class|indy} Select code generation scheme for lambdas. + -Xlambdas=indy Generate lambdas using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater. + Lambda objects created using `LambdaMetafactory.metafactory` will have different `toString()`. + -Xlambdas=class Generate lambdas as explicit classes -Xno-call-assertions Don't generate not-null assertions for arguments of platform types -Xno-exception-on-explicit-equals-for-boxed-null Do not throw NPE on explicit 'equals' call for null receiver of platform boxed primitive type @@ -93,7 +97,7 @@ where advanced options include: Example: -Xprofile=/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000: -Xrepeat= Debug option: Repeats modules compilation times -Xsam-conversions={class|indy} Select code generation scheme for SAM conversions. - -Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 8` or greater. + -Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater. -Xsam-conversions=class Generate SAM conversions as explicit classes -Xsanitize-parentheses Transform '(' and ')' in method names to some other character sequence. This mode can BREAK BINARY COMPATIBILITY and is only supposed to be used to workaround @@ -107,10 +111,10 @@ where advanced options include: -Xgenerate-strict-metadata-version Generate metadata with strict version semantics (see kdoc on Metadata.extraInt) -Xstring-concat={indy-with-constants|indy|inline} - Switch a way in which string concatenation is performed. - -Xstring-concat=indy-with-constants Performs string concatenation via `invokedynamic` 'makeConcatWithConstants'. Works only with `-jvm-target 9` or greater - -Xstring-concat=indy Performs string concatenation via `invokedynamic` 'makeConcat'. Works only with `-jvm-target 9` or greater - -Xstring-concat=inline Performs string concatenation via `StringBuilder` + Select code generation scheme for string concatenation. + -Xstring-concat=indy-with-constants Concatenate strings using `invokedynamic` ` makeConcatWithConstants`. Requires `-jvm-target 9` or greater. + -Xstring-concat=indy Concatenate strings using `invokedynamic` `makeConcat`. Requires `-jvm-target 9` or greater. + -Xstring-concat=inline Concatenate strings using `StringBuilder` -Xsupport-compatqual-checker-framework-annotations=enable|disable Specify behavior for Checker Framework compatqual annotations (NullableDecl/NonNullDecl). Default value is 'enable' diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/capturedDispatchReceiver.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/capturedDispatchReceiver.kt new file mode 100644 index 00000000000..7b5580d4c09 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/capturedDispatchReceiver.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +class C(val x: String) { + fun test() = { x } +} + +fun box() = C("OK").test()() \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/capturedExtensionReceiver.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/capturedExtensionReceiver.kt new file mode 100644 index 00000000000..4ba7c831bea --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/capturedExtensionReceiver.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +class C(val x: String) + +fun C.test() = { x } + +fun box() = C("OK").test()() \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/capturingValue.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/capturingValue.kt new file mode 100644 index 00000000000..d043125b227 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/capturingValue.kt @@ -0,0 +1,8 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box(): String { + val ok = "OK" + return { ok }() +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/capturingVar.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/capturingVar.kt new file mode 100644 index 00000000000..a1d063d9d27 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/capturingVar.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box(): String { + var ok = "Failed" + { ok = "OK" }() + return ok +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/extensionLambda.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/extensionLambda.kt new file mode 100644 index 00000000000..ae44019e814 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/extensionLambda.kt @@ -0,0 +1,12 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +class C(val x: String) + +fun boxLambda(lambda: C.() -> String) = lambda + +fun box(): String { + val ext = boxLambda { x } + return C("OK").ext() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda1.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda1.kt new file mode 100644 index 00000000000..438ae34742e --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda1.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY +// FILE: 1.kt +inline fun cross(crossinline fn: () -> String) : Any = + object { + override fun toString(): String = fn() + } + +fun foo(fn: () -> String) = fn() + +// FILE: 2.kt +fun box() = + cross { + foo { "OK" } + }.toString() \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda2.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda2.kt new file mode 100644 index 00000000000..deec869c487 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda2.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY +// FILE: 1.kt +class C { + fun test() = + cross { + foo { "OK" } + }.toString() +} + +inline fun cross(crossinline fn: () -> String) : Any = + object { + override fun toString(): String = fn() + } + +fun foo(fn: () -> String) = fn() + +// FILE: 2.kt +fun box() = + C().test() + diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineFunInDifferentPackage.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineFunInDifferentPackage.kt new file mode 100644 index 00000000000..7c326af1a10 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineFunInDifferentPackage.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY +// WITH_RUNTIME +// FILE: 2.kt +import a.* + +fun box() = test { k -> "O" + k } + +// FILE: 1.kt +package a + +fun fooK(fn: (String) -> String) = fn("K") + +inline fun test(crossinline lambda: (String) -> String) = + fooK { k -> lambda(k) } \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineLambda1.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineLambda1.kt new file mode 100644 index 00000000000..10f12fb9feb --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineLambda1.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY +// WITH_RUNTIME +// FILE: 1.kt + +fun foo(fn: () -> Unit) = fn() + +inline fun twice(fn: () -> Unit) { + fn() + fn() +} + +// FILE: 2.kt +fun box(): String { + var test = 0 + twice { + foo { test += 1 } + } + if (test != 2) + return "Failed: test=$test" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineAny.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineAny.kt new file mode 100644 index 00000000000..eb73b62dde2 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineAny.kt @@ -0,0 +1,15 @@ +// TARGET_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: Any) + +fun foo1(fs: (Z) -> Z) = fs(Z(1)) + +fun box(): String { + val t = foo1 { Z((it.value as Int) + 41) } + if (t.value != 42) return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineInt.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineInt.kt new file mode 100644 index 00000000000..3ca59c13264 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineInt.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: Int) + +fun foo1(fs: (Z) -> Z) = fs(Z(1)) + +fun box(): String { + val t = foo1 { Z(it.value + 41) } + if (t.value != 42) return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNAny.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNAny.kt new file mode 100644 index 00000000000..c75f7530490 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNAny.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: Any?) + +fun foo1(fs: (Z) -> Z) = fs(Z(1)) + +fun box(): String { + val t = foo1 { Z((it.value as Int) + 41) } + if (t.value != 42) return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNInt.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNInt.kt new file mode 100644 index 00000000000..605ae5d982d --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNInt.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: Int?) + +fun foo1(fs: (Z) -> Z) = fs(Z(1)) + +fun box(): String { + val t = foo1 { Z(it.value!! + 41) } + if (t.value != 42) return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNString.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNString.kt new file mode 100644 index 00000000000..f41d25b5edb --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNString.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: String?) + +fun foo1(fs: (Z) -> Z) = fs(Z("O")) + +fun box(): String { + val t = foo1 { Z(it.value!! + "K") } + if (t.value != "OK") return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineString.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineString.kt new file mode 100644 index 00000000000..04efad0bf78 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineString.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +inline class Z(val value: String) + +fun foo1(fs: (Z) -> Z) = fs(Z("O")) + +fun box(): String { + val t = foo1 { Z(it.value + "K") } + if (t.value != "OK") return "Failed: t=$t" + + return "OK" +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/nestedIndyLambdas.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/nestedIndyLambdas.kt new file mode 100644 index 00000000000..5081ecf869a --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/nestedIndyLambdas.kt @@ -0,0 +1,5 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box() = { { "O" }() + { "K" }() }() diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/primitiveValueParameters.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/primitiveValueParameters.kt new file mode 100644 index 00000000000..31755c370e5 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/primitiveValueParameters.kt @@ -0,0 +1,10 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box(): String { + val test = { i: Int -> i + 40 }(2) + if (test != 42) return "Failed: test=$test" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/simpleIndyLambda.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/simpleIndyLambda.kt new file mode 100644 index 00000000000..5c722ba6995 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/simpleIndyLambda.kt @@ -0,0 +1,5 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box() = { "OK" }() diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/suspendLambda.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/suspendLambda.kt new file mode 100644 index 00000000000..50ab4c25a4d --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/suspendLambda.kt @@ -0,0 +1,35 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY +// WITH_RUNTIME +// WITH_COROUTINES + +import kotlin.coroutines.* + +var c: Continuation? = null + +suspend fun suspendMe() = suspendCoroutine { continuation -> + c = continuation +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object: Continuation { + override val context = EmptyCoroutineContext + override fun resumeWith(result: Result) { + result.getOrThrow() + } + }) +} + +fun box(): String { + var test = "" + builder { + suspendMe() + test += "O" + suspendMe() + test += "K" + } + c?.resume(Unit) + c?.resume(Unit) + return test +} diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/voidReturnType.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/voidReturnType.kt new file mode 100644 index 00000000000..77fb0188c06 --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/voidReturnType.kt @@ -0,0 +1,10 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +var ok = "Failed" + +fun box(): String { + { ok = "OK" }() + return ok +} diff --git a/compiler/testData/codegen/box/invokedynamic/sam/voidReturnTypeAsGeneric.kt b/compiler/testData/codegen/box/invokedynamic/sam/voidReturnTypeAsGeneric.kt new file mode 100644 index 00000000000..6392915e1cc --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/sam/voidReturnTypeAsGeneric.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun interface IFoo { + fun foo(): T +} + +fun foo(iFoo: IFoo) = iFoo.foo() + +var ok = "Failed" + +fun box(): String { + foo { ok = "OK" } + return ok +} diff --git a/compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt b/compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt new file mode 100644 index 00000000000..847147f71c3 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt @@ -0,0 +1,14 @@ +// TARGET_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun test() = { { "O" }() + { "K" }() }() + +// JVM_IR_TEMPLATES +// 3 INVOKEDYNAMIC +// 0 class LambdasKt\$test\$ + +// JVM_TEMPLATES +// 0 INVOKEDYNAMIC +// 3 class LambdasKt\$test\$ \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java index 1b0294f28be..43e6f54d190 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java @@ -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("lambdas.kt") + public void testLambdas() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt"); + } + @Test @TestMetadata("streamApi.kt") public void testStreamApi() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index 28ca0d98394..de081a57448 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -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("lambdas.kt") + public void testLambdas() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/invokedynamic/lambdas.kt"); + } + @Test @TestMetadata("streamApi.kt") public void testStreamApi() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JvmEnvironmentConfigurationDirectives.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JvmEnvironmentConfigurationDirectives.kt index 5e16746d2b8..a911e111943 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JvmEnvironmentConfigurationDirectives.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JvmEnvironmentConfigurationDirectives.kt @@ -57,7 +57,12 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() { @Suppress("RemoveExplicitTypeArguments") val SAM_CONVERSIONS by enumDirective( description = "SAM conversion code generation scheme", - additionalParser = JvmSamConversions.Companion::fromString + additionalParser = JvmClosureGenerationScheme.Companion::fromString + ) + + val LAMBDAS by enumDirective( + description = "Lambdas code generation scheme", + additionalParser = JvmClosureGenerationScheme.Companion::fromString ) val USE_OLD_INLINE_CLASSES_MANGLING_SCHEME by directive( diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index 7ec0669f1d4..1ee91629bec 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ASSERTIONS_MODE import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.CONSTRUCTOR_CALL_NORMALIZATION_MODE +import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.LAMBDAS import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.SAM_CONVERSIONS import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STRING_CONCAT import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME @@ -57,6 +58,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig register(ASSERTIONS_MODE, JVMConfigurationKeys.ASSERTIONS_MODE) register(CONSTRUCTOR_CALL_NORMALIZATION_MODE, JVMConfigurationKeys.CONSTRUCTOR_CALL_NORMALIZATION_MODE) register(SAM_CONVERSIONS, JVMConfigurationKeys.SAM_CONVERSIONS) + register(LAMBDAS, JVMConfigurationKeys.LAMBDAS) register(USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 349cab29b2d..3a4d748d9e1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16179,6 +16179,145 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lambdas extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInLambdas() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("capturedDispatchReceiver.kt") + public void testCapturedDispatchReceiver() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/capturedDispatchReceiver.kt"); + } + + @TestMetadata("capturedExtensionReceiver.kt") + public void testCapturedExtensionReceiver() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/capturedExtensionReceiver.kt"); + } + + @TestMetadata("capturingValue.kt") + public void testCapturingValue() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/capturingValue.kt"); + } + + @TestMetadata("capturingVar.kt") + public void testCapturingVar() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/capturingVar.kt"); + } + + @TestMetadata("extensionLambda.kt") + public void testExtensionLambda() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/extensionLambda.kt"); + } + + @TestMetadata("nestedIndyLambdas.kt") + public void testNestedIndyLambdas() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/nestedIndyLambdas.kt"); + } + + @TestMetadata("primitiveValueParameters.kt") + public void testPrimitiveValueParameters() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/primitiveValueParameters.kt"); + } + + @TestMetadata("simpleIndyLambda.kt") + public void testSimpleIndyLambda() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/simpleIndyLambda.kt"); + } + + @TestMetadata("suspendLambda.kt") + public void testSuspendLambda() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/suspendLambda.kt"); + } + + @TestMetadata("voidReturnType.kt") + public void testVoidReturnType() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/voidReturnType.kt"); + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inline extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("crossinlineLambda1.kt") + public void testCrossinlineLambda1() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda1.kt"); + } + + @TestMetadata("crossinlineLambda2.kt") + public void testCrossinlineLambda2() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inline/crossinlineLambda2.kt"); + } + + @TestMetadata("inlineFunInDifferentPackage.kt") + public void testInlineFunInDifferentPackage() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineFunInDifferentPackage.kt"); + } + + @TestMetadata("inlineLambda1.kt") + public void testInlineLambda1() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inline/inlineLambda1.kt"); + } + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClassInSignature extends AbstractLightAnalysisModeTest { + @TestMetadata("lambdaWithInlineInt.kt") + public void ignoreLambdaWithInlineInt() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineInt.kt"); + } + + @TestMetadata("lambdaWithInlineNAny.kt") + public void ignoreLambdaWithInlineNAny() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNAny.kt"); + } + + @TestMetadata("lambdaWithInlineNInt.kt") + public void ignoreLambdaWithInlineNInt() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNInt.kt"); + } + + @TestMetadata("lambdaWithInlineNString.kt") + public void ignoreLambdaWithInlineNString() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineNString.kt"); + } + + @TestMetadata("lambdaWithInlineString.kt") + public void ignoreLambdaWithInlineString() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineString.kt"); + } + + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInInlineClassInSignature() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("lambdaWithInlineAny.kt") + public void testLambdaWithInlineAny() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature/lambdaWithInlineAny.kt"); + } + } + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -16296,6 +16435,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/invokedynamic/sam/unboundFunctionReferenceEquality.kt"); } + @TestMetadata("voidReturnTypeAsGeneric.kt") + public void testVoidReturnTypeAsGeneric() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/voidReturnTypeAsGeneric.kt"); + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inline") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 251df42ca29..5a5a99456f6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -14459,6 +14459,45 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lambdas extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInLambdas() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inline extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClassInSignature extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInInlineClassInSignature() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + } + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 9c27fd24879..cb3fbff352b 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13944,6 +13944,45 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lambdas extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInLambdas() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inline extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClassInSignature extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInInlineClassInSignature() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 89737bc50e9..18e4a0d608c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -14009,6 +14009,45 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lambdas extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInLambdas() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inline extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClassInSignature extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInInlineClassInSignature() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 4e0931b562e..4b5c0e01b41 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -8080,6 +8080,45 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lambdas extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInLambdas() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inline extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inline"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + } + + @TestMetadata("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClassInSignature extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInInlineClassInSignature() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas/inlineClassInSignature"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + } + } + @TestMetadata("compiler/testData/codegen/box/invokedynamic/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)