diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 2042a2828de..e78a9ec55b2 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1367,11 +1367,31 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/expressions/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("samByProjectedType.kt") + public void testSamByProjectedType() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt"); + } + @TestMetadata("samConstructors.kt") public void testSamConstructors() throws Exception { runTest("compiler/testData/ir/irText/expressions/sam/samConstructors.kt"); } + @TestMetadata("samConversionInGenericConstructorCall.kt") + public void testSamConversionInGenericConstructorCall() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt"); + } + + @TestMetadata("samConversionInGenericConstructorCall_NI.kt") + public void testSamConversionInGenericConstructorCall_NI() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt"); + } + + @TestMetadata("samConversionToGeneric.kt") + public void testSamConversionToGeneric() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt"); + } + @TestMetadata("samConversions.kt") public void testSamConversions() throws Exception { runTest("compiler/testData/ir/irText/expressions/sam/samConversions.kt"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt index 394c14a9c9a..abf80eef031 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor @@ -16,7 +15,7 @@ import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor -import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.* object JvmGeneratorExtensions : GeneratorExtensions() { override val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = { descriptor -> @@ -43,15 +42,14 @@ object JvmGeneratorExtensions : GeneratorExtensions() { override fun isSamType(type: KotlinType): Boolean = SingleAbstractMethodUtils.isSamType(type) - override fun getFunctionTypeForSAMClass(descriptor: ClassDescriptor): KotlinType { - if (descriptor !is JavaClassDescriptor) { - throw AssertionError("SAM should be represented by a Java class: $descriptor") - } - + override fun getSubstitutedFunctionTypeForSamType(samType: KotlinType): KotlinType { + val descriptor = samType.constructor.declarationDescriptor as? JavaClassDescriptor + ?: throw AssertionError("SAM should be represented by a Java class: $samType") val singleAbstractMethod = SingleAbstractMethodUtils.getSingleAbstractMethodOrNull(descriptor) ?: throw AssertionError("$descriptor should have a single abstract method") - - return SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(singleAbstractMethod, false) + val unsubstitutedFunctionType = SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(singleAbstractMethod, false) + return TypeSubstitutor.create(samType).substitute(unsubstitutedFunctionType, Variance.INVARIANT) + ?: throw AssertionError("Failed to substitute function type $unsubstitutedFunctionType corresponding to $samType") } companion object Instance : JvmSamConversion() diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 0fad6be29c0..5724792705d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -41,7 +41,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.scopes.receivers.* import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.Variance import kotlin.math.max import kotlin.math.min @@ -292,17 +294,9 @@ fun StatementGenerator.generateValueArgumentUsing( TODO("Unexpected valueArgument: ${valueArgument::class.java.simpleName}") } -fun StatementGenerator.castArgumentToFunctionalInterfaceForSamType( - irExpression: IrExpression, - samType: KotlinType -): IrExpression { - val samConversion = context.extensions.samConversion - val samTypeDescriptor = samType.constructor.declarationDescriptor - val samClassDescriptor = samTypeDescriptor as? ClassDescriptor - ?: throw AssertionError("SAM class expected: $samType") - val kotlinFunctionType = samConversion.getFunctionTypeForSAMClass(samClassDescriptor) +fun StatementGenerator.castArgumentToFunctionalInterfaceForSamType(irExpression: IrExpression, samType: KotlinType): IrExpression { + val kotlinFunctionType = context.extensions.samConversion.getSubstitutedFunctionTypeForSamType(samType) val irFunctionType = context.typeTranslator.translateType(kotlinFunctionType) - return irExpression.implicitCastTo(irFunctionType) } @@ -422,6 +416,16 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca "Mismatching value parameters, $originalDescriptor vs call: " + "${originalValueParameters.size} != ${call.argumentsCount}" } + assert(underlyingDescriptor.typeParameters.size == originalDescriptor.typeParameters.size) { + "Mismatching type parameters:\n" + + "$underlyingDescriptor has ${underlyingDescriptor.typeParameters}\n" + + "$originalDescriptor has ${originalDescriptor.typeParameters}" + } + + val substitutionContext = call.original.typeArguments.entries.associate { (typeParameterDescriptor, typeArgument) -> + underlyingDescriptor.typeParameters[typeParameterDescriptor.index].typeConstructor to TypeProjectionImpl(typeArgument) + } + val typeSubstitutor = TypeSubstitutor.create(substitutionContext) for (i in underlyingValueParameters.indices) { val originalParameterType = originalValueParameters[i].type @@ -432,7 +436,13 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca val originalArgument = call.irValueArgumentsByIndex[i] ?: continue - val targetType = underlyingParameterType.toIrType() + val expectedArgumentType = typeSubstitutor.substitute(underlyingParameterType, Variance.INVARIANT) + ?: throw AssertionError( + "Failed to substitute value argument type in SAM conversion: " + + "underlyingParameterType=$underlyingParameterType, " + + "substitutionContext=$substitutionContext" + ) + val targetType = expectedArgumentType.toIrType() call.irValueArgumentsByIndex[i] = IrTypeOperatorCallImpl( @@ -440,7 +450,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca targetType, IrTypeOperator.SAM_CONVERSION, targetType, - castArgumentToFunctionalInterfaceForSamType(originalArgument, underlyingParameterType) + castArgumentToFunctionalInterfaceForSamType(originalArgument, expectedArgumentType) ) } } @@ -477,9 +487,12 @@ private fun unwrapSpecialDescriptor( samConversion: GeneratorExtensions.SamConversion ): CallableDescriptor = when (descriptor) { - is ImportedFromObjectCallableDescriptor<*> -> unwrapSpecialDescriptor(descriptor.callableFromObject, samConversion) - is TypeAliasConstructorDescriptor -> descriptor.underlyingConstructorDescriptor - else -> samConversion.getOriginalForSamAdapter(descriptor)?.let { unwrapSpecialDescriptor(it, samConversion) } ?: descriptor + is ImportedFromObjectCallableDescriptor<*> -> + unwrapSpecialDescriptor(descriptor.callableFromObject, samConversion) + is TypeAliasConstructorDescriptor -> + descriptor.underlyingConstructorDescriptor + else -> + samConversion.getOriginalForSamAdapter(descriptor)?.let { unwrapSpecialDescriptor(it, samConversion) } ?: descriptor } fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>, samConversion: GeneratorExtensions.SamConversion): CallBuilder { @@ -503,11 +516,11 @@ fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>, samC if (unsubstitutedUnwrappedTypeParameters.isEmpty()) null else - unsubstitutedUnwrappedTypeParameters.associate { + unsubstitutedUnwrappedTypeParameters.associateWith { val originalTypeParameter = candidateDescriptor.typeParameters[it.index] val originalTypeArgument = originalTypeArguments[originalTypeParameter] ?: throw AssertionError("No type argument for $originalTypeParameter") - it to originalTypeArgument + originalTypeArgument } } @@ -516,8 +529,8 @@ fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>, samC if (substitutedType.arguments.isEmpty()) null else - unsubstitutedUnwrappedTypeParameters.associate { - it to substitutedType.arguments[it.index].type + unsubstitutedUnwrappedTypeParameters.associateWith { + substitutedType.arguments[it.index].type } } @@ -547,5 +560,17 @@ fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>, samC } } - return CallBuilder(resolvedCall, unwrappedDescriptor, unwrappedTypeArguments) + val substitutedUnwrappedDescriptor = + if (unwrappedTypeArguments == null) + unwrappedDescriptor + else { + val substitutionContext = unsubstitutedUnwrappedDescriptor.typeParameters.associate { + val typeArgument = unwrappedTypeArguments[it] + ?: throw AssertionError("No type argument for $it in $unwrappedTypeArguments") + it.typeConstructor to TypeProjectionImpl(typeArgument) + } + unwrappedDescriptor.substitute(TypeSubstitutor.create(substitutionContext)) + } + + return CallBuilder(resolvedCall, substitutedUnwrappedDescriptor, unwrappedTypeArguments) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt index 3671bce894f..b18a3a93b8e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType open class GeneratorExtensions { open val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? @@ -26,8 +27,8 @@ open class GeneratorExtensions { open fun isSamType(type: KotlinType): Boolean = false - open fun getFunctionTypeForSAMClass(descriptor: ClassDescriptor): KotlinType = - throw UnsupportedOperationException("SAM conversion is not supported in this configuration (class=$descriptor)") + open fun getSubstitutedFunctionTypeForSamType(samType: KotlinType): KotlinType = + throw UnsupportedOperationException("SAM conversion is not supported in this configuration (samType=$samType)") companion object Instance : SamConversion() } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 24d45749dc4..9896f67340c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.psi2ir.transformations import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrClass @@ -32,7 +31,6 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded -import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext @@ -181,9 +179,7 @@ open class InsertImplicitCasts( override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression = when (expression.operator) { IrTypeOperator.SAM_CONVERSION -> expression.transformPostfix { - val targetClassDescriptor = typeOperandClassifier.descriptor as? ClassDescriptor - ?: throw AssertionError("Target type of $operator should be a class: ${render()}") - argument = argument.cast(samConversion.getFunctionTypeForSAMClass(targetClassDescriptor)) + argument = argument.cast(samConversion.getSubstitutedFunctionTypeForSamType(typeOperand.originalKotlinType!!)) } IrTypeOperator.IMPLICIT_CAST -> { diff --git a/compiler/testData/codegen/boxAgainstJava/sam/kt11519Constructor.kt b/compiler/testData/codegen/boxAgainstJava/sam/kt11519Constructor.kt index 98ea745dc3c..f1139009d1c 100644 --- a/compiler/testData/codegen/boxAgainstJava/sam/kt11519Constructor.kt +++ b/compiler/testData/codegen/boxAgainstJava/sam/kt11519Constructor.kt @@ -1,5 +1,4 @@ // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // FILE: Custom.java class Custom { diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt new file mode 100644 index 00000000000..36b58dca825 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt @@ -0,0 +1,9 @@ +FILE fqName: fileName:/samByProjectedType.kt + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public open fun bar (j: .J<*>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + j: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Any + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + GET_VAR 'x: kotlin.Any declared in .test1.' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt new file mode 100644 index 00000000000..e258f23d999 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt @@ -0,0 +1,14 @@ +// FILE: samByProjectedType.kt +fun test1() { + H.bar { x: Any -> x } +} + +// FILE: J.java +public interface J { + T foo(T x); +} + +// FILE: H.java +public class H { + public static void bar(J j) {} +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.txt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.txt new file mode 100644 index 00000000000..32042ee7462 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.txt @@ -0,0 +1,11 @@ +FILE fqName: fileName:/samByProjectedType.kt + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public open fun bar (j: .J<*>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + j: TYPE_OP type=.J<*>? origin=SAM_CONVERSION typeOperand=.J<*>? + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Any + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (x: kotlin.Any): kotlin.Any declared in .test1' + GET_VAR 'x: kotlin.Any declared in .test1.' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConstructors.txt b/compiler/testData/ir/irText/expressions/sam/samConstructors.txt index aaf50bbc85a..97cc540cde4 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConstructors.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConstructors.txt @@ -25,13 +25,12 @@ FILE fqName: fileName:/samConstructors.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun test4 (): java.util.Comparator declared in ' TYPE_OP type=java.util.Comparator origin=SAM_CONVERSION typeOperand=java.util.Comparator - TYPE_OP type=kotlin.Function2 origin=IMPLICIT_CAST typeOperand=kotlin.Function2 - FUN_EXPR type=kotlin.Function2 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (a:kotlin.Int?, b:kotlin.Int?) returnType:kotlin.Int - VALUE_PARAMETER name:a index:0 type:kotlin.Int? - VALUE_PARAMETER name:b index:1 type:kotlin.Int? - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (a: kotlin.Int?, b: kotlin.Int?): kotlin.Int declared in .test4' - CALL 'public final fun minus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=MINUS - $this: GET_VAR 'a: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null - other: GET_VAR 'b: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null + FUN_EXPR type=kotlin.Function2 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (a:kotlin.Int?, b:kotlin.Int?) returnType:kotlin.Int + VALUE_PARAMETER name:a index:0 type:kotlin.Int? + VALUE_PARAMETER name:b index:1 type:kotlin.Int? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (a: kotlin.Int?, b: kotlin.Int?): kotlin.Int declared in .test4' + CALL 'public final fun minus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=MINUS + $this: GET_VAR 'a: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null + other: GET_VAR 'b: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.fir.txt new file mode 100644 index 00000000000..3f491c508fe --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.fir.txt @@ -0,0 +1,14 @@ +FILE fqName: fileName:/samConversionInGenericConstructorCall.kt + FUN name:test1 visibility:public modality:FINAL <> (f:kotlin.Function1) returnType:IrErrorType + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test1 (f: kotlin.Function1): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'f: kotlin.Function1 declared in .test1' type=kotlin.Function1 origin=null + FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'x: kotlin.Any declared in .test2' type=kotlin.Any origin=null + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'x: kotlin.Any declared in .test2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt new file mode 100644 index 00000000000..8c962812920 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +SamConversionPerArgument +// FILE: samConversionInGenericConstructorCall.kt +fun test1(f: (String) -> String) = C(f) + +fun test2(x: Any) { + x as (String) -> String + C(x) +} + +// FILE: J.java +public interface J { + T1 foo(T2 x); +} + +// FILE: C.java +public class C { + public C(J jxx) {} +} + diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt new file mode 100644 index 00000000000..7cfb1fc72df --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt @@ -0,0 +1,20 @@ +FILE fqName: fileName:/samConversionInGenericConstructorCall.kt + FUN name:test1 visibility:public modality:FINAL <> (f:kotlin.Function1) returnType:.C + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test1 (f: kotlin.Function1): .C declared in ' + CONSTRUCTOR_CALL 'public constructor (jxx: .J.C?, X of .C?>?) declared in .C' type=.C origin=null + : kotlin.String + jxx: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'f: kotlin.Function1 declared in .test1' type=kotlin.Function1 origin=null + FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'x: kotlin.Any declared in .test2' type=kotlin.Any origin=null + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + CONSTRUCTOR_CALL 'public constructor (jxx: .J.C?, X of .C?>?) declared in .C' type=.C origin=null + : kotlin.String + jxx: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'x: kotlin.Any declared in .test2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.fir.txt new file mode 100644 index 00000000000..5caa99e6086 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.fir.txt @@ -0,0 +1,92 @@ +FILE fqName: fileName:/samConversionInGenericConstructorCall_NI.kt + FUN name:test3 visibility:public modality:FINAL <> (f1:kotlin.Function1, f2:kotlin.Function1) returnType:IrErrorType + VALUE_PARAMETER name:f1 index:0 type:kotlin.Function1 + VALUE_PARAMETER name:f2 index:1 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test3 (f1: kotlin.Function1, f2: kotlin.Function1): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'f2: kotlin.Function1 declared in .test3' type=kotlin.Function1 origin=null + CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Outer + TYPE_PARAMETER name:T1 index:0 variance: superTypes:[] + CONSTRUCTOR visibility:public <> (j11:.J, T1 of >) returnType:.Outer> [primary] + VALUE_PARAMETER name:j11 index:0 type:.J, T1 of > + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:j11 visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:j11 type:.J.Outer, T1 of .Outer> visibility:public [final] + EXPRESSION_BODY + GET_VAR 'j11: .J, T1 of > declared in .Outer.' type=.J, T1 of > origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Outer) returnType:.J.Outer, T1 of .Outer> + correspondingProperty: PROPERTY name:j11 visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Outer + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .J.Outer, T1 of .Outer> declared in .Outer' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j11 type:.J.Outer, T1 of .Outer> visibility:public [final]' type=.J.Outer, T1 of .Outer> origin=null + receiver: GET_VAR ': .Outer declared in .Outer.' type=.Outer origin=null + CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Outer.Inner + TYPE_PARAMETER name:T2 index:0 variance: superTypes:[] + CONSTRUCTOR visibility:public <> (j12:.J.Outer, T2 of >) returnType:.Outer.Inner> [primary] + VALUE_PARAMETER name:j12 index:0 type:.J.Outer, T2 of > + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]' + PROPERTY name:j12 visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:j12 type:.J.Outer, T2 of .Outer.Inner> visibility:public [final] + EXPRESSION_BODY + GET_VAR 'j12: .J.Outer, T2 of > declared in .Outer.Inner.' type=.J.Outer, T2 of > origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Outer.Inner) returnType:.J.Outer, T2 of .Outer.Inner> + correspondingProperty: PROPERTY name:j12 visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Outer.Inner + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .J.Outer, T2 of .Outer.Inner> declared in .Outer.Inner' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j12 type:.J.Outer, T2 of .Outer.Inner> visibility:public [final]' type=.J.Outer, T2 of .Outer.Inner> origin=null + receiver: GET_VAR ': .Outer.Inner declared in .Outer.Inner.' type=.Outer.Inner origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test4 visibility:public modality:FINAL <> (f:kotlin.Function1, g:kotlin.Function1) returnType:IrErrorType + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + VALUE_PARAMETER name:g index:1 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test4 (f: kotlin.Function1, g: kotlin.Function1): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'g: kotlin.Function1 declared in .test4' type=kotlin.Function1 origin=null + FUN name:testGenericJavaCtor1 visibility:public modality:FINAL <> (f:kotlin.Function1) returnType:IrErrorType + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun testGenericJavaCtor1 (f: kotlin.Function1): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'f: kotlin.Function1 declared in .testGenericJavaCtor1' type=kotlin.Function1 origin=null + FUN name:testGenericJavaCtor2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'x: kotlin.Any declared in .testGenericJavaCtor2' type=kotlin.Any origin=null + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'x: kotlin.Any declared in .testGenericJavaCtor2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt new file mode 100644 index 00000000000..8709be42577 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +NewInference +SamConversionPerArgument +SamConversionForKotlinFunctions +// FILE: samConversionInGenericConstructorCall_NI.kt +fun test3( + f1: (String) -> String, + f2: (Int) -> String +) = + C(f1).D(f2) + +class Outer(val j11: J) { + inner class Inner(val j12: J) +} + +fun test4(f: (String) -> String, g: (Any) -> String) = Outer(f).Inner(g) + +fun testGenericJavaCtor1(f: (String) -> Int) = G(f) + +fun testGenericJavaCtor2(x: Any) { + x as (String) -> Int + G(x) +} + +// FILE: J.java +public interface J { + T1 foo(T2 x); +} + +// FILE: C.java +public class C { + public C(J jxx) {} + + public class D { + public D(J jxy) {} + } +} + +// FILE: G.java +public class G { + public G(J x) {} +} diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt new file mode 100644 index 00000000000..91741e44c2b --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt @@ -0,0 +1,113 @@ +FILE fqName: fileName:/samConversionInGenericConstructorCall_NI.kt + FUN name:test3 visibility:public modality:FINAL <> (f1:kotlin.Function1, f2:kotlin.Function1) returnType:.C.D + VALUE_PARAMETER name:f1 index:0 type:kotlin.Function1 + VALUE_PARAMETER name:f2 index:1 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test3 (f1: kotlin.Function1, f2: kotlin.Function1): .C.D declared in ' + CONSTRUCTOR_CALL 'public constructor (jxy: .J.C?, Y of .C.D?>?) declared in .C.D' type=.C.D origin=null + : kotlin.Int + $outer: CONSTRUCTOR_CALL 'public constructor (jxx: .J.C?, X of .C?>?) declared in .C' type=.C origin=null + : kotlin.String + jxx: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'f1: kotlin.Function1 declared in .test3' type=kotlin.Function1 origin=null + jxy: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'f2: kotlin.Function1 declared in .test3' type=kotlin.Function1 origin=null + CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Outer.Outer> + TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> (j11:.J.Outer, T1 of .Outer>) returnType:.Outer.Outer> [primary] + VALUE_PARAMETER name:j11 index:0 type:.J.Outer, T1 of .Outer> + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:j11 visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:j11 type:.J.Outer, T1 of .Outer> visibility:public [final] + EXPRESSION_BODY + GET_VAR 'j11: .J.Outer, T1 of .Outer> declared in .Outer.' type=.J.Outer, T1 of .Outer> origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Outer.Outer>) returnType:.J.Outer, T1 of .Outer> + correspondingProperty: PROPERTY name:j11 visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Outer.Outer> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .J.Outer, T1 of .Outer> declared in .Outer' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j11 type:.J.Outer, T1 of .Outer> visibility:public [final]' type=.J.Outer, T1 of .Outer> origin=null + receiver: GET_VAR ': .Outer.Outer> declared in .Outer.' type=.Outer.Outer> origin=null + CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Outer.Inner.Outer.Inner, T1 of .Outer> + TYPE_PARAMETER name:T2 index:0 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> ($this:.Outer.Outer>, j12:.J.Outer, T2 of .Outer.Inner>) returnType:.Outer.Inner.Outer.Inner, T1 of .Outer> [primary] + $outer: VALUE_PARAMETER name: type:.Outer.Outer> + VALUE_PARAMETER name:j12 index:0 type:.J.Outer, T2 of .Outer.Inner> + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]' + PROPERTY name:j12 visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:j12 type:.J.Outer, T2 of .Outer.Inner> visibility:public [final] + EXPRESSION_BODY + GET_VAR 'j12: .J.Outer, T2 of .Outer.Inner> declared in .Outer.Inner.' type=.J.Outer, T2 of .Outer.Inner> origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Outer.Inner.Outer.Inner, T1 of .Outer>) returnType:.J.Outer, T2 of .Outer.Inner> + correspondingProperty: PROPERTY name:j12 visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Outer.Inner.Outer.Inner, T1 of .Outer> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .J.Outer, T2 of .Outer.Inner> declared in .Outer.Inner' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j12 type:.J.Outer, T2 of .Outer.Inner> visibility:public [final]' type=.J.Outer, T2 of .Outer.Inner> origin=null + receiver: GET_VAR ': .Outer.Inner.Outer.Inner, T1 of .Outer> declared in .Outer.Inner.' type=.Outer.Inner.Outer.Inner, T1 of .Outer> origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test4 visibility:public modality:FINAL <> (f:kotlin.Function1, g:kotlin.Function1) returnType:.Outer.Inner + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + VALUE_PARAMETER name:g index:1 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test4 (f: kotlin.Function1, g: kotlin.Function1): .Outer.Inner declared in ' + CONSTRUCTOR_CALL 'public constructor (j12: .J.Outer, T2 of .Outer.Inner>) [primary] declared in .Outer.Inner' type=.Outer.Inner origin=null + : kotlin.Any + $outer: CONSTRUCTOR_CALL 'public constructor (j11: .J.Outer, T1 of .Outer>) [primary] declared in .Outer' type=.Outer origin=null + : kotlin.String + j11: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'f: kotlin.Function1 declared in .test4' type=kotlin.Function1 origin=null + j12: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'g: kotlin.Function1 declared in .test4' type=kotlin.Function1 origin=null + FUN name:testGenericJavaCtor1 visibility:public modality:FINAL <> (f:kotlin.Function1) returnType:.G + VALUE_PARAMETER name:f index:0 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun testGenericJavaCtor1 (f: kotlin.Function1): .G declared in ' + CONSTRUCTOR_CALL 'public constructor (x: .J.G.?, TClass of .G?>?) declared in .G' type=.G origin=null + : kotlin.String + : kotlin.Int + x: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'f: kotlin.Function1 declared in .testGenericJavaCtor1' type=kotlin.Function1 origin=null + FUN name:testGenericJavaCtor2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'x: kotlin.Any declared in .testGenericJavaCtor2' type=kotlin.Any origin=null + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + CONSTRUCTOR_CALL 'public constructor (x: .J.G.?, TClass of .G?>?) declared in .G' type=.G origin=null + : kotlin.String + : kotlin.Int + x: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'x: kotlin.Any declared in .testGenericJavaCtor2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt new file mode 100644 index 00000000000..6ecaed79991 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt @@ -0,0 +1,72 @@ +FILE fqName: fileName:/samConversionToGeneric.kt + FUN name:test1 visibility:public modality:FINAL <> () returnType:IrErrorType + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test1 (): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + FUN_EXPR type=IrErrorType origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:IrErrorType) returnType:IrErrorType + VALUE_PARAMETER name:x index:0 type:IrErrorType + BLOCK_BODY + ERROR_CALL 'Unresolved reference: x#' type=IrErrorType + FUN name:test2 visibility:public modality:FINAL <> () returnType:IrErrorType + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test2 (): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + FUN_EXPR type=IrErrorType origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:IrErrorType + VALUE_PARAMETER name:x index:0 type:kotlin.String + BLOCK_BODY + ERROR_CALL 'Unresolved reference: x#' type=IrErrorType + FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test3 (): kotlin.Unit declared in ' + CALL 'public open fun bar (j: .J?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + j: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:kotlin.String + VALUE_PARAMETER name:x index:0 type:kotlin.String + BLOCK_BODY + GET_VAR 'x: kotlin.String declared in .test3.' type=kotlin.String origin=null + FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=.J origin=CAST typeOperand=.J + GET_VAR 'a: kotlin.Any declared in .test4' type=kotlin.Any origin=null + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'a: kotlin.Any declared in .test4' type=kotlin.Any origin=null + FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + FUN name:test6 visibility:public modality:FINAL (a:kotlin.Function1.test6, T of .test6>) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[] + VALUE_PARAMETER name:a index:0 type:kotlin.Function1.test6, T of .test6> + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'a: kotlin.Function1.test6, T of .test6> declared in .test6' type=kotlin.Function1.test6, T of .test6> origin=null + FUN name:test7 visibility:public modality:FINAL (a:kotlin.Any) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[] + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Function1.test7, T of .test7> origin=CAST typeOperand=kotlin.Function1.test7, T of .test7> + GET_VAR 'a: kotlin.Any declared in .test7' type=kotlin.Any origin=null + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'a: kotlin.Any declared in .test7' type=kotlin.Any origin=null + FUN name:test8 visibility:public modality:FINAL <> (efn:kotlin.Function1) returnType:IrErrorType + VALUE_PARAMETER name:efn index:0 type:kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test8 (efn: kotlin.Function1): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'efn: kotlin.Function1 declared in .test8' type=kotlin.Function1 origin=null + FUN name:test9 visibility:public modality:FINAL <> (efn:kotlin.Function1) returnType:kotlin.Unit + VALUE_PARAMETER name:efn index:0 type:kotlin.Function1 + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'efn: kotlin.Function1 declared in .test9' type=kotlin.Function1 origin=null + FUN name:test10 visibility:public modality:FINAL <> (fn:kotlin.Function1) returnType:kotlin.Unit + VALUE_PARAMETER name:fn index:0 type:kotlin.Function1 + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + GET_VAR 'fn: kotlin.Function1 declared in .test10' type=kotlin.Function1 origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt new file mode 100644 index 00000000000..2909c9366dc --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt @@ -0,0 +1,56 @@ +// FILE: samConversionToGeneric.kt + +fun test1() = J { x -> x } + +fun test2() = J { x: String -> x } + +fun test3() = H.bar { x: String -> x } + +fun test4(a: Any) { + a as J + H.bar(a) +} + +fun test5(a: Any) { + a as (String) -> String + H.bar(a) +} + +fun test6(a: (T) -> T) { + H.bar(a) +} + +fun test7(a: Any) { + a as (T) -> T + H.bar(a) +} + +fun test8(efn: String.() -> String) = J(efn) + +fun test9(efn: String.() -> String) { + H.bar(efn) +} + +fun test10(fn: (Int) -> String) { + H.bar2x(fn) +} + +// FILE: J.java +public interface J { + T foo(T x); +} + +// FILE: J2.java +public interface J2 { + T1 foo(T2 x); +} + +// FILE: J2X.java +public interface J2X extends J2 { +} + +// FILE: H.java +public class H { + public static void bar(J j) {} + public static void bar2x(J2X j2x) {} +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt new file mode 100644 index 00000000000..cb4449b1883 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt @@ -0,0 +1,94 @@ +FILE fqName: fileName:/samConversionToGeneric.kt + FUN name:test1 visibility:public modality:FINAL <> () returnType:.J + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test1 (): .J declared in ' + TYPE_OP type=.J origin=SAM_CONVERSION typeOperand=.J + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String?) returnType:kotlin.String? + VALUE_PARAMETER name:x index:0 type:kotlin.String? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (x: kotlin.String?): kotlin.String? declared in .test1' + GET_VAR 'x: kotlin.String? declared in .test1.' type=kotlin.String? origin=null + FUN name:test2 visibility:public modality:FINAL <> () returnType:.J + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test2 (): .J declared in ' + TYPE_OP type=.J origin=SAM_CONVERSION typeOperand=.J + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:kotlin.String + VALUE_PARAMETER name:x index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (x: kotlin.String): kotlin.String declared in .test2' + GET_VAR 'x: kotlin.String declared in .test2.' type=kotlin.String origin=null + FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test3 (): kotlin.Unit declared in ' + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : kotlin.String? + j: TYPE_OP type=.J? origin=SAM_CONVERSION typeOperand=.J? + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:kotlin.String + VALUE_PARAMETER name:x index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (x: kotlin.String): kotlin.String declared in .test3' + GET_VAR 'x: kotlin.String declared in .test3.' type=kotlin.String origin=null + FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=.J origin=CAST typeOperand=.J + GET_VAR 'a: kotlin.Any declared in .test4' type=kotlin.Any origin=null + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : kotlin.String? + j: TYPE_OP type=.J origin=IMPLICIT_CAST typeOperand=.J + GET_VAR 'a: kotlin.Any declared in .test4' type=kotlin.Any origin=null + FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function1 origin=CAST typeOperand=kotlin.Function1 + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : kotlin.String? + j: TYPE_OP type=.J? origin=SAM_CONVERSION typeOperand=.J? + TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.String?> + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + FUN name:test6 visibility:public modality:FINAL (a:kotlin.Function1.test6, T of .test6>) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:a index:0 type:kotlin.Function1.test6, T of .test6> + BLOCK_BODY + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : T of .test6? + j: TYPE_OP type=.J.test6?>? origin=SAM_CONVERSION typeOperand=.J.test6?>? + GET_VAR 'a: kotlin.Function1.test6, T of .test6> declared in .test6' type=kotlin.Function1.test6, T of .test6> origin=null + FUN name:test7 visibility:public modality:FINAL (a:kotlin.Any) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function1.test7, T of .test7> origin=CAST typeOperand=kotlin.Function1.test7, T of .test7> + GET_VAR 'a: kotlin.Any declared in .test7' type=kotlin.Any origin=null + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : T of .test7? + j: TYPE_OP type=.J.test7?>? origin=SAM_CONVERSION typeOperand=.J.test7?>? + TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] T of .test7?, T of .test7?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] T of .test7?, T of .test7?> + GET_VAR 'a: kotlin.Any declared in .test7' type=kotlin.Any origin=null + FUN name:test8 visibility:public modality:FINAL <> (efn:@[ExtensionFunctionType] kotlin.Function1) returnType:.J + VALUE_PARAMETER name:efn index:0 type:@[ExtensionFunctionType] kotlin.Function1 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test8 (efn: @[ExtensionFunctionType] kotlin.Function1): .J declared in ' + TYPE_OP type=.J origin=SAM_CONVERSION typeOperand=.J + GET_VAR 'efn: @[ExtensionFunctionType] kotlin.Function1 declared in .test8' type=@[ExtensionFunctionType] kotlin.Function1 origin=null + FUN name:test9 visibility:public modality:FINAL <> (efn:@[ExtensionFunctionType] kotlin.Function1) returnType:kotlin.Unit + VALUE_PARAMETER name:efn index:0 type:@[ExtensionFunctionType] kotlin.Function1 + BLOCK_BODY + CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : kotlin.String? + j: TYPE_OP type=.J? origin=SAM_CONVERSION typeOperand=.J? + GET_VAR 'efn: @[ExtensionFunctionType] kotlin.Function1 declared in .test9' type=@[ExtensionFunctionType] kotlin.Function1 origin=null + FUN name:test10 visibility:public modality:FINAL <> (fn:kotlin.Function1) returnType:kotlin.Unit + VALUE_PARAMETER name:fn index:0 type:kotlin.Function1 + BLOCK_BODY + CALL 'public open fun bar2x (j2x: .J2X.H.bar2x?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null + : kotlin.Int? + j2x: TYPE_OP type=.J2X? origin=SAM_CONVERSION typeOperand=.J2X? + GET_VAR 'fn: kotlin.Function1 declared in .test10' type=kotlin.Function1 origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 630dc2fa669..5892384d248 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1367,11 +1367,31 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/expressions/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("samByProjectedType.kt") + public void testSamByProjectedType() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt"); + } + @TestMetadata("samConstructors.kt") public void testSamConstructors() throws Exception { runTest("compiler/testData/ir/irText/expressions/sam/samConstructors.kt"); } + @TestMetadata("samConversionInGenericConstructorCall.kt") + public void testSamConversionInGenericConstructorCall() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt"); + } + + @TestMetadata("samConversionInGenericConstructorCall_NI.kt") + public void testSamConversionInGenericConstructorCall_NI() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt"); + } + + @TestMetadata("samConversionToGeneric.kt") + public void testSamConversionToGeneric() throws Exception { + runTest("compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt"); + } + @TestMetadata("samConversions.kt") public void testSamConversions() throws Exception { runTest("compiler/testData/ir/irText/expressions/sam/samConversions.kt");