Support SAM conversion in psi2ir
SAM conversion takes a function value (function type or a subtype), and produces a SAM interface value.
This commit is contained in:
+4
-3
@@ -19,13 +19,13 @@ package org.jetbrains.kotlin.backend.common
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.util.superTypes
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -166,7 +166,8 @@ class CheckIrElementVisitor(
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand.toKotlinType()
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION,
|
||||
IrTypeOperator.SAM_CONVERSION -> typeOperand.toKotlinType()
|
||||
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable().toKotlinType()
|
||||
|
||||
|
||||
+2
-4
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.isNullable
|
||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
|
||||
class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
@@ -80,6 +77,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
IrTypeOperator.NOT_INSTANCEOF -> lowerInstanceOf(expression, data, true)
|
||||
IrTypeOperator.CAST -> lowerCast(expression, data, false)
|
||||
IrTypeOperator.SAFE_CAST -> lowerCast(expression, data, true)
|
||||
IrTypeOperator.SAM_CONVERSION -> TODO("SAM conversion: ${expression.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -832,7 +832,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION,
|
||||
IrTypeOperator.SAM_CONVERSION -> type
|
||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
||||
IrTypeOperator.INSTANCEOF,
|
||||
IrTypeOperator.NOT_INSTANCEOF -> context.irBuiltIns.booleanType
|
||||
|
||||
+66
-8
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
@@ -24,7 +25,11 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
@@ -37,6 +42,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpressio
|
||||
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.synthetic.SamAdapterExtensionFunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
@@ -158,13 +164,15 @@ fun StatementGenerator.generateCallReceiver(
|
||||
): CallReceiver {
|
||||
val dispatchReceiverValue: IntermediateValue?
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
val startOffset = ktDefaultElement.startOffsetSkippingComments
|
||||
val endOffset = ktDefaultElement.endOffset
|
||||
when (calleeDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> -> {
|
||||
assert(dispatchReceiver == null) {
|
||||
"Call for member imported from object $calleeDescriptor has non-null dispatch receiver $dispatchReceiver"
|
||||
}
|
||||
dispatchReceiverValue =
|
||||
generateReceiverForCalleeImportedFromObject(ktDefaultElement.startOffsetSkippingComments, ktDefaultElement.endOffset, calleeDescriptor)
|
||||
generateReceiverForCalleeImportedFromObject(startOffset, endOffset, calleeDescriptor)
|
||||
extensionReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver)
|
||||
}
|
||||
is TypeAliasConstructorDescriptor -> {
|
||||
@@ -186,7 +194,7 @@ fun StatementGenerator.generateCallReceiver(
|
||||
SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
|
||||
extensionReceiverValue != null || dispatchReceiverValue != null ->
|
||||
SafeCallReceiver(
|
||||
this, ktDefaultElement.startOffsetSkippingComments, ktDefaultElement.endOffset,
|
||||
this, startOffset, endOffset,
|
||||
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver
|
||||
)
|
||||
else ->
|
||||
@@ -250,7 +258,7 @@ fun StatementGenerator.generateVarargExpressionUsing(
|
||||
return irVararg
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateValueArgument(
|
||||
fun StatementGenerator.generateValueArgument(
|
||||
valueArgument: ResolvedValueArgument,
|
||||
valueParameter: ValueParameterDescriptor
|
||||
) = generateValueArgumentUsing(valueArgument, valueParameter) { generateExpression(it) }
|
||||
@@ -369,6 +377,51 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
|
||||
pregenerateValueArgumentsUsing(call, resolvedCall) {
|
||||
generateExpression(it)
|
||||
}
|
||||
|
||||
generateSamConversionForValueArgumentsIfRequired(call, resolvedCall.resultingDescriptor)
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: CallBuilder, originalDescriptor: CallableDescriptor) {
|
||||
val underlyingDescriptor = when (originalDescriptor) {
|
||||
is SamAdapterDescriptor<*> -> originalDescriptor.baseDescriptorForSynthetic
|
||||
is SamAdapterExtensionFunctionDescriptor -> originalDescriptor.baseDescriptorForSynthetic
|
||||
else -> return
|
||||
}
|
||||
|
||||
val originalValueParameters = originalDescriptor.valueParameters
|
||||
val underlyingValueParameters = underlyingDescriptor.valueParameters
|
||||
|
||||
assert(originalValueParameters.size == underlyingValueParameters.size) {
|
||||
"Mismatching value parameters, $originalDescriptor vs $underlyingDescriptor: " +
|
||||
"${originalValueParameters.size} != ${underlyingValueParameters.size}"
|
||||
}
|
||||
assert(originalValueParameters.size == call.argumentsCount) {
|
||||
"Mismatching value parameters, $originalDescriptor vs call: " +
|
||||
"${originalValueParameters.size} != ${call.argumentsCount}"
|
||||
}
|
||||
|
||||
for (i in underlyingValueParameters.indices) {
|
||||
val originalParameterType = originalValueParameters[i].type
|
||||
val underlyingParameterType = underlyingValueParameters[i].type
|
||||
|
||||
if (!SingleAbstractMethodUtils.isSamType(underlyingParameterType)) continue
|
||||
if (!originalParameterType.isFunctionTypeOrSubtype) continue
|
||||
|
||||
val originalArgument = call.irValueArgumentsByIndex[i] ?: continue
|
||||
|
||||
val targetType = underlyingParameterType.toIrType()
|
||||
val targetClassifier = targetType.classifierOrFail
|
||||
|
||||
call.irValueArgumentsByIndex[i] =
|
||||
IrTypeOperatorCallImpl(
|
||||
originalArgument.startOffset, originalArgument.endOffset,
|
||||
targetType,
|
||||
IrTypeOperator.SAM_CONVERSION,
|
||||
targetType,
|
||||
targetClassifier,
|
||||
originalArgument
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun StatementGenerator.pregenerateValueArgumentsUsing(
|
||||
@@ -398,15 +451,20 @@ fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>):
|
||||
return call
|
||||
}
|
||||
|
||||
private fun unwrapSpecialDescriptor(originalDescriptor: CallableDescriptor): CallableDescriptor =
|
||||
when (originalDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> -> unwrapSpecialDescriptor(originalDescriptor.callableFromObject)
|
||||
is TypeAliasConstructorDescriptor -> originalDescriptor.underlyingConstructorDescriptor
|
||||
is SamAdapterDescriptor<*> -> unwrapSpecialDescriptor(originalDescriptor.baseDescriptorForSynthetic)
|
||||
is SamAdapterExtensionFunctionDescriptor -> unwrapSpecialDescriptor(originalDescriptor.baseDescriptorForSynthetic)
|
||||
else -> originalDescriptor
|
||||
}
|
||||
|
||||
fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val originalDescriptor = resolvedCall.resultingDescriptor
|
||||
val candidateDescriptor = resolvedCall.candidateDescriptor
|
||||
|
||||
val unwrappedDescriptor = when (originalDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> -> originalDescriptor.callableFromObject
|
||||
is TypeAliasConstructorDescriptor -> originalDescriptor.underlyingConstructorDescriptor
|
||||
else -> originalDescriptor
|
||||
}
|
||||
val unwrappedDescriptor = unwrapSpecialDescriptor(originalDescriptor)
|
||||
|
||||
val originalTypeArguments = resolvedCall.typeArguments
|
||||
val unsubstitutedUnwrappedDescriptor = unwrappedDescriptor.original
|
||||
|
||||
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||
@@ -40,6 +42,8 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
val descriptor = call.descriptor
|
||||
|
||||
return when (descriptor) {
|
||||
is SamConstructorDescriptor ->
|
||||
generateSamConstructorCall(descriptor, startOffset, endOffset, call)
|
||||
is PropertyDescriptor ->
|
||||
generatePropertyGetterCall(descriptor, startOffset, endOffset, call)
|
||||
is FunctionDescriptor ->
|
||||
@@ -51,6 +55,24 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateSamConstructorCall(
|
||||
descriptor: SamConstructorDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder
|
||||
): IrExpression {
|
||||
val targetType = descriptor.returnType!!.toIrType()
|
||||
|
||||
return IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset,
|
||||
targetType,
|
||||
IrTypeOperator.SAM_CONVERSION,
|
||||
targetType,
|
||||
targetType.classifierOrFail,
|
||||
call.irValueArgumentsByIndex[0]!!
|
||||
)
|
||||
}
|
||||
|
||||
fun generateValueReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
+23
@@ -30,7 +30,10 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -167,6 +170,26 @@ open class InsertImplicitCasts(
|
||||
finallyExpression = finallyExpression?.coerceToUnit()
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression =
|
||||
if (expression.operator == IrTypeOperator.SAM_CONVERSION)
|
||||
expression.coerceArgumentToFunctionalType()
|
||||
else
|
||||
super.visitTypeOperator(expression)
|
||||
|
||||
private fun IrTypeOperatorCall.coerceArgumentToFunctionalType(): IrExpression {
|
||||
val targetClassDescriptor = typeOperandClassifier.descriptor as? JavaClassDescriptor
|
||||
?: throw AssertionError("Target type of $operator should be a Java class: ${render()}")
|
||||
|
||||
val singleAbstractMethod = SingleAbstractMethodUtils.getSingleAbstractMethodOrNull(targetClassDescriptor)
|
||||
?: throw AssertionError("$targetClassDescriptor should have a single abstract method")
|
||||
|
||||
val functionalType = SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(singleAbstractMethod, false)
|
||||
|
||||
argument = argument.cast(functionalType)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitVararg(expression: IrVararg): IrExpression =
|
||||
expression.transformPostfix {
|
||||
elements.forEachIndexed { i, element ->
|
||||
|
||||
@@ -27,7 +27,8 @@ enum class IrTypeOperator {
|
||||
IMPLICIT_INTEGER_COERCION,
|
||||
SAFE_CAST,
|
||||
INSTANCEOF,
|
||||
NOT_INSTANCEOF;
|
||||
NOT_INSTANCEOF,
|
||||
SAM_CONVERSION;
|
||||
}
|
||||
|
||||
interface IrTypeOperatorCall : IrExpression {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// WITH_JDK
|
||||
fun test1() = Runnable { }
|
||||
|
||||
fun test2(a: () -> Unit) = Runnable(a)
|
||||
|
||||
fun foo() {}
|
||||
fun test3() = Runnable(::foo)
|
||||
@@ -0,0 +1,27 @@
|
||||
FILE fqName:<root> fileName:/samConstructors.kt
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:java.lang.Runnable flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='test1(): Runnable'
|
||||
TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
BLOCK type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<anonymous>(): Unit'
|
||||
GET_OBJECT 'Unit' type=kotlin.Unit
|
||||
FUNCTION_REFERENCE '<anonymous>(): Unit' type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:java.lang.Runnable flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='test2(() -> Unit): Runnable'
|
||||
TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
FUN name:test3 visibility:public modality:FINAL <> () returnType:java.lang.Runnable flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='test3(): Runnable'
|
||||
TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
FUNCTION_REFERENCE 'foo(): Unit' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null
|
||||
@@ -0,0 +1,31 @@
|
||||
// WITH_JDK
|
||||
// FILE: samConversions.kt
|
||||
fun J.test0(a: Runnable) {
|
||||
J.runStatic(a)
|
||||
runIt(a)
|
||||
}
|
||||
|
||||
fun test1() {
|
||||
J.runStatic { test1() }
|
||||
}
|
||||
|
||||
fun J.test2() {
|
||||
runIt { test1() }
|
||||
}
|
||||
|
||||
fun J.test3(a: () -> Unit) {
|
||||
run2(a, a)
|
||||
}
|
||||
|
||||
fun J.test4(a: () -> Unit, b: () -> Unit, flag: Boolean) {
|
||||
runIt(if (flag) a else b)
|
||||
}
|
||||
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public static void runStatic(Runnable r) {}
|
||||
|
||||
public void runIt(Runnable r) {}
|
||||
|
||||
public void run2(Runnable r1, Runnable r2) {}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
FILE fqName:<root> fileName:/samConversions.kt
|
||||
FUN name:test0 visibility:public modality:FINAL <> ($receiver:J, a:java.lang.Runnable) returnType:kotlin.Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:J flags:
|
||||
VALUE_PARAMETER name:a index:0 type:java.lang.Runnable flags:
|
||||
BLOCK_BODY
|
||||
CALL 'runStatic(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
r: GET_VAR 'value-parameter a: Runnable' type=java.lang.Runnable origin=null
|
||||
CALL 'runIt(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'this@test0: J' type=J origin=null
|
||||
r: GET_VAR 'value-parameter a: Runnable' type=java.lang.Runnable origin=null
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
CALL 'runStatic(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
BLOCK type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<anonymous>(): Unit'
|
||||
CALL 'test1(): Unit' type=kotlin.Unit origin=null
|
||||
FUNCTION_REFERENCE '<anonymous>(): Unit' type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN name:test2 visibility:public modality:FINAL <> ($receiver:J) returnType:kotlin.Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:J flags:
|
||||
BLOCK_BODY
|
||||
CALL 'runIt(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'this@test2: J' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
BLOCK type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<anonymous>(): Unit'
|
||||
CALL 'test1(): Unit' type=kotlin.Unit origin=null
|
||||
FUNCTION_REFERENCE '<anonymous>(): Unit' type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN name:test3 visibility:public modality:FINAL <> ($receiver:J, a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:J flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
CALL 'run2(Runnable!, Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'this@test3: J' type=J origin=null
|
||||
r1: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
r2: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test4 visibility:public modality:FINAL <> ($receiver:J, a:kotlin.Function0<kotlin.Unit>, b:kotlin.Function0<kotlin.Unit>, flag:kotlin.Boolean) returnType:kotlin.Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:J flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
VALUE_PARAMETER name:b index:1 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
VALUE_PARAMETER name:flag index:2 type:kotlin.Boolean flags:
|
||||
BLOCK_BODY
|
||||
CALL 'runIt(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'this@test4: J' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
WHEN type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
BRANCH
|
||||
if: GET_VAR 'value-parameter flag: Boolean' type=kotlin.Boolean origin=null
|
||||
then: GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: GET_VAR 'value-parameter b: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
@@ -0,0 +1,71 @@
|
||||
// !LANGUAGE: -NewInference
|
||||
// NB new inference doesn't really work with old JVM back-end.
|
||||
|
||||
// WITH_JDK
|
||||
// FILE: samConversionsWithSmartCasts.kt
|
||||
|
||||
fun test1(a: () -> Unit) {
|
||||
if (a is Runnable) {
|
||||
J.runStatic(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test2(a: () -> Unit) {
|
||||
if (a is Runnable) {
|
||||
J().run1(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3(a: () -> Unit) {
|
||||
if (a is Runnable) {
|
||||
J().run2(a, a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test4(a: () -> Unit, b: () -> Unit) {
|
||||
if (a is Runnable) {
|
||||
J().run2(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
fun test5(a: Any) {
|
||||
if (a is Runnable) {
|
||||
J().run1(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test5x(a: Any) {
|
||||
if (a is Runnable) {
|
||||
a as () -> Unit
|
||||
J().run1(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test6(a: Any) {
|
||||
a as () -> Unit
|
||||
J().run1(a)
|
||||
}
|
||||
|
||||
fun test7(a: (Int) -> Int) {
|
||||
a as () -> Unit
|
||||
J().run1(a)
|
||||
}
|
||||
|
||||
fun test8(a: () -> Unit) {
|
||||
J().run1(J.id(a))
|
||||
}
|
||||
|
||||
fun test9() {
|
||||
J().run1(::test9)
|
||||
}
|
||||
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public static void runStatic(Runnable r) {}
|
||||
|
||||
public void run1(Runnable r) {}
|
||||
|
||||
public void run2(Runnable r1, Runnable r2) {}
|
||||
|
||||
public static <T> T id(T x) { return x; }
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
FUN name:test1 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'runStatic(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'run2(Runnable!, Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r1: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
r2: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>, b:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
VALUE_PARAMETER name:b index:1 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'run2(Runnable!, Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r1: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
r2: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter b: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
FUN name:test5x visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any flags:
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=null
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags: superTypes:[kotlin.Any]
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Function0 modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Function<R>]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any flags:
|
||||
BLOCK_BODY
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags: superTypes:[kotlin.Any]
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Function0 modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Function<R>]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Function0 modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Function<R>]
|
||||
GET_VAR 'value-parameter a: Any' type=kotlin.Any origin=null
|
||||
FUN name:test7 visibility:public modality:FINAL <> (a:kotlin.Function1<kotlin.Int, kotlin.Int>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function1<kotlin.Int, kotlin.Int> flags:
|
||||
BLOCK_BODY
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags: superTypes:[kotlin.Any]
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Function0 modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Function<R>]
|
||||
GET_VAR 'value-parameter a: (Int) -> Int' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Function0 modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Function<R>]
|
||||
GET_VAR 'value-parameter a: (Int) -> Int' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
|
||||
FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit flags:
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit> flags:
|
||||
BLOCK_BODY
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
CALL 'id(T!): T!' type=kotlin.Function0<kotlin.Unit>? origin=null
|
||||
<T : Any!>: kotlin.Function0<kotlin.Unit>?
|
||||
x: GET_VAR 'value-parameter a: () -> Unit' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
CALL 'run1(Runnable!): Unit' type=kotlin.Unit origin=null
|
||||
$this: CALL 'constructor J()' type=J origin=null
|
||||
r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable?
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
FUNCTION_REFERENCE 'test9(): Unit' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null
|
||||
+3
-2
@@ -2,8 +2,9 @@ FILE fqName:<root> fileName:/samAdapter.kt
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
VAR name:hello type:java.lang.Runnable flags:val
|
||||
CALL 'Runnable(() -> Unit): Runnable' type=java.lang.Runnable origin=null
|
||||
function: BLOCK type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB INTERFACE name:Runnable modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any]
|
||||
BLOCK type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<anonymous>(): Unit'
|
||||
|
||||
@@ -1284,6 +1284,34 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
runTest("compiler/testData/ir/irText/expressions/floatingPointComparisons/whenByFloatingPoint.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/expressions/sam")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Sam extends AbstractIrTextTestCase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSam() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/expressions/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructors.kt")
|
||||
public void testSamConstructors() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/sam/samConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConversions.kt")
|
||||
public void testSamConversions() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/sam/samConversions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConversionsWithSmartCasts.kt")
|
||||
public void testSamConversionsWithSmartCasts() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
||||
|
||||
Reference in New Issue
Block a user