[IR] Fix compilation of MFVC in different module

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-05-11 20:13:26 +03:00
committed by teamcity
parent a788433aac
commit 406bc4e497
3 changed files with 25 additions and 28 deletions
@@ -64,7 +64,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
fun remapSymbol(original: IrValueSymbol, replacement: IrValueDeclaration) {
symbol2getter[original] = { irGet(replacement) }
symbol2setters[original] = listOf(if (replacement.isAssignable) { _, value -> irSet(replacement, value) } else null)
symbol2setters[original] = if (replacement.isAssignable) listOf { _, value -> irSet(replacement, value) } else listOf(null)
}
fun remapSymbol(
@@ -262,7 +262,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
}
override fun handleSpecificNewClass(declaration: IrClass) {
replacements.setOldFields(declaration, declaration.fields.toList())
replacements.commitMFVCOldProperties(declaration)
val newDeclarations = replacements.getDeclarations(declaration)!!
if (newDeclarations.valueClass != declaration) error("Unexpected IrClass ${newDeclarations.valueClass} instead of $declaration")
newDeclarations.replaceFields()
@@ -317,17 +317,11 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
private fun MultiFieldValueClassSpecificDeclarations.replaceFields() {
valueClass.declarations.removeIf { it is IrField }
valueClass.declarations += fields
for (field in fields) {
field.parent = valueClass
}
}
private fun MultiFieldValueClassSpecificDeclarations.replaceProperties() {
valueClass.declarations.removeAll(oldProperties.values.mapNotNull { it.getter })
properties.values.forEach {
it.parent = valueClass
}
valueClass.declarations += properties.values.map { it.getter!!.apply { parent = valueClass } }
valueClass.declarations += properties.values.map { it.getter!! }
}
override fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction =
@@ -454,9 +448,6 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
fun MultiFieldValueClassSpecificDeclarations.buildPrimaryMultiFieldValueClassConstructor() {
valueClass.declarations.removeIf { it is IrConstructor && it.isPrimary }
val primaryConstructorReplacements = listOf(primaryConstructor, primaryConstructorImpl)
for (exConstructor in primaryConstructorReplacements) {
exConstructor.parent = valueClass
}
valueClass.declarations += primaryConstructorReplacements
val initializersStatements = valueClass.declarations.filterIsInstance<IrAnonymousInitializer>().flatMap { it.body.statements }
@@ -483,7 +474,6 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
})
}
valueClass.declarations += boxMethod
boxMethod.parent = valueClass
}
fun MultiFieldValueClassSpecificDeclarations.buildUnboxFunctions() {
@@ -493,7 +483,6 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
@Suppress("unused")
fun MultiFieldValueClassSpecificDeclarations.buildSpecializedEqualsMethod() {
// todo defaults
specializedEqualsMethod.parent = valueClass
specializedEqualsMethod.body = with(context.createIrBuilder(specializedEqualsMethod.symbol)) {
// TODO: Revisit this once we allow user defined equals methods in inline/multi-field value classes.
leaves.indices.map {
@@ -44,14 +44,16 @@ class MemoizedMultiFieldValueClassReplacements(
null
}
private val oldFields: MutableMap<IrClass, List<IrField>> =
ConcurrentHashMap<IrClass, List<IrField>>().withDefault { it.fields.toList() }
fun setOldFields(irClass: IrClass, fields: List<IrField>) {
oldFields[irClass] = fields
val getOldMFVCProperties: (IrClass) -> List<IrProperty> = storageManager.createMemoizedFunction { irClass ->
require(irClass.isMultiFieldValueClass) { "No need to save data for non MFVC" }
(irClass.properties.toList().filter { it.getter?.isMultiFieldValueClassOriginalFieldGetter == true }.takeIf { it.isNotEmpty() }
?: irClass.fields.mapNotNull { it.correspondingPropertySymbol?.owner }.toList().takeIf { it.isNotEmpty() }
?: error("No properties found: ${irClass.render()}"))
}
fun getOldFields(irClass: IrClass): List<IrField> = oldFields.getOrPut(irClass) { irClass.fields.toList() }
fun commitMFVCOldProperties(irClass: IrClass) {
getOldMFVCProperties(irClass)
}
class ValueParameterTemplate(
val name: String,
@@ -258,8 +260,9 @@ class MemoizedMultiFieldValueClassReplacements(
}
function is IrSimpleFunction && !function.isFromJava() &&
function.fullValueParameterList.any { it.type.isMultiFieldValueClassType() && !it.type.isNullable() } &&
!(function.isFakeOverride &&
bindingOldFunctionToParameterTemplateStructure[findSuperDeclaration(function, false, context.state.jvmDefaultMode)] == null)->
(!function.isFakeOverride ||
findSuperDeclaration(function, false, context.state.jvmDefaultMode)
in bindingOldFunctionToParameterTemplateStructure) ->
createMethodReplacement(function)
else -> null
}
@@ -77,14 +77,14 @@ sealed class MultiFieldValueClassTree<out TI, out TL> {
) : this(type, defaultInternalNodeValue, 0.let {
val valueClassRepresentation = type.erasedUpperBound.valueClassRepresentation as MultiFieldValueClassRepresentation
val primaryConstructor = type.erasedUpperBound.primaryConstructor!!
val fieldsByName = replacements.getOldFields(primaryConstructor.constructedClass).associateBy { it.name }
val propertiesByName = replacements.getOldMFVCProperties(primaryConstructor.constructedClass).associateBy { it.name }
valueClassRepresentation.underlyingPropertyNamesToTypes.map { (name, type) ->
val field = fieldsByName[name]!!
val innerVisibility = field.correspondingPropertySymbol!!.owner.visibility
val property = propertiesByName[name]!!
val innerVisibility = property.visibility
val comparison = visibility.compareTo(innerVisibility)
?: error("Expected comparable visibilities but got $visibility and $innerVisibility")
val newVisibility = if (comparison < 0) visibility else innerVisibility
TreeField(name, type, defaultInternalNodeValue, newVisibility, field.annotations, defaultLeafValue, replacements)
TreeField(name, type, defaultInternalNodeValue, newVisibility, property.annotations, defaultLeafValue, replacements)
}
})
@@ -223,15 +223,16 @@ class MultiFieldValueClassSpecificDeclarations(
}
val oldPrimaryConstructor = valueClass.primaryConstructor ?: error("Value classes have primary constructors")
private val oldFields = replacements.getOldFields(valueClass)
val oldProperties = oldFields.map { it.correspondingPropertySymbol!!.owner }.associateBy { it.name }
val oldProperties = replacements.getOldMFVCProperties(valueClass).associateBy { it.name }
val fields = leaves.map { leaf ->
irFactory.buildField {
this.name = nodeFullNames[leaf]!!
this.type = leaf.type
visibility = DescriptorVisibilities.PRIVATE
}.apply {
parent = valueClass
}
}
@@ -300,6 +301,7 @@ class MultiFieldValueClassSpecificDeclarations(
copyTypeParametersFrom(oldPrimaryConstructor)
addFlattenedClassRepresentationToParameters()
val irConstructor = this@apply
parent = valueClass
body = context.createIrBuilder(irConstructor.symbol).irBlockBody(irConstructor) {
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
for (i in leaves.indices) {
@@ -319,6 +321,7 @@ class MultiFieldValueClassSpecificDeclarations(
returnType = context.irBuiltIns.unitType
modality = Modality.FINAL
}.apply {
parent = valueClass
copyTypeParametersFrom(oldPrimaryConstructor)
addFlattenedClassRepresentationToParameters()
// body is added in Lowering file
@@ -329,6 +332,7 @@ class MultiFieldValueClassSpecificDeclarations(
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER
returnType = valueClass.defaultType
}.apply {
parent = valueClass
copyTypeParametersFrom(valueClass)
addFlattenedClassRepresentationToParameters()
// body is added in Lowering file
@@ -349,6 +353,7 @@ class MultiFieldValueClassSpecificDeclarations(
origin = JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD
returnType = context.irBuiltIns.booleanType
}.apply {
parent = valueClass
copyTypeParametersFrom(oldPrimaryConstructor)
for (leaf in leaves) {
addValueParameter {