JVM_IR simplify RenameFieldsLowering
This commit is contained in:
+13
-85
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user