From bcc8f3e073979af5aec5d8099917b9d57b5848df Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 8 Apr 2019 14:49:10 +0300 Subject: [PATCH] [IR] Move Ir utils from Kotlin/Native --- .../kotlin/backend/common/ir/IrUtils.kt | 115 ++++++++++++++++++ .../kotlin/ir/backend/js/ir/IrBuilder.kt | 8 -- 2 files changed, 115 insertions(+), 8 deletions(-) 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 804d0e64ce2..d6fa308a076 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 @@ -21,9 +21,11 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithVariables import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl +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.descriptors.IrBuiltIns @@ -33,6 +35,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl +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.* @@ -347,3 +350,115 @@ fun isElseBranch(branch: IrBranch) = branch is IrElseBranch || ((branch.conditio fun IrSimpleFunction.isMethodOfAny() = ((valueParameters.size == 0 && name.asString().let { it == "hashCode" || it == "toString" }) || (valueParameters.size == 1 && name.asString() == "equals" && valueParameters[0].type.isNullableAny())) + +fun IrClass.simpleFunctions() = declarations.flatMap { + when (it) { + is IrSimpleFunction -> listOf(it) + is IrProperty -> listOfNotNull(it.getter, it.setter) + else -> emptyList() + } +} + +fun IrClass.createParameterDeclarations() { + assert (thisReceiver == null) + + thisReceiver = WrappedReceiverParameterDescriptor().let { + IrValueParameterImpl( + startOffset, endOffset, + IrDeclarationOrigin.INSTANCE_RECEIVER, + IrValueParameterSymbolImpl(it), + Name.special(""), + 0, + symbol.typeWith(typeParameters.map { it.defaultType }), + null, + false, + false + ).apply { + it.bind(this) + parent = this@createParameterDeclarations + } + } +} + +fun IrFunction.createDispatchReceiverParameter(origin: IrDeclarationOrigin? = null) { + assert(dispatchReceiverParameter == null) + + dispatchReceiverParameter = IrValueParameterImpl( + startOffset, endOffset, + origin ?: parentAsClass.origin, + IrValueParameterSymbolImpl(parentAsClass.thisReceiver!!.descriptor), + Name.special(""), + 0, + parentAsClass.defaultType, + null, + false, + false + ).apply { + parent = this@createDispatchReceiverParameter + } +} + +val IrFunction.allParameters: List + get() = if (this is IrConstructor) { + listOf(this.constructedClass.thisReceiver + ?: error(this.descriptor) + ) + explicitParameters + } else { + explicitParameters + } + +fun IrClass.addFakeOverrides() { + fun IrDeclaration.toList() = when (this) { + is IrSimpleFunction -> listOf(this) + is IrProperty -> listOfNotNull(getter, setter) + else -> emptyList() + } + + val overriddenFunctions = declarations + .flatMap { it.toList() } + .flatMap { it.overriddenSymbols.map { it.owner } } + .toSet() + + val unoverriddenSuperFunctions = superTypes + .map { it.getClass()!! } + .flatMap { irClass -> + irClass.declarations + .flatMap { it.toList() } + .filter { it !in overriddenFunctions } + } + .toMutableSet() + + // TODO: A dirty hack. + val groupedUnoverriddenSuperFunctions = unoverriddenSuperFunctions.groupBy { it.name.asString() + it.allParameters.size } + + fun createFakeOverride(overriddenFunctions: List) = + overriddenFunctions.first().let { irFunction -> + val descriptor = WrappedSimpleFunctionDescriptor() + IrFunctionImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + IrDeclarationOrigin.FAKE_OVERRIDE, + IrSimpleFunctionSymbolImpl(descriptor), + irFunction.name, + Visibilities.INHERITED, + Modality.OPEN, + irFunction.returnType, + irFunction.isInline, + irFunction.isExternal, + irFunction.isTailrec, + irFunction.isSuspend + ).apply { + descriptor.bind(this) + parent = this@addFakeOverrides + overriddenSymbols += overriddenFunctions.map { it.symbol } + copyParameterDeclarationsFrom(irFunction) + } + } + + val fakeOverriddenFunctions = groupedUnoverriddenSuperFunctions + .asSequence() + .associate { it.value.first() to createFakeOverride(it.value) } + .toMutableMap() + + declarations += fakeOverriddenFunctions.values +} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrBuilder.kt index c40b33a4ab3..8125121151d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ir/IrBuilder.kt @@ -253,12 +253,4 @@ object JsIrBuilder { fun buildString(type: IrType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s) fun buildTry(type: IrType) = IrTryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type) fun buildCatch(ex: IrVariable, block: IrBlockImpl) = IrCatchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, ex, block) -} - -fun IrClass.simpleFunctions(): List = this.declarations.flatMap { - when (it) { - is IrSimpleFunction -> listOf(it) - is IrProperty -> listOfNotNull(it.getter, it.setter) - else -> emptyList() - } } \ No newline at end of file