JVM_IR: do not erase constant non-static field initializers...
...unless in 1.4 mode.
This commit is contained in:
+9
-2
@@ -51,14 +51,21 @@ abstract class InitializersLoweringBase(open val context: CommonBackendContext)
|
||||
irClass.declarations.removeAll { it is IrAnonymousInitializer && filter(it) }
|
||||
}
|
||||
|
||||
protected open fun shouldEraseFieldInitializer(irField: IrField): Boolean = true
|
||||
|
||||
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
|
||||
declaration.initializer = null
|
||||
IrSetFieldImpl(startOffset, endOffset, declaration.symbol, receiver, expression, context.irBuiltIns.unitType)
|
||||
val value = if (shouldEraseFieldInitializer(declaration)) {
|
||||
declaration.initializer = null
|
||||
expression
|
||||
} else {
|
||||
expression.deepCopyWithSymbols()
|
||||
}
|
||||
IrSetFieldImpl(startOffset, endOffset, declaration.symbol, receiver, value, context.irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
private fun handleAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement =
|
||||
|
||||
@@ -173,8 +173,13 @@ private val staticInitializersPhase = makeIrFilePhase(
|
||||
description = "Move code from object init blocks and static field initializers to a new <clinit> function"
|
||||
)
|
||||
|
||||
private val initializersPhase = makeIrFilePhase(
|
||||
::InitializersLowering,
|
||||
private val initializersPhase = makeIrFilePhase<JvmBackendContext>(
|
||||
{ context ->
|
||||
object : InitializersLowering(context) {
|
||||
override fun shouldEraseFieldInitializer(irField: IrField): Boolean =
|
||||
irField.constantValue(context) == null
|
||||
}
|
||||
},
|
||||
name = "Initializers",
|
||||
description = "Merge init blocks and field initializers into constructors",
|
||||
stickyPostconditions = setOf(fun(irFile: IrFile) {
|
||||
|
||||
@@ -33,12 +33,12 @@ fun IrField.constantValue(context: JvmBackendContext? = null): IrConst<*>? {
|
||||
// JVM has a ConstantValue attribute which does two things:
|
||||
// 1. allows the field to be inlined into other modules;
|
||||
// 2. implicitly generates an initialization of that field in <clinit>
|
||||
// It is only allowed on static final fields of primitive/string types. Java and Kotlin < 1.4
|
||||
// It is only allowed on final fields of primitive/string types. Java and Kotlin < 1.4
|
||||
// apply it whenever possible; Kotlin >= 1.4 only applies it to `const val`s to avoid making
|
||||
// values part of the library's ABI unless explicitly requested by the author.
|
||||
val allowImplicitConst =
|
||||
context != null && !context.state.languageVersionSettings.supportsFeature(LanguageFeature.NoConstantValueAttributeForNonConstVals)
|
||||
val implicitConst = isStatic && isFinal && (origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB ||
|
||||
val implicitConst = isFinal && ((isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) ||
|
||||
(allowImplicitConst && (type.isPrimitiveType() || type.isStringClassType())))
|
||||
return if (implicitConst || correspondingPropertySymbol?.owner?.isConst == true) value else null
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: -NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
class C {
|
||||
val testClassVal = 100
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: -NoConstantValueAttributeForNonConstVals
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
//ALLOW_AST_ACCESS
|
||||
|
||||
package test
|
||||
|
||||
Reference in New Issue
Block a user