Fix casts of the null constant to SAM types

This commit is contained in:
pyos
2019-04-03 12:26:57 +02:00
committed by max-kammerer
parent f47d9d54c0
commit ee59530f71
@@ -71,15 +71,15 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow
// Not an exhaustive check, but enough to cover the most common cases.
if (invokable is IrFunctionReference) {
// Runnable(::function)
createFunctionProxyInstance(superType, invokable)
+createFunctionProxyInstance(superType, invokable)
} else if (invokable is IrBlock && invokable.statements.last() is IrFunctionReference) {
// Runnable { lambda }
for (statement in invokable.statements.dropLast(1))
+statement
createFunctionProxyInstance(superType, invokable.statements.last() as IrFunctionReference)
+createFunctionProxyInstance(superType, invokable.statements.last() as IrFunctionReference)
} else {
// Fall back to materializing an invokable object.
createObjectProxyInstance(superType, invokable)
+createObjectProxyInstance(superType, invokable)
}
}
}
@@ -166,16 +166,19 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow
}
}
private fun IrBlockBuilder.createObjectProxyInstance(superType: IrType, invokable: IrExpression) {
private fun IrBlockBuilder.createObjectProxyInstance(superType: IrType, invokable: IrExpression): IrExpression {
// Do not generate a wrapper class for null, it has no invoke() anyway.
if (invokable.isNullConst())
return invokable
val implementation = cachedImplementations.getOrPut(superType.toKotlinType() to invokable.type.toKotlinType()) {
createObjectProxy(superType, invokable.type)
}
if (superType.isNullable() && invokable.type.isNullable()) {
return if (superType.isNullable() && invokable.type.isNullable()) {
val invokableVariable = irTemporary(invokable)
val instance = irCall(implementation.constructors.single()).apply { putValueArgument(0, irGet(invokableVariable)) }
+irIfNull(superType, irGet(invokableVariable), irNull(), instance)
irIfNull(superType, irGet(invokableVariable), irNull(), instance)
} else {
+irCall(implementation.constructors.single()).apply { putValueArgument(0, invokable) }
irCall(implementation.constructors.single()).apply { putValueArgument(0, invokable) }
}
}
@@ -217,10 +220,10 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow
}
}
private fun IrBlockBuilder.createFunctionProxyInstance(superType: IrType, reference: IrFunctionReference) {
private fun IrBlockBuilder.createFunctionProxyInstance(superType: IrType, reference: IrFunctionReference): IrExpression {
val implementation = createFunctionProxy(superType, reference)
localImplementations += implementation
+irCall(implementation.constructors.single()).apply {
return irCall(implementation.constructors.single()).apply {
reference.arguments.filterNotNull().forEachIndexed(::putValueArgument)
}
}