JVM IR: minor, refactor replaceThisByStaticReference

Allow to replace "this" references not only inside IrBody, but inside
any IrElement. This will be useful in JvmStatic in object lowering where
we want not only to replace usages inside the function body, but also in
default values of its parameters.
This commit is contained in:
Alexander Udalov
2020-11-11 19:26:52 +01:00
parent ebb545a9fb
commit 0a00cbefaf
4 changed files with 17 additions and 24 deletions
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.setSourceRange import org.jetbrains.kotlin.ir.builders.setSourceRange
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
@@ -135,9 +134,8 @@ class JvmCachedDeclarations(
annotations = oldField.annotations annotations = oldField.annotations
} }
initializer = oldField.initializer initializer = oldField.initializer?.patchDeclarationParents(this)
?.replaceThisByStaticReference(this@JvmCachedDeclarations, oldParent, oldParent.thisReceiver!!) oldField.replaceThisByStaticReference(this@JvmCachedDeclarations, oldParent, oldParent.thisReceiver!!)
?.patchDeclarationParents(this) as IrExpressionBody?
origin = if (irProperty.parentAsClass.isCompanion) JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD else origin origin = if (irProperty.parentAsClass.isCompanion) JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD else origin
} }
} }
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.Scope
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -223,25 +225,23 @@ fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext):
} }
} }
fun IrBody.replaceThisByStaticReference( fun IrElement.replaceThisByStaticReference(
cachedDeclarations: JvmCachedDeclarations, cachedDeclarations: JvmCachedDeclarations,
irClass: IrClass, irClass: IrClass,
oldThisReceiverParameter: IrValueParameter oldThisReceiverParameter: IrValueParameter
): IrBody = ) {
transform(object : IrElementTransformerVoid() { transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression =
if (expression.symbol == oldThisReceiverParameter.symbol) { if (expression.symbol == oldThisReceiverParameter.symbol) {
val instanceField = cachedDeclarations.getPrivateFieldForObjectInstance(irClass) IrGetFieldImpl(
return IrGetFieldImpl(
expression.startOffset, expression.startOffset,
expression.endOffset, expression.endOffset,
instanceField.symbol, cachedDeclarations.getPrivateFieldForObjectInstance(irClass).symbol,
irClass.defaultType irClass.defaultType
) )
} } else super.visitGetValue(expression)
return super.visitGetValue(expression) })
} }
}, null)
// TODO: Interface Parameters // TODO: Interface Parameters
// //
@@ -139,11 +139,8 @@ private class SingletonObjectJvmStaticLowering(val context: JvmBackendContext) :
val replacement = createReplacement(context, function as IrSimpleFunction) val replacement = createReplacement(context, function as IrSimpleFunction)
// Set dispatch receiver parameter for body move operation. // Set dispatch receiver parameter for body move operation.
replacement.dispatchReceiverParameter = function.dispatchReceiverParameter replacement.dispatchReceiverParameter = function.dispatchReceiverParameter
replacement.body = function.moveBodyTo(replacement)?.replaceThisByStaticReference( replacement.body = function.moveBodyTo(replacement)
context.cachedDeclarations, replacement.replaceThisByStaticReference(context.cachedDeclarations, irClass, function.dispatchReceiverParameter!!)
irClass,
function.dispatchReceiverParameter!!
)
// Clear dispatch receiver parameter again after body move operation. // Clear dispatch receiver parameter again after body move operation.
replacement.dispatchReceiverParameter = null replacement.dispatchReceiverParameter = null
irClass.declarations.remove(function) irClass.declarations.remove(function)
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
@@ -105,9 +104,8 @@ private class MoveOrCopyCompanionObjectFieldsLowering(val context: JvmBackendCon
val newSymbol = IrAnonymousInitializerSymbolImpl(newParent.symbol) val newSymbol = IrAnonymousInitializerSymbolImpl(newParent.symbol)
IrAnonymousInitializerImpl(startOffset, endOffset, origin, newSymbol, isStatic = true).apply { IrAnonymousInitializerImpl(startOffset, endOffset, origin, newSymbol, isStatic = true).apply {
parent = newParent parent = newParent
body = this@with.body body = this@with.body.patchDeclarationParents(newParent)
.replaceThisByStaticReference(context.cachedDeclarations, oldParent, oldParent.thisReceiver!!) replaceThisByStaticReference(context.cachedDeclarations, oldParent, oldParent.thisReceiver!!)
.patchDeclarationParents(newParent) as IrBlockBody
} }
} }