diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index 6d5349d11d2..73979c5b70d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -415,7 +415,7 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() { startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER, IrValueParameterSymbolImpl(thisReceiverDescriptor), - Name.identifier(""), + Name.special(""), index = -1, type = symbol.typeWithParameters(typeParameters), varargElementType = null, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt index 0c23064fd9d..805d60413ab 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt @@ -65,6 +65,8 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : abstract fun getSuperTypeForWrapper(typeOperand: IrType): IrType override fun lower(irFile: IrFile) { + cachedImplementations.clear() + inlineCachedImplementations.clear() enclosingContainer = irFile.declarations.filterIsInstance().find { it.isFileClass } ?: irFile irFile.transformChildrenVoid() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index eb85d90c612..27fec274752 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -475,11 +475,21 @@ private val bridgesConstructionPhase = makeDeclarationTransformerPhase( prerequisite = setOf(suspendFunctionsLoweringPhase) ) +private val singleAbstractMethodPhase = makeIrModulePhase( + ::JsSingleAbstractMethodLowering, + name = "SingleAbstractMethod", + description = "Replace SAM conversions with instances of interface-implementing classes" +).toModuleLowering() + private val typeOperatorLoweringPhase = makeBodyLoweringPhase( ::TypeOperatorLowering, name = "TypeOperatorLowering", description = "Lower IrTypeOperator with corresponding logic", - prerequisite = setOf(bridgesConstructionPhase, removeInlineFunctionsWithReifiedTypeParametersLoweringPhase) + prerequisite = setOf( + bridgesConstructionPhase, + removeInlineFunctionsWithReifiedTypeParametersLoweringPhase, + singleAbstractMethodPhase + ) ) private val secondaryConstructorLoweringPhase = makeDeclarationTransformerPhase( @@ -580,6 +590,7 @@ val loweringList = listOf( copyInlineFunctionBodyLoweringPhase, createScriptFunctionsPhase, provisionalFunctionExpressionPhase, + singleAbstractMethodPhase, lateinitNullableFieldsPhase, lateinitDeclarationLoweringPhase, lateinitUsageLoweringPhase, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsSingleAbstractMethodLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsSingleAbstractMethodLowering.kt new file mode 100644 index 00000000000..1e36163dbd0 --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsSingleAbstractMethodLowering.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.ir.backend.js.lower + +import org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.types.defaultType +import org.jetbrains.kotlin.ir.util.render + +class JsSingleAbstractMethodLowering(context: JsIrBackendContext) : SingleAbstractMethodLowering(context) { + override fun getSuperTypeForWrapper(typeOperand: IrType): IrType { + // FE doesn't allow type parameters for now. + // And since there is a to-do in common SingleAbstractMethodLowering (at function visitTypeOperator), + // we don't have to be more saint than a pope here. + return typeOperand.classOrNull?.defaultType ?: error("Unsupported SAM conversion: ${typeOperand.render()}") + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt index a08976647c8..243978ff3fe 100644 --- a/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt +++ b/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt @@ -1,6 +1,7 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS, JS_IR +// IGNORE_BACKEND: JS +// SKIP_DCE_DRIVEN fun interface Foo { fun invoke(): String diff --git a/compiler/testData/codegen/box/funInterface/nullableSam.kt b/compiler/testData/codegen/box/funInterface/nullableSam.kt index 586e77fe84d..eb535398491 100644 --- a/compiler/testData/codegen/box/funInterface/nullableSam.kt +++ b/compiler/testData/codegen/box/funInterface/nullableSam.kt @@ -1,7 +1,8 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS, JS_IR +// IGNORE_BACKEND: JS // WITH_RUNTIME +// SKIP_DCE_DRIVEN fun interface KRunnable { fun invoke() diff --git a/compiler/testData/codegen/box/funInterface/partialSam.kt b/compiler/testData/codegen/box/funInterface/partialSam.kt index b32b4ed9087..8289e832a18 100644 --- a/compiler/testData/codegen/box/funInterface/partialSam.kt +++ b/compiler/testData/codegen/box/funInterface/partialSam.kt @@ -1,7 +1,8 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS, JS_IR +// IGNORE_BACKEND: JS // WITH_RUNTIME +// SKIP_DCE_DRIVEN fun interface Fn { fun run(s: String, i: Int, t: T): R diff --git a/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt b/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt index fdf8091e36f..f7609a450d0 100644 --- a/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt +++ b/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt @@ -1,7 +1,8 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS, JS_IR +// IGNORE_BACKEND: JS // WITH_RUNTIME +// SKIP_DCE_DRIVEN fun interface KRunnable { fun invoke()