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:
@@ -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,
|
||||
|
||||
-5
@@ -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");
|
||||
|
||||
+1
-2
@@ -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) {
|
||||
|
||||
+3
-9
@@ -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",
|
||||
|
||||
+5
-11
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -1,4 +1,3 @@
|
||||
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -64,4 +63,4 @@ fun box(): String {
|
||||
assertEquals(400, testTopLevelVal)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
// !LANGUAGE: +NoConstantValueAttributeForNonConstVals +JvmFieldInInterface
|
||||
|
||||
class C {
|
||||
val testClassVal = 100
|
||||
|
||||
Vendored
-61
@@ -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
|
||||
|
||||
-19
@@ -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
|
||||
}
|
||||
}
|
||||
-25
@@ -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
|
||||
}
|
||||
}
|
||||
+3
-9
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-9
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-5
@@ -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");
|
||||
|
||||
Generated
-5
@@ -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");
|
||||
|
||||
-5
@@ -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");
|
||||
|
||||
Generated
-5
@@ -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");
|
||||
|
||||
-5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user