[JVM IR] Get rid of MfvcNodeWithSubnodesImpl class

`MfvcNodeWithSubnodesImpl` has two problems:
- Naming: its name makes one think that the class is inherited from
`MfvcNode` and implements `MfvcNodeWithSubnodes`.However, both
statements are false.
- Semantics: the class only makes unnecessary indirection between its
properties and code of `MfvcNodeWithSubnodes` class
This commit is contained in:
Vladislav Grechko
2023-04-03 15:26:47 +02:00
committed by Space Team
parent 8102744e00
commit bd7bce9f97
2 changed files with 56 additions and 66 deletions
@@ -139,11 +139,43 @@ fun MfvcNode.getSubnodeAndIndices(name: Name): Pair<NameableMfvcNode, IntRange>?
return node to indices
}
sealed interface MfvcNodeWithSubnodes : MfvcNode {
sealed class MfvcNodeWithSubnodes(val subnodes: List<NameableMfvcNode>) : MfvcNode {
abstract override val type: IrSimpleType
val boxMethod: IrSimpleFunction
val leavesUnboxMethods: List<IrSimpleFunction>?
val subnodesImpl: MfvcNodeWithSubnodesImpl
abstract val boxMethod: IrSimpleFunction
abstract val leavesUnboxMethods: List<IrSimpleFunction>?
abstract val allUnboxMethods: List<IrSimpleFunction>
init {
require(subnodes.isNotEmpty())
require(subnodes.map { it.nameParts.dropLast(1) }.allEqual())
}
private val mapping = subnodes.associateBy { it.name }.also { mapping ->
require(mapping.size == subnodes.size) {
subnodes
.groupBy { it.name }
.filterValues { it.size > 1 }
.entries.joinToString(prefix = "Repeating node names found: ") { (name, nodes) -> "${nodes.size} nodes with name '$name'" }
}
}
operator fun get(name: Name): NameableMfvcNode? = mapping[name]
val leaves: List<LeafMfvcNode> = subnodes.leaves
val fields: List<IrField>? = subnodes.fields
val allInnerUnboxMethods: List<IrSimpleFunction> = subnodes.flatMap { subnode ->
when (subnode) {
is MfvcNodeWithSubnodes -> subnode.allUnboxMethods
is LeafMfvcNode -> listOf(subnode.unboxMethod)
}
}
val indices: IntRange = leaves.indices
val subnodeIndices = subnodes.subnodeIndices
}
fun MfvcNodeWithSubnodes.makeBoxedExpression(
@@ -173,24 +205,10 @@ operator fun MfvcNodeWithSubnodes.get(names: List<Name>): MfvcNode? {
private fun List<Any>.allEqual() = all { it == first() }
class MfvcNodeWithSubnodesImpl(val subnodes: List<NameableMfvcNode>, unboxMethod: IrSimpleFunction?) {
init {
require(subnodes.isNotEmpty())
require(subnodes.map { it.nameParts.dropLast(1) }.allEqual())
}
val List<NameableMfvcNode>.leaves get() = this.mapLeaves { it }
private val mapping = subnodes.associateBy { it.name }.also { mapping ->
require(mapping.size == subnodes.size) {
subnodes
.groupBy { it.name }
.filterValues { it.size > 1 }
.entries.joinToString(prefix = "Repeating node names found: ") { (name, nodes) -> "${nodes.size} nodes with name '$name'" }
}
}
operator fun get(name: Name): NameableMfvcNode? = mapping[name]
val leaves: List<LeafMfvcNode> = mapLeaves { it }
val fields: List<IrField>? = mapLeaves { it.field }.run {
val List<NameableMfvcNode>.fields
get() = mapLeaves { it.field }.run {
@Suppress("UNCHECKED_CAST")
when {
all { it == null } -> null
@@ -199,20 +217,10 @@ class MfvcNodeWithSubnodesImpl(val subnodes: List<NameableMfvcNode>, unboxMethod
}
}
val allInnerUnboxMethods: List<IrSimpleFunction> = subnodes.flatMap { subnode ->
when (subnode) {
is MfvcNodeWithSubnodes -> subnode.allUnboxMethods
is LeafMfvcNode -> listOf(subnode.unboxMethod)
}
}
val allUnboxMethods = allInnerUnboxMethods + listOfNotNull(unboxMethod)
val indices: IntRange = leaves.indices
val subnodeIndices: Map<NameableMfvcNode, IntRange> = buildMap {
val List<NameableMfvcNode>.subnodeIndices: Map<NameableMfvcNode, IntRange>
get() = buildMap {
var offset = 0
for (node in subnodes) {
for (node in this@subnodeIndices) {
when (node) {
is IntermediateMfvcNode -> {
val nodeSize = node.leavesCount
@@ -228,26 +236,6 @@ class MfvcNodeWithSubnodesImpl(val subnodes: List<NameableMfvcNode>, unboxMethod
}
}
}
}
val MfvcNodeWithSubnodes.subnodes: List<NameableMfvcNode>
get() = subnodesImpl.subnodes
operator fun MfvcNodeWithSubnodes.get(name: Name): NameableMfvcNode? = subnodesImpl[name]
val MfvcNodeWithSubnodes.leaves: List<LeafMfvcNode>
get() = subnodesImpl.leaves
val MfvcNodeWithSubnodes.fields: List<IrField>?
get() = subnodesImpl.fields
val RootMfvcNode.fields: List<IrField>?
get() = subnodesImpl.fields
val MfvcNodeWithSubnodes.indices: IntRange
get() = subnodesImpl.indices
val MfvcNodeWithSubnodes.subnodeIndices: Map<NameableMfvcNode, IntRange>
get() = subnodesImpl.subnodeIndices
val MfvcNodeWithSubnodes.allUnboxMethods: List<IrSimpleFunction>
get() = subnodesImpl.allUnboxMethods
val MfvcNodeWithSubnodes.allInnerUnboxMethods: List<IrSimpleFunction>
get() = subnodesImpl.allInnerUnboxMethods
inline fun <R> MfvcNode.mapLeaves(crossinline f: (LeafMfvcNode) -> R): List<R> = flatMapLeaves { listOf(f(it)) }
@@ -256,7 +244,7 @@ fun <R> MfvcNode.flatMapLeaves(f: (LeafMfvcNode) -> List<R>): List<R> = when (th
is LeafMfvcNode -> f(this)
}
inline fun <R> MfvcNodeWithSubnodesImpl.mapLeaves(crossinline f: (LeafMfvcNode) -> R): List<R> = subnodes.flatMap { it.mapLeaves(f) }
inline fun <R> List<NameableMfvcNode>.mapLeaves(crossinline f: (LeafMfvcNode) -> R): List<R> = flatMap { it.mapLeaves(f) }
private fun requireSameClasses(vararg classes: IrClass?) {
@@ -330,11 +318,10 @@ class IntermediateMfvcNode(
unboxMethod: IrSimpleFunction,
defaultMethodsImplementationSourceNode: UnboxFunctionImplementation,
val rootNode: RootMfvcNode, // root node corresponding type of the node
) : NameableMfvcNode, MfvcNodeWithSubnodes {
) : NameableMfvcNode, MfvcNodeWithSubnodes(subnodes) {
override val hasPureUnboxMethod: Boolean =
defaultMethodsImplementationSourceNode.hasPureUnboxMethod && subnodes.all { it.hasPureUnboxMethod }
override val namedNodeImpl: NameableMfvcNodeImpl = NameableMfvcNodeImpl(methodFullNameMode, nameParts, unboxMethod)
override val subnodesImpl: MfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, unboxMethod)
override val leavesCount
get() = leaves.size
@@ -350,6 +337,8 @@ class IntermediateMfvcNode(
validateGettingAccessorParameters(unboxMethod)
}
override val allUnboxMethods = allInnerUnboxMethods + listOf(unboxMethod)
override val boxMethod: IrSimpleFunction
get() = rootNode.boxMethod
@@ -394,8 +383,7 @@ class RootMfvcNode internal constructor(
override val boxMethod: IrSimpleFunction,
val specializedEqualsMethod: IrSimpleFunction,
val createdNewSpecializedEqualsMethod: Boolean,
) : MfvcNodeWithSubnodes {
override val subnodesImpl: MfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, null)
) : MfvcNodeWithSubnodes(subnodes) {
override val type: IrSimpleType = mfvc.defaultType
override val leavesCount: Int
@@ -403,6 +391,8 @@ class RootMfvcNode internal constructor(
override val leavesUnboxMethods: List<IrSimpleFunction> = collectLeavesUnboxMethods()
override val allUnboxMethods: List<IrSimpleFunction> get() = allInnerUnboxMethods
init {
require(type.needsMfvcFlattening()) { "MFVC type expected but got: ${type.render()}" }
for (constructor in listOf(oldPrimaryConstructor, newPrimaryConstructor)) {
@@ -341,12 +341,11 @@ fun getRootNode(context: JvmBackendContext, mfvc: IrClass): RootMfvcNode {
val subnodes = makeRootMfvcNodeSubnodes(representation, properties, context, mfvc)
val mfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, null)
val leaves = mfvcNodeWithSubnodesImpl.leaves
val fields = mfvcNodeWithSubnodesImpl.fields
val leaves = subnodes.leaves
val fields = subnodes.fields
val newPrimaryConstructor = makeMfvcPrimaryConstructor(context, oldPrimaryConstructor, mfvc, leaves, fields)
val primaryConstructorImpl = makePrimaryConstructorImpl(context, oldPrimaryConstructor, mfvc, leaves, mfvcNodeWithSubnodesImpl)
val primaryConstructorImpl = makePrimaryConstructorImpl(context, oldPrimaryConstructor, mfvc, leaves, subnodes)
val boxMethod = makeBoxMethod(context, mfvc, leaves, newPrimaryConstructor)
val customEqualsAny = mfvc.functions.singleOrNull {
@@ -438,7 +437,7 @@ private fun makePrimaryConstructorImpl(
oldPrimaryConstructor: IrConstructor,
mfvc: IrClass,
leaves: List<LeafMfvcNode>,
subnodesImpl: MfvcNodeWithSubnodesImpl,
subnodes: List<NameableMfvcNode>,
) = context.irFactory.buildFun {
name = InlineClassAbi.mangledNameFor(oldPrimaryConstructor, false, false)
visibility = oldPrimaryConstructor.visibility
@@ -452,9 +451,10 @@ private fun makePrimaryConstructorImpl(
addValueParameter(leaf.fullFieldName, leaf.type.substitute(mfvc.typeParameters, typeParameters.map { it.defaultType }))
}
for ((index, oldParameter) in oldPrimaryConstructor.valueParameters.withIndex()) {
val node = subnodesImpl.subnodes[index]
val node = subnodes[index]
val subnodesIndices = subnodes.subnodeIndices
if (node is LeafMfvcNode) {
val newIndex = subnodesImpl.subnodeIndices[node]!!.first
val newIndex = subnodesIndices[node]!!.first
valueParameters[newIndex].annotations = oldParameter.annotations
}
}