[IR] Combine value class lowerings
Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com> #KT-1179
This commit is contained in:
committed by
Space Team
parent
68fb8aa2a1
commit
86809e898a
+1
-1
@@ -30,7 +30,7 @@ open class ScopeWithIr(val scope: Scope, val irElement: IrElement)
|
||||
|
||||
abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid() {
|
||||
|
||||
private val scopeStack = mutableListOf<ScopeWithIr>()
|
||||
protected open val scopeStack = mutableListOf<ScopeWithIr>()
|
||||
|
||||
protected open fun createScope(declaration: IrSymbolOwner): ScopeWithIr =
|
||||
ScopeWithIr(Scope(declaration.symbol), declaration)
|
||||
|
||||
+4
-5
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
@@ -75,14 +74,14 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
val jumps = mutableMapOf<HighLevelJump, IrReturnTargetSymbol>()
|
||||
}
|
||||
|
||||
private val scopeStack = mutableListOf<Scope>()
|
||||
private val otherScopeStack = mutableListOf<Scope>()
|
||||
|
||||
private inline fun <S: Scope, R> using(scope: S, block: (S) -> R): R {
|
||||
scopeStack.push(scope)
|
||||
otherScopeStack.push(scope)
|
||||
try {
|
||||
return block(scope)
|
||||
} finally {
|
||||
scopeStack.pop()
|
||||
otherScopeStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +154,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
endOffset: Int,
|
||||
value: IrExpression
|
||||
): IrExpression? {
|
||||
val tryScopes = scopeStack.reversed()
|
||||
val tryScopes = otherScopeStack.reversed()
|
||||
.takeWhile { !targetScopePredicate(it) }
|
||||
.filterIsInstance<TryScope>()
|
||||
.toList()
|
||||
|
||||
@@ -310,8 +310,7 @@ private val jvmFilePhases = listOf(
|
||||
forLoopsPhase,
|
||||
collectionStubMethodLowering,
|
||||
singleAbstractMethodPhase,
|
||||
jvmMultiFieldValueClassPhase,
|
||||
jvmInlineClassPhase,
|
||||
jvmValueClassPhase,
|
||||
tailrecPhase,
|
||||
// makePatchParentsPhase(),
|
||||
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ internal val bridgePhase = makeIrFilePhase(
|
||||
::BridgeLowering,
|
||||
name = "Bridge",
|
||||
description = "Generate bridges",
|
||||
prerequisite = setOf(jvmInlineClassPhase, jvmMultiFieldValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
||||
prerequisite = setOf(jvmValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
||||
)
|
||||
|
||||
internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
|
||||
|
||||
+15
-22
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
@@ -31,28 +31,19 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||
|
||||
val jvmInlineClassPhase = makeIrFilePhase(
|
||||
::JvmInlineClassLowering,
|
||||
name = "Inline Classes",
|
||||
description = "Lower inline classes",
|
||||
// forLoopsPhase may produce UInt and ULong which are inline classes.
|
||||
// Standard library replacements are done on the unmangled names for UInt and ULong classes.
|
||||
// Collection stubs may require mangling by inline class rules.
|
||||
// SAM wrappers may require mangling for fun interfaces with inline class parameters
|
||||
prerequisite = setOf(
|
||||
forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase, jvmMultiFieldValueClassPhase
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Adds new constructors, box, and unbox functions to inline classes as well as replacement
|
||||
* functions and bridges to avoid clashes between overloaded function. Changes calls with
|
||||
* functions and bridges to avoid clashes between overloaded function. Changes call with
|
||||
* known types to call the replacement functions.
|
||||
*
|
||||
* We do not unfold inline class types here. Instead, the type mapper will lower inline class
|
||||
* types to the types of their underlying field.
|
||||
*/
|
||||
private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClassAbstractLowering(context) {
|
||||
internal class JvmInlineClassLowering(
|
||||
context: JvmBackendContext,
|
||||
fileClassNewDeclarations: MutableMap<IrFile, MutableList<IrSimpleFunction>>,
|
||||
scopeStack: MutableList<ScopeWithIr>,
|
||||
) : JvmValueClassAbstractLowering(context, fileClassNewDeclarations, scopeStack) {
|
||||
override val replacements: MemoizedValueClassAbstractReplacements
|
||||
get() = context.inlineClassReplacements
|
||||
|
||||
@@ -83,8 +74,10 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
|
||||
override val specificMangle: SpecificMangle
|
||||
get() = SpecificMangle.Inline
|
||||
override val IrType.needsHandling get() = isInlineClassType()
|
||||
override fun visitClassNewDeclarationsWhenParallel(declaration: IrDeclaration) = Unit
|
||||
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
override fun visitClassNew(declaration: IrClass): IrClass {
|
||||
// The arguments to the primary constructor are in scope in the initializers of IrFields.
|
||||
|
||||
declaration.primaryConstructor?.let {
|
||||
@@ -122,7 +115,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
addJvmInlineAnnotation(declaration)
|
||||
}
|
||||
|
||||
fun addJvmInlineAnnotation(valueClass: IrClass) {
|
||||
private fun addJvmInlineAnnotation(valueClass: IrClass) {
|
||||
if (valueClass.hasAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME)) return
|
||||
val constructor = context.ir.symbols.jvmInlineAnnotation.constructors.first()
|
||||
valueClass.annotations = valueClass.annotations + IrConstructorCallImpl.fromSymbolOwner(
|
||||
@@ -424,7 +417,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
return super.visitSetValue(expression)
|
||||
}
|
||||
|
||||
fun buildPrimaryInlineClassConstructor(valueClass: IrClass, irConstructor: IrConstructor) {
|
||||
private fun buildPrimaryInlineClassConstructor(valueClass: IrClass, irConstructor: IrConstructor) {
|
||||
// Add the default primary constructor
|
||||
valueClass.addConstructor {
|
||||
updateFrom(irConstructor)
|
||||
@@ -469,7 +462,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
valueClass.declarations += function
|
||||
}
|
||||
|
||||
fun buildBoxFunction(valueClass: IrClass) {
|
||||
private fun buildBoxFunction(valueClass: IrClass) {
|
||||
val function = context.inlineClassReplacements.getBoxFunction(valueClass)
|
||||
with(context.createIrBuilder(function.symbol)) {
|
||||
function.body = irExprBody(
|
||||
@@ -494,7 +487,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
irClass.declarations += function
|
||||
}
|
||||
|
||||
fun buildSpecializedEqualsMethodIfNeeded(valueClass: IrClass) {
|
||||
private fun buildSpecializedEqualsMethodIfNeeded(valueClass: IrClass) {
|
||||
val function = context.inlineClassReplacements.getSpecializedEqualsMethod(valueClass, context.irBuiltIns)
|
||||
// Return if we have already built specialized equals as static replacement of typed equals
|
||||
if (function.body != null) return
|
||||
|
||||
+60
-53
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irCatch
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
@@ -36,16 +35,14 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val jvmMultiFieldValueClassPhase = makeIrFilePhase(
|
||||
::JvmMultiFieldValueClassLowering,
|
||||
name = "Multi-field Value Classes",
|
||||
description = "Lower multi-field value classes",
|
||||
// Collection stubs may require mangling by multi-field value class rules.
|
||||
// SAM wrappers may require mangling for fun interfaces with multi-field value class parameters
|
||||
prerequisite = setOf(collectionStubMethodLowering, singleAbstractMethodPhase),
|
||||
)
|
||||
internal class JvmMultiFieldValueClassLowering(
|
||||
context: JvmBackendContext,
|
||||
fileClassNewDeclarations: MutableMap<IrFile, MutableList<IrSimpleFunction>>,
|
||||
scopeStack: MutableList<ScopeWithIr>,
|
||||
) : JvmValueClassAbstractLowering(context, fileClassNewDeclarations, scopeStack) {
|
||||
override val IrType.needsHandling: Boolean
|
||||
get() = needsMfvcFlattening()
|
||||
|
||||
private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmValueClassAbstractLowering(context) {
|
||||
private sealed class MfvcNodeInstanceAccessor {
|
||||
abstract val instance: MfvcNodeInstance
|
||||
abstract operator fun get(name: Name): MfvcNodeInstanceAccessor?
|
||||
@@ -268,7 +265,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
variablesToAdd.getOrPut(variable.parent) { mutableSetOf() }.add(variable)
|
||||
}
|
||||
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
override fun visitClassNew(declaration: IrClass): IrClass {
|
||||
|
||||
if (declaration.isSpecificLoweringLogicApplicable()) {
|
||||
handleSpecificNewClass(declaration)
|
||||
@@ -284,25 +281,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
null
|
||||
}).also { declarations ->
|
||||
for (replacingDeclaration in declarations ?: listOf(memberDeclaration)) {
|
||||
when (replacingDeclaration) {
|
||||
is IrFunction -> replacingDeclaration.body = replacingDeclaration.body?.makeBodyWithAddedVariables(
|
||||
context, variablesToAdd[replacingDeclaration] ?: emptySet(), replacingDeclaration.symbol
|
||||
)?.apply {
|
||||
if (replacingDeclaration in possibleExtraBoxUsageGenerated) {
|
||||
removeAllExtraBoxes()
|
||||
}
|
||||
}
|
||||
|
||||
is IrAnonymousInitializer -> replacingDeclaration.body = replacingDeclaration.body.makeBodyWithAddedVariables(
|
||||
context, variablesToAdd[replacingDeclaration.parent] ?: emptySet(), replacingDeclaration.symbol
|
||||
).apply {
|
||||
if (replacingDeclaration in possibleExtraBoxUsageGenerated) {
|
||||
removeAllExtraBoxes()
|
||||
}
|
||||
} as IrBlockBody
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
postActionAfterTransformingClassDeclaration(replacingDeclaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +289,31 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitClassNewDeclarationsWhenParallel(declaration: IrDeclaration) =
|
||||
postActionAfterTransformingClassDeclaration(declaration)
|
||||
|
||||
private fun postActionAfterTransformingClassDeclaration(replacingDeclaration: IrDeclaration) {
|
||||
when (replacingDeclaration) {
|
||||
is IrFunction -> replacingDeclaration.body = replacingDeclaration.body?.makeBodyWithAddedVariables(
|
||||
context, variablesToAdd[replacingDeclaration] ?: emptySet(), replacingDeclaration.symbol
|
||||
)?.apply {
|
||||
if (replacingDeclaration in possibleExtraBoxUsageGenerated) {
|
||||
removeAllExtraBoxes()
|
||||
}
|
||||
}
|
||||
|
||||
is IrAnonymousInitializer -> replacingDeclaration.body = replacingDeclaration.body.makeBodyWithAddedVariables(
|
||||
context, variablesToAdd[replacingDeclaration.parent] ?: emptySet(), replacingDeclaration.symbol
|
||||
).apply {
|
||||
if (replacingDeclaration in possibleExtraBoxUsageGenerated) {
|
||||
removeAllExtraBoxes()
|
||||
}
|
||||
} as IrBlockBody
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNonSpecificNewClass(irClass: IrClass) {
|
||||
irClass.primaryConstructor?.let {
|
||||
replacements.getReplacementForRegularClassConstructor(it)?.let { replacement -> addBindingsFor(it, replacement) }
|
||||
@@ -319,7 +323,8 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
val property = (propertyOrField as? IrPropertyOrIrField.Property)?.property ?: return@mapNotNull null
|
||||
property.backingField?.let { property to it }
|
||||
}.toMap()
|
||||
val propertiesOrFieldsReplacement = collectRegularClassMfvcPropertiesOrFieldsReplacement(propertiesOrFields) // resets backing fields
|
||||
val propertiesOrFieldsReplacement =
|
||||
collectRegularClassMfvcPropertiesOrFieldsReplacement(propertiesOrFields) // resets backing fields
|
||||
|
||||
val fieldsToRemove = propertiesOrFieldsReplacement.keys.mapNotNull {
|
||||
when (it) {
|
||||
@@ -696,7 +701,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
}
|
||||
}
|
||||
|
||||
fun RootMfvcNode.replacePrimaryMultiFieldValueClassConstructor() {
|
||||
private fun RootMfvcNode.replacePrimaryMultiFieldValueClassConstructor() {
|
||||
val rootMfvcNode = this
|
||||
mfvc.declarations.removeIf { it is IrConstructor && it.isPrimary }
|
||||
mfvc.declarations += listOf(newPrimaryConstructor, primaryConstructorImpl)
|
||||
@@ -755,26 +760,28 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
}
|
||||
}
|
||||
|
||||
override val fileClassNewDeclarations = mutableMapOf<IrFile, MutableList<IrSimpleFunction>>()
|
||||
|
||||
private fun createMfvcPrimaryConstructorReferenceHelperFunction(rootNode: RootMfvcNode) = context.irFactory.buildFun {
|
||||
name = Name.identifier("mfvcConstructorReferenceHelper\$${fileClassNewDeclarations[currentFile]?.size ?: 0}")
|
||||
origin = JvmLoweredDeclarationOrigin.MFVC_PRIMARY_CONSTRUCTOR_REFERENCE_HELPER
|
||||
}.apply function@{
|
||||
fileClassNewDeclarations.getOrPut(currentFile) { mutableListOf() }.add(this)
|
||||
copyParameterDeclarationsFrom(rootNode.primaryConstructorImpl)
|
||||
returnType = rootNode.type.substitute(rootNode.mfvc.typeParameters, typeParameters.map { it.defaultType })
|
||||
body = context.createJvmIrBuilder(this.symbol).run {
|
||||
irExprBody(irBlock {
|
||||
for (callee in listOf(rootNode.primaryConstructorImpl, rootNode.boxMethod)) {
|
||||
+irCall(callee).apply {
|
||||
passTypeArgumentsFrom(this@function)
|
||||
for ((index, parameter) in this@function.valueParameters.withIndex()) {
|
||||
putValueArgument(index, irGet(parameter))
|
||||
private fun createMfvcPrimaryConstructorReferenceHelperFunction(rootNode: RootMfvcNode): IrSimpleFunction {
|
||||
val currentFile = currentFile
|
||||
return context.irFactory.buildFun {
|
||||
name = Name.identifier("mfvcConstructorReferenceHelper\$${fileClassNewDeclarations[currentFile]?.size ?: 0}")
|
||||
origin = JvmLoweredDeclarationOrigin.MFVC_PRIMARY_CONSTRUCTOR_REFERENCE_HELPER
|
||||
}.apply function@{
|
||||
parent = currentFile
|
||||
fileClassNewDeclarations.getOrPut(currentFile) { mutableListOf() }.add(this)
|
||||
copyParameterDeclarationsFrom(rootNode.primaryConstructorImpl)
|
||||
returnType = rootNode.type.substitute(rootNode.mfvc.typeParameters, typeParameters.map { it.defaultType })
|
||||
body = context.createJvmIrBuilder(this.symbol).run {
|
||||
irExprBody(irBlock {
|
||||
for (callee in listOf(rootNode.primaryConstructorImpl, rootNode.boxMethod)) {
|
||||
+irCall(callee).apply {
|
||||
passTypeArgumentsFrom(this@function)
|
||||
for ((index, parameter) in this@function.valueParameters.withIndex()) {
|
||||
putValueArgument(index, irGet(parameter))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,7 +978,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
* val b = 3
|
||||
* [a, b, b + 1]
|
||||
*/
|
||||
fun IrBuilderWithScope.removeExtraSetVariablesFromExpressionList(
|
||||
private fun IrBuilderWithScope.removeExtraSetVariablesFromExpressionList(
|
||||
block: IrContainerExpression,
|
||||
variables: List<IrVariable>
|
||||
): List<IrExpression> {
|
||||
@@ -1114,7 +1121,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
/**
|
||||
* Takes not transformed expression and initialized given MfvcNodeInstance with transformed version of it
|
||||
*/
|
||||
fun IrBlockBuilder.flattenExpressionTo(expression: IrExpression, instance: MfvcNodeInstance) {
|
||||
private fun IrBlockBuilder.flattenExpressionTo(expression: IrExpression, instance: MfvcNodeInstance) {
|
||||
val rootNode = replacements.getRootMfvcNodeOrNull(
|
||||
if (expression is IrConstructorCall) expression.symbol.owner.constructedClass else expression.type.erasedUpperBound
|
||||
)
|
||||
@@ -1197,7 +1204,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
/**
|
||||
* Removes boxing when the result is not used
|
||||
*/
|
||||
fun IrBody.removeAllExtraBoxes() {
|
||||
private fun IrBody.removeAllExtraBoxes() {
|
||||
// data is whether the expression result is used
|
||||
accept(object : IrElementVisitor<Unit, Boolean> {
|
||||
override fun visitElement(element: IrElement, data: Boolean) {
|
||||
|
||||
+167
-22
@@ -5,44 +5,37 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendContext) : FileLoweringPass,
|
||||
IrElementTransformerVoidWithContext() {
|
||||
internal abstract class JvmValueClassAbstractLowering(
|
||||
val context: JvmBackendContext,
|
||||
protected val fileClassNewDeclarations: MutableMap<IrFile, MutableList<IrSimpleFunction>>,
|
||||
override val scopeStack: MutableList<ScopeWithIr>,
|
||||
) : FileLoweringPass, IrElementTransformerVoidWithContext() {
|
||||
abstract val replacements: MemoizedValueClassAbstractReplacements
|
||||
|
||||
final override fun lower(irFile: IrFile) {
|
||||
withinScope(irFile) {
|
||||
irFile.transformChildrenVoid()
|
||||
fileClassNewDeclarations[irFile]?.let { newDeclarations ->
|
||||
val oldFileClass = irFile.declarations.filterIsInstanceAnd<IrClass> { it.isFileClass }.singleOrNull()
|
||||
val allFileDeclarations = (oldFileClass?.declarations ?: listOf()) + newDeclarations
|
||||
val newClass = createFileClass(context, irFile, allFileDeclarations)
|
||||
oldFileClass?.let { irFile.declarations.remove(it) }
|
||||
irFile.addChild(newClass)
|
||||
}
|
||||
}
|
||||
final override fun lower(irFile: IrFile) = withinScope(irFile) {
|
||||
irFile.transformChildrenVoid()
|
||||
addDeclarations(context, fileClassNewDeclarations, irFile)
|
||||
}
|
||||
|
||||
abstract fun IrClass.isSpecificLoweringLogicApplicable(): Boolean
|
||||
|
||||
abstract override fun visitClassNew(declaration: IrClass): IrStatement
|
||||
|
||||
abstract fun handleSpecificNewClass(declaration: IrClass)
|
||||
|
||||
protected fun transformFunctionFlat(function: IrFunction): List<IrDeclaration>? {
|
||||
@@ -91,7 +84,7 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformFlattenedConstructor(function: IrConstructor, replacement: IrConstructor): List<IrDeclaration>? {
|
||||
private fun transformFlattenedConstructor(function: IrConstructor, replacement: IrConstructor): List<IrDeclaration> {
|
||||
replacement.valueParameters.forEach {
|
||||
visitParameter(it)
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
@@ -155,7 +148,7 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
return super.visitReturn(expression)
|
||||
}
|
||||
|
||||
private fun visitStatementContainer(container: IrStatementContainer) {
|
||||
internal fun visitStatementContainer(container: IrStatementContainer) {
|
||||
container.statements.transformFlat { statement ->
|
||||
if (statement is IrFunction)
|
||||
transformFunctionFlat(statement)
|
||||
@@ -248,5 +241,157 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
|
||||
protected abstract fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean)
|
||||
|
||||
protected open val fileClassNewDeclarations: Map<IrFile, List<IrSimpleFunction>> = emptyMap()
|
||||
|
||||
// Functions for common lowering dispatching
|
||||
private inner class NeedsToVisit : IrElementVisitor<Boolean, Nothing?> {
|
||||
override fun visitElement(element: IrElement, data: Nothing?): Boolean = false
|
||||
override fun visitClass(declaration: IrClass, data: Nothing?): Boolean =
|
||||
declaration.isSpecificLoweringLogicApplicable() || declaration.declarations.any { it.accept(this, null) }
|
||||
|
||||
override fun visitFunction(declaration: IrFunction, data: Nothing?): Boolean =
|
||||
replacements.quickCheckIfFunctionIsNotApplicable(declaration)
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): Boolean =
|
||||
visitFunction(expression.symbol.owner, data)
|
||||
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: Nothing?): Boolean =
|
||||
visitFunction(expression.symbol.owner, data)
|
||||
|
||||
override fun visitField(declaration: IrField, data: Nothing?): Boolean = declaration.type.needsHandling
|
||||
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: Nothing?): Boolean =
|
||||
visitField(expression.symbol.owner, data)
|
||||
|
||||
override fun visitVariable(declaration: IrVariable, data: Nothing?): Boolean = visitValueDeclaration(declaration)
|
||||
|
||||
private fun visitValueDeclaration(declaration: IrValueDeclaration) = declaration.type.needsHandling
|
||||
override fun visitValueParameter(declaration: IrValueParameter, data: Nothing?): Boolean = visitValueDeclaration(declaration)
|
||||
override fun visitValueAccess(expression: IrValueAccessExpression, data: Nothing?): Boolean =
|
||||
visitValueDeclaration(expression.symbol.owner)
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): Boolean = false
|
||||
override fun visitReturn(expression: IrReturn, data: Nothing?): Boolean = expression.returnTargetSymbol.owner.safeAs<IrFunction>()
|
||||
?.let { replacements.quickCheckIfFunctionIsNotApplicable(it) } ?: false
|
||||
|
||||
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?): Boolean =
|
||||
declaration.parent.safeAs<IrClass>()?.isSpecificLoweringLogicApplicable() == true
|
||||
|
||||
private fun visitStatementContainer(container: IrStatementContainer) = container.statements.any { it.accept(this, null) }
|
||||
|
||||
override fun visitContainerExpression(expression: IrContainerExpression, data: Nothing?): Boolean =
|
||||
visitStatementContainer(expression)
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody, data: Nothing?): Boolean = visitStatementContainer(body)
|
||||
}
|
||||
|
||||
internal fun needsToVisitClassNew(declaration: IrClass): Boolean = declaration.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitFunctionReference(expression: IrFunctionReference): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitFunctionAccess(expression: IrFunctionAccessExpression): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitCall(expression: IrCall): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitStringConcatenation(expression: IrStringConcatenation): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitGetField(expression: IrGetField): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitSetField(expression: IrSetField): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitGetValue(expression: IrGetValue): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitSetValue(expression: IrSetValue): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitVariable(declaration: IrVariable): Boolean = declaration.accept(NeedsToVisit(), null)
|
||||
|
||||
internal fun needsToVisitReturn(expression: IrReturn): Boolean = expression.accept(NeedsToVisit(), null)
|
||||
internal abstract fun visitClassNewDeclarationsWhenParallel(declaration: IrDeclaration)
|
||||
|
||||
// forbid other overrides without modifying dispatcher file JvmValueClassLoweringDispatcher.kt
|
||||
|
||||
final override fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = super.visitModuleFragment(declaration)
|
||||
final override fun visitPackageFragment(declaration: IrPackageFragment): IrPackageFragment = super.visitPackageFragment(declaration)
|
||||
final override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment): IrExternalPackageFragment =
|
||||
super.visitExternalPackageFragment(declaration)
|
||||
|
||||
final override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement = super.visitDeclaration(declaration)
|
||||
final override fun visitSimpleFunction(declaration: IrSimpleFunction) = super.visitSimpleFunction(declaration)
|
||||
final override fun visitConstructor(declaration: IrConstructor) = super.visitConstructor(declaration)
|
||||
final override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty) = super.visitLocalDelegatedProperty(declaration)
|
||||
final override fun visitEnumEntry(declaration: IrEnumEntry) = super.visitEnumEntry(declaration)
|
||||
final override fun visitTypeParameter(declaration: IrTypeParameter) = super.visitTypeParameter(declaration)
|
||||
final override fun visitTypeAlias(declaration: IrTypeAlias) = super.visitTypeAlias(declaration)
|
||||
final override fun visitBody(body: IrBody): IrBody = super.visitBody(body)
|
||||
final override fun visitExpressionBody(body: IrExpressionBody) = super.visitExpressionBody(body)
|
||||
final override fun visitSyntheticBody(body: IrSyntheticBody) = super.visitSyntheticBody(body)
|
||||
final override fun visitSuspendableExpression(expression: IrSuspendableExpression) = super.visitSuspendableExpression(expression)
|
||||
final override fun visitSuspensionPoint(expression: IrSuspensionPoint) = super.visitSuspensionPoint(expression)
|
||||
final override fun visitExpression(expression: IrExpression): IrExpression = super.visitExpression(expression)
|
||||
final override fun visitConst(expression: IrConst<*>) = super.visitConst(expression)
|
||||
final override fun visitConstantValue(expression: IrConstantValue): IrConstantValue = super.visitConstantValue(expression)
|
||||
final override fun visitConstantObject(expression: IrConstantObject) = super.visitConstantObject(expression)
|
||||
final override fun visitConstantPrimitive(expression: IrConstantPrimitive) = super.visitConstantPrimitive(expression)
|
||||
final override fun visitConstantArray(expression: IrConstantArray) = super.visitConstantArray(expression)
|
||||
final override fun visitVararg(expression: IrVararg) = super.visitVararg(expression)
|
||||
final override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement = super.visitSpreadElement(spread)
|
||||
final override fun visitBlock(expression: IrBlock) = super.visitBlock(expression)
|
||||
final override fun visitComposite(expression: IrComposite) = super.visitComposite(expression)
|
||||
final override fun visitDeclarationReference(expression: IrDeclarationReference) = super.visitDeclarationReference(expression)
|
||||
final override fun visitSingletonReference(expression: IrGetSingletonValue) = super.visitSingletonReference(expression)
|
||||
final override fun visitGetObjectValue(expression: IrGetObjectValue) = super.visitGetObjectValue(expression)
|
||||
final override fun visitGetEnumValue(expression: IrGetEnumValue) = super.visitGetEnumValue(expression)
|
||||
final override fun visitValueAccess(expression: IrValueAccessExpression) = super.visitValueAccess(expression)
|
||||
final override fun visitFieldAccess(expression: IrFieldAccessExpression) = super.visitFieldAccess(expression)
|
||||
final override fun visitMemberAccess(expression: IrMemberAccessExpression<*>) = super.visitMemberAccess(expression)
|
||||
final override fun visitConstructorCall(expression: IrConstructorCall) = super.visitConstructorCall(expression)
|
||||
final override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) =
|
||||
super.visitDelegatingConstructorCall(expression)
|
||||
|
||||
final override fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = super.visitEnumConstructorCall(expression)
|
||||
final override fun visitGetClass(expression: IrGetClass) = super.visitGetClass(expression)
|
||||
final override fun visitCallableReference(expression: IrCallableReference<*>) = super.visitCallableReference(expression)
|
||||
final override fun visitPropertyReference(expression: IrPropertyReference) = super.visitPropertyReference(expression)
|
||||
final override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference) =
|
||||
super.visitLocalDelegatedPropertyReference(expression)
|
||||
|
||||
final override fun visitRawFunctionReference(expression: IrRawFunctionReference) = super.visitRawFunctionReference(expression)
|
||||
final override fun visitFunctionExpression(expression: IrFunctionExpression) = super.visitFunctionExpression(expression)
|
||||
final override fun visitClassReference(expression: IrClassReference) = super.visitClassReference(expression)
|
||||
final override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = super.visitInstanceInitializerCall(expression)
|
||||
final override fun visitTypeOperator(expression: IrTypeOperatorCall) = super.visitTypeOperator(expression)
|
||||
final override fun visitWhen(expression: IrWhen) = super.visitWhen(expression)
|
||||
final override fun visitBranch(branch: IrBranch): IrBranch = super.visitBranch(branch)
|
||||
final override fun visitElseBranch(branch: IrElseBranch): IrElseBranch = super.visitElseBranch(branch)
|
||||
final override fun visitLoop(loop: IrLoop) = super.visitLoop(loop)
|
||||
final override fun visitWhileLoop(loop: IrWhileLoop) = super.visitWhileLoop(loop)
|
||||
final override fun visitDoWhileLoop(loop: IrDoWhileLoop) = super.visitDoWhileLoop(loop)
|
||||
final override fun visitTry(aTry: IrTry) = super.visitTry(aTry)
|
||||
final override fun visitCatch(aCatch: IrCatch): IrCatch = super.visitCatch(aCatch)
|
||||
final override fun visitBreakContinue(jump: IrBreakContinue) = super.visitBreakContinue(jump)
|
||||
final override fun visitBreak(jump: IrBreak) = super.visitBreak(jump)
|
||||
final override fun visitContinue(jump: IrContinue) = super.visitContinue(jump)
|
||||
final override fun visitThrow(expression: IrThrow) = super.visitThrow(expression)
|
||||
final override fun visitDynamicExpression(expression: IrDynamicExpression) = super.visitDynamicExpression(expression)
|
||||
final override fun visitDynamicOperatorExpression(expression: IrDynamicOperatorExpression) =
|
||||
super.visitDynamicOperatorExpression(expression)
|
||||
|
||||
final override fun visitDynamicMemberExpression(expression: IrDynamicMemberExpression) = super.visitDynamicMemberExpression(expression)
|
||||
final override fun visitErrorDeclaration(declaration: IrErrorDeclaration) = super.visitErrorDeclaration(declaration)
|
||||
final override fun visitErrorExpression(expression: IrErrorExpression) = super.visitErrorExpression(expression)
|
||||
final override fun visitErrorCallExpression(expression: IrErrorCallExpression) = super.visitErrorCallExpression(expression)
|
||||
|
||||
companion object {
|
||||
internal fun addDeclarations(
|
||||
context: JvmBackendContext, fileClassNewDeclarations: MutableMap<IrFile, MutableList<IrSimpleFunction>>, irFile: IrFile
|
||||
) {
|
||||
fileClassNewDeclarations[irFile]?.let { newDeclarations ->
|
||||
val oldFileClass = irFile.declarations.filterIsInstanceAnd<IrClass> { it.isFileClass }.singleOrNull()
|
||||
val allFileDeclarations = (oldFileClass?.declarations ?: listOf()) + newDeclarations
|
||||
val newClass = createFileClass(context, irFile, allFileDeclarations)
|
||||
oldFileClass?.let { irFile.declarations.remove(it) }
|
||||
irFile.addChild(newClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract val IrType.needsHandling: Boolean
|
||||
}
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
val jvmValueClassPhase = makeIrFilePhase(
|
||||
::JvmValueClassLoweringDispatcher,
|
||||
name = "Value Classes",
|
||||
description = "Lower value classes",
|
||||
// forLoopsPhase may produce UInt and ULong which are inline classes.
|
||||
// Standard library replacements are done on the not mangled names for UInt and ULong classes.
|
||||
// Collection stubs may require mangling by value class rules.
|
||||
// SAM wrappers may require mangling for fun interfaces with value class parameters
|
||||
prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase),
|
||||
)
|
||||
|
||||
internal class JvmValueClassLoweringDispatcher(
|
||||
private val context: JvmBackendContext,
|
||||
private val fileClassNewDeclarations: MutableMap<IrFile, MutableList<IrSimpleFunction>> = mutableMapOf(),
|
||||
override val scopeStack: MutableList<ScopeWithIr> = mutableListOf(),
|
||||
private val inlineClassLowering: JvmInlineClassLowering = JvmInlineClassLowering(context, fileClassNewDeclarations, scopeStack),
|
||||
private val multiFieldValueClassLowering: JvmMultiFieldValueClassLowering =
|
||||
JvmMultiFieldValueClassLowering(context, fileClassNewDeclarations, scopeStack),
|
||||
) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
|
||||
|
||||
override fun lower(irFile: IrFile) = withinScope(irFile) {
|
||||
irFile.transformChildrenVoid()
|
||||
JvmValueClassAbstractLowering.addDeclarations(context, fileClassNewDeclarations, irFile)
|
||||
}
|
||||
|
||||
|
||||
private fun IrElement.requiresAnyHandling() =
|
||||
requiresHandling(multiFieldValueClassLowering) || requiresHandling(inlineClassLowering)
|
||||
|
||||
override fun visitClassNew(declaration: IrClass): IrClass = if (declaration.requiresAnyHandling()) {
|
||||
declaration
|
||||
.let(multiFieldValueClassLowering::visitClassNew)
|
||||
.let(inlineClassLowering::visitClassNew)
|
||||
} else {
|
||||
declaration.transformChildrenVoid()
|
||||
for (innerDeclaration in declaration.declarations) {
|
||||
multiFieldValueClassLowering.visitClassNewDeclarationsWhenParallel(innerDeclaration)
|
||||
}
|
||||
for (innerDeclaration in declaration.declarations) {
|
||||
inlineClassLowering.visitClassNewDeclarationsWhenParallel(innerDeclaration)
|
||||
}
|
||||
declaration
|
||||
}
|
||||
|
||||
private fun transformExpressionConsequently(expression: IrExpression) = expression
|
||||
.transform(multiFieldValueClassLowering, null)
|
||||
.transform(inlineClassLowering, null)
|
||||
|
||||
private fun transformStatementConsequently(statement: IrStatement) = statement
|
||||
.transformStatement(multiFieldValueClassLowering)
|
||||
.transformStatement(inlineClassLowering)
|
||||
|
||||
private fun IrElement.requiresHandling(lowering: JvmValueClassAbstractLowering) =
|
||||
accept(object : IrElementVisitor<Boolean, Nothing?> {
|
||||
override fun visitElement(element: IrElement, data: Nothing?): Boolean = false
|
||||
override fun visitClass(declaration: IrClass, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitClassNew(declaration) || super.visitClass(declaration, data)
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitFunctionReference(expression) || super.visitFunctionReference(expression, data)
|
||||
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitFunctionAccess(expression) || super.visitFunctionAccess(expression, data)
|
||||
|
||||
override fun visitCall(expression: IrCall, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitCall(expression) || super.visitCall(expression, data)
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitStringConcatenation(expression) || super.visitStringConcatenation(expression, data)
|
||||
|
||||
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitGetField(expression) || super.visitGetField(expression, data)
|
||||
|
||||
override fun visitSetField(expression: IrSetField, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitSetField(expression) || super.visitSetField(expression, data)
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitGetValue(expression) || super.visitGetValue(expression, data)
|
||||
|
||||
override fun visitSetValue(expression: IrSetValue, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitSetValue(expression) || super.visitSetValue(expression, data)
|
||||
|
||||
override fun visitVariable(declaration: IrVariable, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitVariable(declaration) || super.visitVariable(declaration, data)
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Nothing?): Boolean =
|
||||
lowering.needsToVisitReturn(expression) || super.visitReturn(expression, data)
|
||||
}, null)
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitFunctionReference(expression)
|
||||
}
|
||||
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitFunctionAccess(expression)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitCall(expression)
|
||||
}
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitStringConcatenation(expression)
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitGetField(expression)
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitSetField(expression)
|
||||
}
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitGetValue(expression)
|
||||
}
|
||||
|
||||
override fun visitSetValue(expression: IrSetValue): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitSetValue(expression)
|
||||
}
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrStatement = if (declaration.requiresAnyHandling()) {
|
||||
transformStatementConsequently(declaration)
|
||||
} else {
|
||||
super.visitVariable(declaration)
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression = if (expression.requiresAnyHandling()) {
|
||||
transformExpressionConsequently(expression)
|
||||
} else {
|
||||
super.visitReturn(expression)
|
||||
}
|
||||
|
||||
override fun visitAnonymousInitializerNew(declaration: IrAnonymousInitializer): IrStatement = if (declaration.requiresAnyHandling()) {
|
||||
transformStatementConsequently(declaration)
|
||||
} else {
|
||||
super.visitAnonymousInitializerNew(declaration)
|
||||
}
|
||||
|
||||
private fun visitStatementContainer(container: IrStatementContainer) = if (container.statements.any { it.requiresAnyHandling() }) {
|
||||
multiFieldValueClassLowering.visitStatementContainer(container)
|
||||
inlineClassLowering.visitStatementContainer(container)
|
||||
} else {
|
||||
container.statements.replaceAll { it.transformStatement(this) }
|
||||
}
|
||||
|
||||
override fun visitContainerExpression(expression: IrContainerExpression): IrExpression {
|
||||
visitStatementContainer(expression)
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody): IrBody {
|
||||
visitStatementContainer(body)
|
||||
return body
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -95,7 +95,7 @@ abstract class MemoizedValueClassAbstractReplacements(
|
||||
annotations = propertySymbol.owner.annotations
|
||||
// In case this property is declared in an object in another file which is not yet lowered, its backing field will
|
||||
// be made static later. We have to handle it here though, because this new property will be saved to the cache
|
||||
// and reused when lowering the same call in all subsequent files, which would be incorrect if it was unlowered.
|
||||
// and reused when lowering the same call in all subsequent files, which would be incorrect if it was not lowered.
|
||||
backingField = context.cachedDeclarations.getStaticBackingField(propertySymbol.owner)
|
||||
?: propertySymbol.owner.backingField
|
||||
}
|
||||
@@ -132,5 +132,5 @@ abstract class MemoizedValueClassAbstractReplacements(
|
||||
function.overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
|
||||
protected abstract fun quickCheckIfFunctionIsNotApplicable(function: IrFunction): Boolean
|
||||
abstract fun quickCheckIfFunctionIsNotApplicable(function: IrFunction): Boolean
|
||||
}
|
||||
Reference in New Issue
Block a user