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