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