Support anonymous function as inline parameters
This commit is contained in:
+21
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
@@ -12,9 +13,11 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.util.getArguments
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlineParameter
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -150,4 +153,20 @@ class IrExpressionLambdaImpl(
|
||||
}
|
||||
|
||||
fun isInlineIrExpression(argumentExpression: IrExpression) =
|
||||
argumentExpression is IrBlock && argumentExpression.origin == IrStatementOrigin.LAMBDA
|
||||
argumentExpression is IrBlock &&
|
||||
(argumentExpression.origin == IrStatementOrigin.LAMBDA || argumentExpression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
|
||||
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
|
||||
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) &&
|
||||
(isInline || isArrayConstructorWithLambda())
|
||||
|
||||
private fun IrFunction.isArrayConstructorWithLambda() =
|
||||
valueParameters.size == 2 &&
|
||||
this is IrConstructor &&
|
||||
parentAsClass.let {
|
||||
it.getPackageFragment()?.fqName?.asString() == "kotlin" &&
|
||||
it.name.asString().endsWith("Array")
|
||||
}
|
||||
|
||||
fun IrValueParameter.isInlineParameter() =
|
||||
!isNoinline && !type.isNullable() && type.isFunctionOrKFunction()
|
||||
+3
-17
@@ -28,7 +28,9 @@ import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineParameter
|
||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -83,7 +85,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val callee = expression.symbol.owner
|
||||
if (callee.isInlineFunction(context)) {
|
||||
if (callee.isInlineFunctionCall(context)) {
|
||||
//TODO: more wise filtering
|
||||
callee.valueParameters.forEach { valueParameter ->
|
||||
if (valueParameter.isInlineParameter()) {
|
||||
@@ -589,22 +591,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
}
|
||||
|
||||
// TODO: Move to IrUtils
|
||||
|
||||
private fun IrFunction.isInlineFunction(context: JvmBackendContext) =
|
||||
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) &&
|
||||
(isInline || isArrayConstructorWithLambda())
|
||||
|
||||
private fun IrFunction.isArrayConstructorWithLambda() =
|
||||
valueParameters.size == 2 &&
|
||||
this is IrConstructor &&
|
||||
parentAsClass.let {
|
||||
it.getPackageFragment()?.fqName?.asString() == "kotlin" &&
|
||||
it.name.asString().endsWith("Array")
|
||||
}
|
||||
|
||||
private fun IrValueParameter.isInlineParameter() =
|
||||
!isNoinline && !type.isNullable() && type.isFunctionOrKFunction()
|
||||
|
||||
private fun IrType.substitute(substitutionMap: Map<IrTypeParameter, IrType>): IrType {
|
||||
if (this !is IrSimpleType) return this
|
||||
|
||||
|
||||
+8
-4
@@ -8,12 +8,16 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineCall
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.util.isFunction
|
||||
import org.jetbrains.kotlin.ir.util.isNullable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -32,12 +36,12 @@ private class RemoveDeclarationsThatWouldBeInlinedLowering(val context: JvmBacke
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val owner = expression.symbol.owner
|
||||
if (expression.descriptor.isInlineCall(context.state)) {
|
||||
if (expression.symbol.owner.isInlineFunctionCall(context)) {
|
||||
owner.valueParameters.filter {
|
||||
!it.isNoinline && it.type.isFunction() && !it.type.isNullable()
|
||||
}.forEach {
|
||||
val valueArgument = expression.getValueArgument(it.index) as? IrContainerExpression ?: return@forEach
|
||||
if (valueArgument.origin == IrStatementOrigin.LAMBDA) {
|
||||
if (isInlineIrExpression(valueArgument)) {
|
||||
val reference =
|
||||
valueArgument.statements.firstIsInstanceOrNull<IrFunctionReference>() ?: return@forEach
|
||||
loweredLambdasToDelete.add(reference.symbol.owner)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
Reference in New Issue
Block a user