JVM: remove support for disabling NoConstantValueAttributeForNonConstVals

This feature is enabled by default since 1.4, which is the earliest
language version supported by Kotlin at this moment.
This commit is contained in:
Alexander Udalov
2021-09-10 02:01:10 +02:00
parent d07070e184
commit e857966edb
22 changed files with 20 additions and 202 deletions
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext;
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
@@ -344,7 +343,7 @@ public class PropertyCodegen {
defaultValue = null;
}
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
if (shouldWriteFieldInitializer(descriptor)) {
if (descriptor.isConst()) {
ConstantValue<?> initializer = descriptor.getCompileTimeInitializer();
defaultValue = initializer == null ? null : initializer.getValue();
}
@@ -488,20 +487,6 @@ public class PropertyCodegen {
return delegateType;
}
private boolean shouldWriteFieldInitializer(@NotNull PropertyDescriptor descriptor) {
if (!descriptor.isConst() &&
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.NoConstantValueAttributeForNonConstVals)) {
return false;
}
//final field of primitive or String type
if (!descriptor.isVar()) {
Type type = typeMapper.mapType(descriptor);
return AsmUtil.isPrimitive(type) || "java.lang.String".equals(type.getClassName());
}
return false;
}
private void generateGetter(@NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor getter) {
generateAccessor(
getter,
@@ -2534,11 +2534,6 @@ public class FirLoadCompiledKotlinGenerated extends AbstractFirLoadCompiledKotli
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");
@@ -299,13 +299,12 @@ class FirElementSerializer private constructor(
}
}
val hasConstant = property.isConst // TODO: this is only correct with LanguageFeature.NoConstantValueAttributeForNonConstVals
val flags = Flags.getPropertyFlags(
hasAnnotations,
ProtoEnumFlags.visibility(normalizeVisibility(property)),
ProtoEnumFlags.modality(modality),
ProtoBuf.MemberKind.DECLARATION,
property.isVar, hasGetter, hasSetter, hasConstant, property.isConst, property.isLateInit,
property.isVar, hasGetter, hasSetter, property.isConst, property.isConst, property.isLateInit,
property.isExternal, property.delegateFieldSymbol != null, property.isExpect
)
if (flags != builder.flags) {
@@ -1439,15 +1439,9 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_after.kt")
public void testNonConstValHasNoDefaultValue_after() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_after.kt");
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_before.kt")
public void testNonConstValHasNoDefaultValue_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_before.kt");
@TestMetadata("nonConstValHasNoDefaultValue.kt")
public void testNonConstValHasNoDefaultValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue.kt");
}
}
@@ -230,7 +230,7 @@ private val initializersPhase = makeIrFilePhase(
private val initializersCleanupPhase = makeIrFilePhase(
{ context ->
InitializersCleanupLowering(context) {
it.constantValue(context) == null && (!it.isStatic || it.correspondingPropertySymbol?.owner?.isConst != true)
it.constantValue() == null && (!it.isStatic || it.correspondingPropertySymbol?.owner?.isConst != true)
}
},
name = "InitializersCleanup",
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -16,8 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.isStringClassType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.ConstantRef
@@ -40,18 +37,15 @@ internal val constPhase2 = makeIrFilePhase(
description = "Substitute calls to const properties with constant values"
)
fun IrField.constantValue(context: JvmBackendContext? = null): IrConst<*>? {
fun IrField.constantValue(): IrConst<*>? {
val value = initializer?.expression as? IrConst<*> ?: return null
// 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 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 = isFinal && ((isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) ||
(allowImplicitConst && (type.isPrimitiveType() || type.isStringClassType())))
// It is only allowed on final fields of primitive/string types. Java applies it whenever possible; Kotlin only applies it to
// `const val`s to avoid making values part of the library's ABI unless explicitly requested by the author.
val implicitConst = isFinal && isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
return if (implicitConst || correspondingPropertySymbol?.owner?.isConst == true) value else null
}
@@ -25,7 +25,7 @@ class StaticInitializersLowering(override val context: JvmBackendContext) : Init
val staticInitializerStatements = extractInitializers(irClass) {
// JVM implementations are required to generate initializers for all static fields with ConstantValue,
// so don't add any to <clinit>.
(it is IrField && it.isStatic && it.constantValue(context) == null) || (it is IrAnonymousInitializer && it.isStatic)
(it is IrField && it.isStatic && it.constantValue() == null) || (it is IrAnonymousInitializer && it.isStatic)
}.toMutableList()
if (staticInitializerStatements.isNotEmpty()) {
staticInitializerStatements.sortBy {
+1 -3
View File
@@ -1,7 +1,5 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: MINOR: CONST_EQUIVALENCE
// !LANGUAGE: -NoConstantValueAttributeForNonConstVals
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: NATIVE
object A {
@@ -33,4 +31,4 @@ fun box(): String {
if (A.bNullable !== B.bNullable) return "Fail 5: A.bNullable !== B.bNullable"
return "OK"
}
}
@@ -1,4 +1,3 @@
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -64,4 +63,4 @@ fun box(): String {
assertEquals(400, testTopLevelVal)
return "OK"
}
}
@@ -1,5 +1,3 @@
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
class C {
val testClassVal = 100
@@ -1,61 +0,0 @@
// !LANGUAGE: -NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
class C {
val testClassVal = 100
@JvmField
val testJvmFieldVal = 105
companion object {
val testCompanionObjectVal = 110
@JvmStatic
val testJvmStaticCompanionObjectVal = 120
@JvmField
val testJvmFieldCompanionObjectVal = 130
}
}
interface IFoo {
companion object {
val testInterfaceCompanionObjectVal = 200
}
}
interface IBar {
companion object {
@JvmField
val testJvmFieldInInterfaceCompanionObject = 210
}
}
object Obj {
val testObjectVal = 300
@JvmStatic
val testJvmStaticObjectVal = 310
@JvmField
val testJvmFieldObjectVal = 320
}
val testTopLevelVal = 400
// 1 final I testClassVal = 100
// 1 final I testJvmFieldVal = 105
// 1 final static I testCompanionObjectVal = 110
// 1 final static I testJvmStaticCompanionObjectVal = 120
// 1 final static I testJvmFieldCompanionObjectVal = 130
// 1 final static I testInterfaceCompanionObjectVal = 200
// 1 final static I testJvmFieldInInterfaceCompanionObject = 210
// 1 final static I testObjectVal = 300
// 1 final static I testJvmStaticObjectVal = 310
// 1 final static I testJvmFieldObjectVal = 320
// 1 final static I testTopLevelVal = 400
@@ -1,4 +1,3 @@
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals
val a = 1.0 + 10
val b = 2 + 10.0
val c = 3.0F + 10
@@ -1,19 +0,0 @@
// !LANGUAGE: -NoConstantValueAttributeForNonConstVals
//ALLOW_AST_ACCESS
package test
val nonConstVal1 = 1
class C {
val nonConstVal2 = 2
companion object {
val nonConstVal3 = 3
}
}
interface I {
companion object {
val nonConstVal4 = 4
}
}
@@ -1,25 +0,0 @@
package test
public val nonConstVal1: kotlin.Int = 1
public fun <get-nonConstVal1>(): kotlin.Int
public final class C {
/*primary*/ public constructor C()
public final val nonConstVal2: kotlin.Int = 2
public final fun <get-nonConstVal2>(): kotlin.Int
public companion object Companion {
/*primary*/ private constructor Companion()
public final val nonConstVal3: kotlin.Int = 3
public final fun <get-nonConstVal3>(): kotlin.Int
}
}
public interface I {
public companion object Companion {
/*primary*/ private constructor Companion()
public final val nonConstVal4: kotlin.Int = 4
public final fun <get-nonConstVal4>(): kotlin.Int
}
}
@@ -1427,15 +1427,9 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_after.kt")
public void testNonConstValHasNoDefaultValue_after() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_after.kt");
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_before.kt")
public void testNonConstValHasNoDefaultValue_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_before.kt");
@TestMetadata("nonConstValHasNoDefaultValue.kt")
public void testNonConstValHasNoDefaultValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue.kt");
}
}
@@ -1439,15 +1439,9 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_after.kt")
public void testNonConstValHasNoDefaultValue_after() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_after.kt");
}
@Test
@TestMetadata("nonConstValHasNoDefaultValue_before.kt")
public void testNonConstValHasNoDefaultValue_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue_before.kt");
@TestMetadata("nonConstValHasNoDefaultValue.kt")
public void testNonConstValHasNoDefaultValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/constProperty/nonConstValHasNoDefaultValue.kt");
}
}
@@ -4212,11 +4212,6 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");
@@ -2534,11 +2534,6 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");
@@ -4213,11 +4213,6 @@ public class IrLoadJavaTestGenerated extends AbstractIrLoadJavaTest {
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");
@@ -4212,11 +4212,6 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");
@@ -2536,11 +2536,6 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
runTest("compiler/testData/loadJava/compiledKotlin/prop/ExtVarl.kt");
}
@TestMetadata("nonConstValWithConstantValueAttribute.kt")
public void testNonConstValWithConstantValueAttribute() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/nonConstValWithConstantValueAttribute.kt");
}
@TestMetadata("NsVal.kt")
public void testNsVal() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/prop/NsVal.kt");