IR: refactor InitializersLoweringBase and descendants

This commit is contained in:
pyos
2019-11-23 13:56:03 +01:00
committed by Alexander Udalov
parent a6f8859a49
commit 2ebe269448
2 changed files with 62 additions and 113 deletions
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
@@ -18,73 +17,51 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
object SYNTHESIZED_INIT_BLOCK : IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
open class InitializersLowering(
context: CommonBackendContext
) : InitializersLoweringBase(context) {
open class InitializersLowering(context: CommonBackendContext) : InitializersLoweringBase(context) {
override fun lower(irClass: IrClass) {
val nonStaticDeclarations = getDeclarationsWithNonStaticInitializers(irClass)
val instanceInitializerStatements = nonStaticDeclarations.mapNotNull { handleDeclaration(irClass, it) }
transformInstanceInitializerCallsInConstructors(irClass, instanceInitializerStatements)
val anonymousInitializers = nonStaticDeclarations.filterTo(hashSetOf()) { it is IrAnonymousInitializer }
irClass.declarations.removeAll(anonymousInitializers)
}
private fun getDeclarationsWithNonStaticInitializers(irClass: IrClass): List<IrDeclaration> =
irClass.declarations.filter {
val instanceInitializerStatements = extractInitializers(irClass) {
(it is IrField && !it.isStatic) || (it is IrAnonymousInitializer && !it.isStatic)
}
irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
// Only transform constructors of current class.
override fun visitClassNew(declaration: IrClass) = declaration
private fun transformInstanceInitializerCallsInConstructors(irClass: IrClass, instanceInitializerStatements: List<IrStatement>) {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
val copiedBlock =
IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, null, instanceInitializerStatements)
.copy(irClass) as IrBlock
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null, copiedBlock.statements)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction) = declaration
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression =
IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null, instanceInitializerStatements)
.deepCopyWithSymbols(currentScope!!.scope.getLocalDeclarationParent())
})
}
}
abstract class InitializersLoweringBase(val context: CommonBackendContext) : ClassLoweringPass {
protected fun handleDeclaration(irClass: IrClass, declaration: IrDeclaration): IrStatement? = when (declaration) {
is IrField -> handleField(irClass, declaration)
is IrAnonymousInitializer -> handleAnonymousInitializer(declaration)
else -> null
}
protected fun extractInitializers(irClass: IrClass, filter: (IrDeclaration) -> Boolean) =
irClass.declarations.filter(filter).mapNotNull {
when (it) {
is IrField -> handleField(irClass, it)
is IrAnonymousInitializer -> handleAnonymousInitializer(it)
else -> null
}
}.also {
irClass.declarations.removeAll { it is IrAnonymousInitializer && filter(it) }
}
private fun handleField(irClass: IrClass, declaration: IrField): IrStatement? {
val irFieldInitializer = declaration.initializer?.expression ?: return null
private fun handleField(irClass: IrClass, declaration: IrField): IrStatement? =
declaration.initializer?.run {
val receiver = if (!declaration.isStatic) // TODO isStaticField
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol)
else
null
IrSetFieldImpl(startOffset, endOffset, declaration.symbol, receiver, expression, context.irBuiltIns.unitType)
}
val receiver =
if (!declaration.isStatic) // TODO isStaticField
IrGetValueImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
)
else null
return IrSetFieldImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
declaration.symbol,
receiver,
irFieldInitializer,
context.irBuiltIns.unitType,
null, null
)
}
private fun handleAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement = IrBlockImpl(
declaration.startOffset, declaration.endOffset,
context.irBuiltIns.unitType,
SYNTHESIZED_INIT_BLOCK,
declaration.body.statements
)
protected fun IrStatement.copy(containingDeclaration: IrDeclarationParent): IrStatement = deepCopyWithSymbols(containingDeclaration)
private fun handleAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement =
with(declaration) {
IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, SYNTHESIZED_INIT_BLOCK, body.statements)
}
}