diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 6e6b9a9099b..a87688f999c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -274,7 +274,7 @@ class JvmSymbols( val getOrCreateKotlinClasses: IrSimpleFunctionSymbol = reflection.functions.single { it.owner.name.asString() == "getOrCreateKotlinClasses" } - val unsafeCoerceIntrinsic = + private val unsafeCoerceIntrinsic = buildFun { name = Name.special("") origin = IrDeclarationOrigin.IR_BUILTINS_STUB @@ -286,4 +286,25 @@ class JvmSymbols( returnType = dst.defaultType } val unsafeCoerceIntrinsicSymbol = unsafeCoerceIntrinsic.symbol + + private val collectionToArrayClass: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.CollectionToArray")) { klass -> + klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY + + val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType) + klass.addFunction("toArray", arrayType, isStatic = true).apply { + origin = JvmLoweredDeclarationOrigin.TO_ARRAY + addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY) + } + klass.addFunction("toArray", arrayType, isStatic = true).apply { + origin = JvmLoweredDeclarationOrigin.TO_ARRAY + addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY) + addValueParameter("array", arrayType, JvmLoweredDeclarationOrigin.TO_ARRAY) + } + }.symbol + + val nonGenericToArray: IrSimpleFunctionSymbol = + collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 1 } + + val genericToArray: IrSimpleFunctionSymbol = + collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 2 } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ToArrayLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ToArrayLowering.kt index 093d43bbac4..53de5be8f3e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ToArrayLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ToArrayLowering.kt @@ -6,25 +6,34 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass -import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor +import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor +import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.backend.common.lower.createIrBuilder 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.isJvmInterface -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irReturn -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl -import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.isClass import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.DFS @@ -36,11 +45,11 @@ internal val toArrayPhase = makeIrFilePhase( ) private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass { - override fun lower(irClass: IrClass) { if (irClass.isJvmInterface || !irClass.isDirectCollectionSubClass()) return val irBuiltIns = context.irBuiltIns + val symbols = context.ir.symbols val toArrayName = Name.identifier("toArray") val genericToArray = irClass.declarations.find { it.isGenericToArray() } @@ -116,7 +125,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody { +irReturn( - irCall(genericToArrayUtilFunction.symbol, genericToArrayUtilFunction.returnType).apply { + irCall(symbols.genericToArray, symbols.genericToArray.owner.returnType).apply { putValueArgument( 0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol) @@ -165,7 +174,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody { +irReturn( - irCall(nonGenericToArrayUtilFunction.symbol, nonGenericToArrayUtilFunction.returnType).apply { + irCall(symbols.nonGenericToArray, symbols.nonGenericToArray.owner.returnType).apply { putValueArgument( 0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol) @@ -179,105 +188,6 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow } } - private val kotlinJvmInternalPackageFragment: IrPackageFragment by lazy { - IrExternalPackageFragmentImpl( - IrExternalPackageFragmentSymbolImpl( - EmptyPackageFragmentDescriptor( - context.ir.irModule.descriptor, - FqName("kotlin.jvm.internal") - ) - ) - ) - } - - private val collectionUtilClass: IrClass by lazy { - val descriptor = WrappedClassDescriptor() - IrClassImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.TO_ARRAY, - IrClassSymbolImpl(descriptor), - Name.identifier("CollectionToArray"), - ClassKind.CLASS, - Visibilities.PUBLIC, - Modality.FINAL, - isCompanion = false, - isInner = false, - isInline = false, - isData = false, - isExternal = false - ).apply { - descriptor.bind(this) - parent = kotlinJvmInternalPackageFragment - superTypes.add(context.irBuiltIns.anyType) - kotlinJvmInternalPackageFragment.declarations.add(this) - } - } - - private fun createToArrayUtilFunction(isGeneric: Boolean): IrSimpleFunction { - val irBuiltIns = context.irBuiltIns - val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType) - - val utilFunctionDescriptor = WrappedSimpleFunctionDescriptor() - return IrFunctionImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.TO_ARRAY, - IrSimpleFunctionSymbolImpl(utilFunctionDescriptor), - Name.identifier("toArray"), - Visibilities.PUBLIC, - Modality.FINAL, - returnType = arrayType, - isInline = false, - isExternal = false, - isTailrec = false, - isSuspend = false - ).also { irFunction -> - utilFunctionDescriptor.bind(irFunction) - irFunction.parent = collectionUtilClass - - val collectionParameterDescriptor = WrappedValueParameterDescriptor() - irFunction.valueParameters.add( - IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.TO_ARRAY, - IrValueParameterSymbolImpl(collectionParameterDescriptor), - Name.identifier("collection"), - 0, - irBuiltIns.collectionClass.owner.defaultType, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - collectionParameterDescriptor.bind(this) - parent = irFunction - } - ) - if (isGeneric) { - val arrayParameterDescriptor = WrappedValueParameterDescriptor() - irFunction.valueParameters.add( - IrValueParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - JvmLoweredDeclarationOrigin.TO_ARRAY, - IrValueParameterSymbolImpl(arrayParameterDescriptor), - Name.identifier("array"), - 1, - arrayType, - varargElementType = null, - isCrossinline = false, - isNoinline = false - ).apply { - arrayParameterDescriptor.bind(this) - parent = irFunction - } - ) - } - collectionUtilClass.declarations.add(irFunction) - } - } - - private val nonGenericToArrayUtilFunction: IrSimpleFunction by lazy { createToArrayUtilFunction(false) } - private val genericToArrayUtilFunction: IrSimpleFunction by lazy { createToArrayUtilFunction(true) } - - private fun IrDeclaration.isGenericToArray(): Boolean { if (this !is IrSimpleFunction) return false val signature = context.state.typeMapper.mapAsmMethod(descriptor) @@ -287,7 +197,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow private fun IrDeclaration.isNonGenericToArray(): Boolean { if (this !is IrSimpleFunction) return false if (this.name.asString() != "toArray") return false - if (!typeParameters.isEmpty() || !valueParameters.isEmpty()) return false + if (typeParameters.isNotEmpty() || valueParameters.isNotEmpty()) return false if (!returnType.isArray()) return false return true diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index 74997696df7..e827c970327 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -115,3 +115,5 @@ fun IrClassifierSymbol.typeWith(arguments: List): IrSimpleType = ) fun IrClass.typeWith(arguments: List) = this.symbol.typeWith(arguments) + +fun IrClass.typeWith(vararg arguments: IrType) = this.symbol.typeWith(arguments.toList())