diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index bcc107c0543..962edb25bf2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -110,6 +110,8 @@ val jvmPhases = namedIrFilePhase( jvmBuiltinOptimizationLoweringPhase then additionalClassAnnotationPhase then + // should be last transformation + removeDeclarationsThatWouldBeInlined then makePatchParentsPhase(3) ) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/RemoveDeclarationsThatWouldBeInlinedLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/RemoveDeclarationsThatWouldBeInlinedLowering.kt new file mode 100644 index 00000000000..9067109ec48 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/RemoveDeclarationsThatWouldBeInlinedLowering.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +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.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.util.isFunction +import org.jetbrains.kotlin.ir.util.isNullable +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +internal val removeDeclarationsThatWouldBeInlined = makeIrFilePhase( + ::RemoveDeclarationsThatWouldBeInlinedLowering, + name = "RemoveInlinedDeclarations", + description = "Rename declaration that should be inlined" +) + +private class RemoveDeclarationsThatWouldBeInlinedLowering(val context: JvmBackendContext) : FileLoweringPass { + override fun lower(irFile: IrFile) { + val loweredLambdasToDelete = hashSetOf() + irFile.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitCall(expression: IrCall): IrExpression { + val owner = expression.symbol.owner + if (expression.descriptor.isInlineCall(context.state)) { + 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) { + val reference = + valueArgument.statements.firstIsInstanceOrNull() ?: return@forEach + loweredLambdasToDelete.add(reference.symbol.owner) + } + } + + } + return super.visitCall(expression) + } + }) + + irFile.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitClass(declaration: IrClass): IrStatement { + return super.visitClass(declaration).also { + declaration.declarations.removeAll(loweredLambdasToDelete) + } + } + }) + } +}