JVM_IR simplify RenameFieldsLowering

This commit is contained in:
Dmitry Petrov
2022-02-14 16:16:02 +03:00
committed by Space
parent 7f95d7f414
commit 3b3734f0bb
@@ -5,36 +5,22 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetField
import org.jetbrains.kotlin.ir.expressions.IrSetField
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.fields
import org.jetbrains.kotlin.name.Name
internal val renameFieldsPhase = makeIrFilePhase(
::RenameFieldsLowering,
internal val renameFieldsPhase = makeIrFilePhase<CommonBackendContext>(
{ RenameFieldsLowering() },
name = "RenameFields",
description = "Rename private fields (including fields copied from companion object) to avoid JVM declaration clash"
)
private class RenameFieldsLowering(val context: CommonBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
val fields = mutableListOf<IrField>()
irFile.accept(FieldCollector, fields)
private class RenameFieldsLowering : ClassLoweringPass {
override fun lower(irClass: IrClass) {
val fields = irClass.fields.toMutableList()
fields.sortBy {
when {
// We never rename public ABI fields (public and protected visibility) since they are accessible from Java
@@ -51,72 +37,14 @@ private class RenameFieldsLowering(val context: CommonBackendContext) : FileLowe
}
}
val newNames = mutableMapOf<IrField, Name>()
val count = hashMapOf<Pair<IrDeclarationParent, Name>, Int>()
val count = hashMapOf<Name, Int>()
for (field in fields) {
val key = field.parent to field.name
val index = count[key] ?: 0
val oldName = field.name
val index = count[oldName] ?: 0
if (index != 0 && !field.visibility.isPublicAPI) {
newNames[field] = Name.identifier("${field.name}$$index")
field.name = Name.identifier("$oldName$$index")
}
count[key] = index + 1
}
val renamer = FieldRenamer(newNames)
irFile.transform(renamer, null)
irFile.transform(FieldAccessTransformer(renamer.newSymbols), null)
}
}
private object FieldCollector : IrElementVisitor<Unit, MutableList<IrField>> {
override fun visitElement(element: IrElement, data: MutableList<IrField>) {
element.acceptChildren(this, data)
}
override fun visitField(declaration: IrField, data: MutableList<IrField>) {
data.add(declaration)
}
}
private class FieldRenamer(private val newNames: Map<IrField, Name>) : IrElementTransformerVoid() {
val newSymbols = mutableMapOf<IrField, IrFieldSymbol>()
override fun visitField(declaration: IrField): IrStatement {
val newName = newNames[declaration] ?: return super.visitField(declaration)
return declaration.factory.buildField {
updateFrom(declaration)
name = newName
}.also {
it.parent = declaration.parent
it.initializer = declaration.initializer
?.transform(this, null)
?.patchDeclarationParents(it)
newSymbols[declaration] = it.symbol
count[oldName] = index + 1
}
}
}
private class FieldAccessTransformer(private val oldToNew: Map<IrField, IrFieldSymbol>) : IrElementTransformerVoid() {
override fun visitGetField(expression: IrGetField): IrExpression {
val newSymbol = oldToNew[expression.symbol.owner] ?: return super.visitGetField(expression)
return IrGetFieldImpl(
expression.startOffset, expression.endOffset, newSymbol, expression.type,
expression.receiver?.transform(this, null),
expression.origin, expression.superQualifierSymbol
)
}
override fun visitSetField(expression: IrSetField): IrExpression {
val newSymbol = oldToNew[expression.symbol.owner] ?: return super.visitSetField(expression)
return IrSetFieldImpl(
expression.startOffset, expression.endOffset, newSymbol,
expression.receiver?.transform(this, null),
expression.value.transform(this, null),
expression.type,
expression.origin, expression.superQualifierSymbol
)
}
}