JVM_IR indy-SAM conversions: more cases

KT-44278 KT-26060 KT-42621
This commit is contained in:
Dmitry Petrov
2021-01-20 14:51:07 +03:00
parent 3140cca050
commit f30e25aa52
17 changed files with 383 additions and 57 deletions
@@ -18403,6 +18403,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/boundReference.kt");
}
@Test
@TestMetadata("builtinMemberReference.kt")
public void testBuiltinMemberReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/builtinMemberReference.kt");
}
@Test
@TestMetadata("capturedDispatchReceiver.kt")
public void testCapturedDispatchReceiver() throws Exception {
@@ -18427,12 +18433,42 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingIndySam.kt");
}
@Test
@TestMetadata("capturingVar.kt")
public void testCapturingVar() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingVar.kt");
}
@Test
@TestMetadata("constructorReference.kt")
public void testConstructorReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/constructorReference.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterface.kt");
}
@Test
@TestMetadata("genericFunInterfaceWithPrimitive.kt")
public void testGenericFunInterfaceWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
}
@Test
@TestMetadata("primitiveVsWrapperInSam.kt")
public void testPrimitiveVsWrapperInSam() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/primitiveVsWrapperInSam.kt");
}
@Test
@TestMetadata("samConversionOnFunctionReference.kt")
public void testSamConversionOnFunctionReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/samConversionOnFunctionReference.kt");
}
@Test
@TestMetadata("simpleIndyFunInterface.kt")
public void testSimpleIndyFunInterface() throws Exception {
@@ -604,11 +604,25 @@ class JvmSymbols(
}.symbol
// Intrinsic used to represent MethodType objects in bootstrap method arguments (see jvmInvokeDynamicIntrinsic above).
// Type argument is a possibly substituted method owner type (e.g., 'java.lang.function.Supplier<String>').
// Value argument is a raw function reference to a corresponding method (e.g., 'java.lang.function.Supplier#get').
val jvmMethodTypeIntrinsic: IrSimpleFunctionSymbol =
// Resulting method type is unsubstituted.
val jvmOriginalMethodTypeIntrinsic: IrSimpleFunctionSymbol =
irFactory.buildFun {
name = Name.special("<jvm-method-type>")
name = Name.special("<jvm-original-method-type>")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
}.apply {
parent = kotlinJvmInternalPackage
addValueParameter("method", irBuiltIns.anyType)
returnType = irBuiltIns.anyType
}.symbol
// Intrinsic used to represent MethodType objects in bootstrap method arguments (see jvmInvokeDynamicIntrinsic above).
// Type argument is a substituted method owner type (e.g., 'java.lang.function.Supplier<String>').
// Value argument is a raw function reference to a corresponding method (e.g., 'java.lang.function.Supplier#get').
// Resulting method type is substituted.
val jvmSubstitutedMethodTypeIntrinsic: IrSimpleFunctionSymbol =
irFactory.buildFun {
name = Name.special("<jvm-substituted-method-type>")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
}.apply {
parent = kotlinJvmInternalPackage
@@ -8,10 +8,17 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
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.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.overrides.buildFakeOverrideMember
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Handle
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -71,8 +78,10 @@ object JvmInvokeDynamic : IntrinsicMethod() {
generateMethodHandle(element, codegen)
is IrCall ->
when (element.symbol) {
codegen.context.ir.symbols.jvmMethodTypeIntrinsic ->
generateMethodType(element, codegen)
codegen.context.ir.symbols.jvmOriginalMethodTypeIntrinsic ->
generateOriginalMethodType(element, codegen)
codegen.context.ir.symbols.jvmSubstitutedMethodTypeIntrinsic ->
generateSubstitutedMethodType(element, codegen)
else ->
throw AssertionError("Unexpected callee in bootstrap method argument:\n${element.dump()}")
}
@@ -92,12 +101,14 @@ object JvmInvokeDynamic : IntrinsicMethod() {
throw AssertionError("Unexpected bootstrap method argument:\n${element.dump()}")
}
private fun generateMethodHandle(irRawFunctionReference: IrRawFunctionReference, codegen: ExpressionCodegen): Any {
private fun generateMethodHandle(irRawFunctionReference: IrRawFunctionReference, codegen: ExpressionCodegen): Handle {
val irFun = irRawFunctionReference.symbol.owner
val irParentClass = irFun.parentAsClass
val owner = codegen.typeMapper.mapOwner(irParentClass)
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun)
val handleTag = when {
irFun is IrConstructor ->
Opcodes.H_NEWINVOKESPECIAL
irFun.dispatchReceiverParameter == null ->
Opcodes.H_INVOKESTATIC
else ->
@@ -106,18 +117,57 @@ object JvmInvokeDynamic : IntrinsicMethod() {
return Handle(handleTag, owner.internalName, asmMethod.name, asmMethod.descriptor, irParentClass.isJvmInterface)
}
private fun generateMethodType(jvmMethodTypeCall: IrCall, codegen: ExpressionCodegen): Any {
val irRawFunctionReference = jvmMethodTypeCall.getValueArgument(0) as? IrRawFunctionReference
private fun generateOriginalMethodType(irCall: IrCall, codegen: ExpressionCodegen): Type {
val irRawFunRef = irCall.getValueArgument(0) as? IrRawFunctionReference
?: throw AssertionError(
"Argument in ${jvmMethodTypeCall.symbol.owner.name} call is expected to be a raw function reference:\n" +
jvmMethodTypeCall.dump()
"Argument in ${irCall.symbol.owner.name} call is expected to be a raw function reference:\n" +
irCall.dump()
)
val irFun = irRawFunctionReference.symbol.owner
// TODO substitute signature
val irFun = irRawFunRef.symbol.owner
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun)
return Type.getMethodType(asmMethod.descriptor)
}
private fun generateSubstitutedMethodType(irCall: IrCall, codegen: ExpressionCodegen): Type {
fun fail(message: String): Nothing =
throw AssertionError("$message; irCall:\n${irCall.dump()}")
val irRawFunRef = irCall.getValueArgument(0) as? IrRawFunctionReference
?: fail("Argument in ${irCall.symbol.owner.name} call is expected to be a raw function reference")
val irOriginalFun = irRawFunRef.symbol.owner as? IrSimpleFunction
?: fail("IrSimpleFunction expected: ${irRawFunRef.symbol.owner.render()}")
val substitutedType = irCall.getTypeArgument(0) as? IrSimpleType
?: fail("Type argument expected")
// Force boxing on primitive types, otherwise D8 fails to accept resulting MethodType in presence of primitive types in arguments
// (LambdaMetafactory is ok with such types, though).
val substitutedTypeWithNullableArgs =
substitutedType.classifier.typeWithArguments(
substitutedType.arguments.map {
when (it) {
is IrStarProjection -> it
is IrTypeProjection -> {
val type = it.type
if (type !is IrSimpleType || type.hasQuestionMark)
it
else
makeTypeProjection(type.withHasQuestionMark(true), it.variance)
}
else ->
fail("Unexpected type argument '${it}' :: ${it::class.simpleName}")
}
}
)
val fakeClass = codegen.context.irFactory.buildClass { name = Name.special("<fake>") }
fakeClass.parent = codegen.context.ir.symbols.kotlinJvmInternalInvokeDynamicPackage
val irFakeOverride = buildFakeOverrideMember(substitutedTypeWithNullableArgs, irOriginalFun, fakeClass) as IrSimpleFunction
irFakeOverride.overriddenSymbols = listOf(irOriginalFun.symbol)
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFakeOverride)
return Type.getMethodType(asmMethod.descriptor)
}
private fun IrExpression.getIntConst() =
if (this is IrConst<*> && kind == IrConstKind.Int)
this.value as Int
@@ -103,13 +103,24 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
}
reference.transformChildrenVoid()
return if (shouldUseIndySamConversions) {
return if (shouldUseIndySamConversions && canUseIndySamConversion(reference)) {
wrapSamConversionArgumentWithIndySamConversion(expression)
} else {
FunctionReferenceBuilder(reference, expression.typeOperand).build()
}
}
private fun canUseIndySamConversion(reference: IrFunctionReference): Boolean {
// Can't use indy for regular function references by default (because of 'equals').
// TODO special mode that would generate indy everywhere?
if (reference.origin != IrStatementOrigin.LAMBDA)
return false
// TODO wrap intrinsic function in lambda?
if (context.irIntrinsics.getIntrinsic(reference.symbol) != null)
return false
return true
}
private fun wrapSamConversionArgumentWithIndySamConversion(expression: IrTypeOperatorCall): IrExpression {
return when (val argument = expression.argument) {
is IrFunctionReference ->
@@ -121,10 +121,16 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
putValueArgument(5, irVararg(context.irBuiltIns.anyType, bootstrapMethodArguments))
}
private val methodTypeIntrinsic = context.ir.symbols.jvmMethodTypeIntrinsic
private val originalMethodTypeIntrinsic = context.ir.symbols.jvmOriginalMethodTypeIntrinsic
private val substitutedMethodTypeIntrinsic = context.ir.symbols.jvmSubstitutedMethodTypeIntrinsic
private fun IrBuilderWithScope.jvmMethodType(ownerType: IrType, methodSymbol: IrFunctionSymbol) =
irCall(methodTypeIntrinsic, context.irBuiltIns.anyType).apply {
private fun IrBuilderWithScope.jvmOriginalMethodType(methodSymbol: IrFunctionSymbol) =
irCall(originalMethodTypeIntrinsic, context.irBuiltIns.anyType).apply {
putValueArgument(0, irRawFunctionReferefence(context.irBuiltIns.anyType, methodSymbol))
}
private fun IrBuilderWithScope.jvmSubstitutedMethodType(ownerType: IrType, methodSymbol: IrFunctionSymbol) =
irCall(substitutedMethodTypeIntrinsic, context.irBuiltIns.anyType).apply {
putTypeArgument(0, ownerType)
putValueArgument(0, irRawFunctionReferefence(context.irBuiltIns.anyType, methodSymbol))
}
@@ -181,16 +187,15 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
?: fail("'method' is expected to be 'IrFunctionReference'")
val funSymbol = irFunRef.symbol
val erasedSamType = samClassSymbol.defaultType as IrSimpleType
val dynamicCall = wrapClosureInDynamicCall(erasedSamType, samMethod, irFunRef)
val dynamicCall = wrapClosureInDynamicCall(samType, samMethod, irFunRef)
return context.createJvmIrBuilder(
funSymbol, // TODO actual symbol for outer scope
startOffset, endOffset
).run {
val samMethodType = jvmMethodType(erasedSamType, samMethod.symbol)
val samMethodType = jvmOriginalMethodType(samMethod.symbol)
val irRawFunRef = irRawFunctionReferefence(irFunRef.type, funSymbol)
val instanceMethodType = jvmMethodType(samType, samMethod.symbol)
val instanceMethodType = jvmSubstitutedMethodType(samType, samMethod.symbol)
jvmInvokeDynamic(
dynamicCall,
@@ -38,7 +38,8 @@ abstract class IrGetEnumValue : IrGetSingletonValue() {
/**
* Platform-specific low-level reference to function.
*
* On JS platform represent a plain reference to JavaScript function.
* On JS platform it represents a plain reference to JavaScript function.
* On JVM platform it represents a MethodHandle constant.
*/
abstract class IrRawFunctionReference : IrDeclarationReference() {
abstract override val symbol: IrFunctionSymbol
@@ -23,33 +23,8 @@ import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.types.Variance
abstract class FakeOverrideBuilderStrategy {
open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember{
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
for (i in typeParameters.indices) {
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: $ta @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
}
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride
}
open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember =
buildFakeOverrideMember(superType, member, clazz)
fun linkFakeOverride(fakeOverride: IrOverridableMember) {
when (fakeOverride) {
@@ -66,6 +41,35 @@ abstract class FakeOverrideBuilderStrategy {
val propertyOverriddenSymbols: MutableMap<IrOverridableMember, List<IrSymbol>> = mutableMapOf()
}
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember {
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
for (i in typeParameters.indices) {
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: $ta @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
}
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride
}
// TODO:
// The below pile of code is basically half of OverridingUtil.java
// adapted to IR and converted to Kotlin.
@@ -294,7 +298,7 @@ class IrOverridingUtil(
}
val realOverrides = members
.map{ originals[it]!! }
.map { originals[it]!! }
.collectAndFilterRealOverrides()
return getMinimalModality(realOverrides, transformAbstractToClassModality, current.modality)
}
@@ -349,7 +353,10 @@ class IrOverridingUtil(
return result
}
private fun IrSimpleFunction.updateAccessorModalityAndVisibility(newModality: Modality, newVisibility: DescriptorVisibility): IrSimpleFunction? {
private fun IrSimpleFunction.updateAccessorModalityAndVisibility(
newModality: Modality,
newVisibility: DescriptorVisibility
): IrSimpleFunction? {
require(this is IrFakeOverrideFunction) {
"Unexpected fake override accessor kind: $this"
}
@@ -746,15 +753,15 @@ class IrOverridingUtil(
fun IrSimpleFunction.isOverridableFunction(): Boolean =
this.visibility != DescriptorVisibilities.PRIVATE &&
this.dispatchReceiverParameter != null
this.dispatchReceiverParameter != null
fun IrProperty.isOverridableProperty(): Boolean =
this.visibility != DescriptorVisibilities.PRIVATE &&
(this.getter?.dispatchReceiverParameter != null ||
this.setter?.dispatchReceiverParameter != null)
(this.getter?.dispatchReceiverParameter != null ||
this.setter?.dispatchReceiverParameter != null)
fun IrDeclaration.isOverridableMemberOrAccessor(): Boolean = when(this) {
fun IrDeclaration.isOverridableMemberOrAccessor(): Boolean = when (this) {
is IrSimpleFunction -> isOverridableFunction()
is IrProperty -> isOverridableProperty()
else -> false
}
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
fun interface IntFun {
fun invoke(i: Int): Int
}
fun invoke1(intFun: IntFun) = intFun.invoke(1)
fun box(): String {
val test = invoke1(41::plus)
if (test != 42) return "Failed: $test"
return "OK"
}
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
fun interface KRunnable {
fun run()
}
fun runIt(r: KRunnable) {
r.run()
}
fun box(): String {
var test = "Failed"
runIt { test = "OK" }
return test
}
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
class C(val test: String)
fun interface MakeC {
fun make(x: String): C
}
fun make(makeC: MakeC) = makeC.make("OK")
fun box() = make(::C).test
@@ -0,0 +1,11 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
fun interface IFoo<T> {
fun foo(x: T): T
}
fun foo(fs: IFoo<String>) = fs.foo("O")
fun box() = foo { "${it}K" }
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
fun interface IFoo<T> {
fun foo(x: T): T
}
fun foo1(fs: IFoo<Int>) = fs.foo(1)
fun box(): String {
val t = foo1 { it + 41 }
if (t != 42) return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,22 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
fun interface KRunnable {
fun run()
}
fun runnable(kr: KRunnable) = kr
fun foo() {}
fun box(): String {
val foo1 = runnable(::foo)
val foo2 = runnable(::foo)
if (foo1 != foo2) {
return "Failed: foo1 != foo2"
}
return "OK"
}
@@ -18403,6 +18403,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/invokedynamic/sam/boundReference.kt");
}
@Test
@TestMetadata("builtinMemberReference.kt")
public void testBuiltinMemberReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/builtinMemberReference.kt");
}
@Test
@TestMetadata("capturedDispatchReceiver.kt")
public void testCapturedDispatchReceiver() throws Exception {
@@ -18427,12 +18433,42 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingIndySam.kt");
}
@Test
@TestMetadata("capturingVar.kt")
public void testCapturingVar() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingVar.kt");
}
@Test
@TestMetadata("constructorReference.kt")
public void testConstructorReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/constructorReference.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterface.kt");
}
@Test
@TestMetadata("genericFunInterfaceWithPrimitive.kt")
public void testGenericFunInterfaceWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
}
@Test
@TestMetadata("primitiveVsWrapperInSam.kt")
public void testPrimitiveVsWrapperInSam() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/primitiveVsWrapperInSam.kt");
}
@Test
@TestMetadata("samConversionOnFunctionReference.kt")
public void testSamConversionOnFunctionReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/samConversionOnFunctionReference.kt");
}
@Test
@TestMetadata("simpleIndyFunInterface.kt")
public void testSimpleIndyFunInterface() throws Exception {
@@ -18403,6 +18403,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/boundReference.kt");
}
@Test
@TestMetadata("builtinMemberReference.kt")
public void testBuiltinMemberReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/builtinMemberReference.kt");
}
@Test
@TestMetadata("capturedDispatchReceiver.kt")
public void testCapturedDispatchReceiver() throws Exception {
@@ -18427,12 +18433,42 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingIndySam.kt");
}
@Test
@TestMetadata("capturingVar.kt")
public void testCapturingVar() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingVar.kt");
}
@Test
@TestMetadata("constructorReference.kt")
public void testConstructorReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/constructorReference.kt");
}
@Test
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterface.kt");
}
@Test
@TestMetadata("genericFunInterfaceWithPrimitive.kt")
public void testGenericFunInterfaceWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
}
@Test
@TestMetadata("primitiveVsWrapperInSam.kt")
public void testPrimitiveVsWrapperInSam() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/primitiveVsWrapperInSam.kt");
}
@Test
@TestMetadata("samConversionOnFunctionReference.kt")
public void testSamConversionOnFunctionReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/samConversionOnFunctionReference.kt");
}
@Test
@TestMetadata("simpleIndyFunInterface.kt")
public void testSimpleIndyFunInterface() throws Exception {
@@ -46,7 +46,11 @@ class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(testSe
try {
for (ktFile in ktFiles) {
val className = ktFile.getFacadeFqName() ?: continue
val clazz = classLoader.getGeneratedClass(className)
val clazz = try {
classLoader.getGeneratedClass(className)
} catch (e: LinkageError) {
throw AssertionError("Failed to load class '$className':\n${info.classFileFactory.createText()}", e)
}
val method = clazz.getBoxMethodOrNull() ?: continue
boxMethodFound = true
callBoxMethodAndCheckResultWithCleanup(
@@ -128,7 +132,7 @@ class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(testSe
): GeneratedClassLoader {
val classLoader = createClassLoader(module, classFileFactory)
val verificationSucceeded = CodegenTestUtil.verifyAllFilesWithAsm(classFileFactory, classLoader, reportProblems)
if (!verificationSucceeded ) {
if (!verificationSucceeded) {
assertions.fail { "Verification failed: see exceptions above" }
}
return classLoader
@@ -16138,6 +16138,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/boundReference.kt");
}
@TestMetadata("builtinMemberReference.kt")
public void testBuiltinMemberReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/builtinMemberReference.kt");
}
@TestMetadata("capturedDispatchReceiver.kt")
public void testCapturedDispatchReceiver() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturedDispatchReceiver.kt");
@@ -16158,11 +16163,36 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingIndySam.kt");
}
@TestMetadata("capturingVar.kt")
public void testCapturingVar() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/capturingVar.kt");
}
@TestMetadata("constructorReference.kt")
public void testConstructorReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/constructorReference.kt");
}
@TestMetadata("genericFunInterface.kt")
public void testGenericFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterface.kt");
}
@TestMetadata("genericFunInterfaceWithPrimitive.kt")
public void testGenericFunInterfaceWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
}
@TestMetadata("primitiveVsWrapperInSam.kt")
public void testPrimitiveVsWrapperInSam() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/primitiveVsWrapperInSam.kt");
}
@TestMetadata("samConversionOnFunctionReference.kt")
public void testSamConversionOnFunctionReference() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/samConversionOnFunctionReference.kt");
}
@TestMetadata("simpleIndyFunInterface.kt")
public void testSimpleIndyFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/simpleIndyFunInterface.kt");