[Commonizer] Fallback for const val properties with different values
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|||||||
interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
|
interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
|
||||||
val isVar: Boolean
|
val isVar: Boolean
|
||||||
val isLateInit: Boolean
|
val isLateInit: Boolean
|
||||||
val isConst: Boolean
|
var isConst: Boolean
|
||||||
val isDelegate: Boolean
|
val isDelegate: Boolean
|
||||||
val getter: CirPropertyGetter?
|
val getter: CirPropertyGetter?
|
||||||
val setter: CirPropertySetter?
|
val setter: CirPropertySetter?
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ data class CirPropertyImpl(
|
|||||||
override val kind: CallableMemberDescriptor.Kind,
|
override val kind: CallableMemberDescriptor.Kind,
|
||||||
override val isVar: Boolean,
|
override val isVar: Boolean,
|
||||||
override val isLateInit: Boolean,
|
override val isLateInit: Boolean,
|
||||||
override val isConst: Boolean,
|
override var isConst: Boolean,
|
||||||
override val isDelegate: Boolean,
|
override val isDelegate: Boolean,
|
||||||
override val getter: CirPropertyGetter?,
|
override val getter: CirPropertyGetter?,
|
||||||
override val setter: CirPropertySetter?,
|
override val setter: CirPropertySetter?,
|
||||||
|
|||||||
+45
-9
@@ -8,17 +8,25 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
|
|||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyGetterFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyGetterFactory
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
|
|
||||||
class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirProperty>(cache) {
|
class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirProperty>(cache) {
|
||||||
private val setter = PropertySetterCommonizer()
|
private val setter = PropertySetterCommonizer()
|
||||||
private var isExternal = true
|
private var isExternal = true
|
||||||
private var constCompileTimeInitializer: ConstantValue<*>? = null
|
private lateinit var constCommonizationState: ConstCommonizationState
|
||||||
|
|
||||||
override fun commonizationResult(): CirProperty {
|
override fun commonizationResult(): CirProperty {
|
||||||
val setter = setter.result
|
val setter = setter.result
|
||||||
val constCompileTimeInitializer = constCompileTimeInitializer
|
|
||||||
|
val constCommonizationState = constCommonizationState
|
||||||
|
val constCompileTimeInitializer = (constCommonizationState as? ConstSameValue)?.compileTimeInitializer
|
||||||
|
|
||||||
|
if (constCommonizationState is ConstMultipleValues) {
|
||||||
|
// fix all commonized properties to make then non-const
|
||||||
|
constCommonizationState.properties.forEach { it.isConst = false }
|
||||||
|
}
|
||||||
|
|
||||||
return CirPropertyFactory.create(
|
return CirPropertyFactory.create(
|
||||||
annotations = emptyList(),
|
annotations = emptyList(),
|
||||||
@@ -46,8 +54,10 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
|
|||||||
override fun initialize(first: CirProperty) {
|
override fun initialize(first: CirProperty) {
|
||||||
super.initialize(first)
|
super.initialize(first)
|
||||||
|
|
||||||
if (first.isConst) {
|
constCommonizationState = if (first.isConst) {
|
||||||
constCompileTimeInitializer = first.compileTimeInitializer
|
first.compileTimeInitializer?.let(::ConstSameValue) ?: NonConst
|
||||||
|
} else {
|
||||||
|
NonConst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,16 +67,28 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val constCompileTimeInitializer = constCompileTimeInitializer
|
val constCommonizationState = constCommonizationState
|
||||||
if (next.isConst) {
|
if (next.isConst) {
|
||||||
// const properties should be lifted up
|
// const properties should be lifted up
|
||||||
// otherwise commonization should fail: expect property can't be const because expect can't have initializer
|
// otherwise commonization should fail: expect property can't be const because expect can't have initializer
|
||||||
|
when (constCommonizationState) {
|
||||||
|
NonConst -> {
|
||||||
|
// previous property was not constant
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
is Const -> {
|
||||||
|
// previous property was constant
|
||||||
|
constCommonizationState.properties += next
|
||||||
|
|
||||||
if (constCompileTimeInitializer == null || constCompileTimeInitializer != next.compileTimeInitializer) {
|
if (constCommonizationState is ConstSameValue) {
|
||||||
// previous property was not constant or const properties have different constants
|
if (constCommonizationState.compileTimeInitializer != next.compileTimeInitializer) {
|
||||||
return false
|
// const properties have different constants
|
||||||
|
this.constCommonizationState = ConstMultipleValues(constCommonizationState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (constCompileTimeInitializer != null) {
|
} else if (constCommonizationState != NonConst) {
|
||||||
// previous property was constant but this one is not
|
// previous property was constant but this one is not
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -80,4 +102,18 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class ConstCommonizationState {
|
||||||
|
object NonConst : ConstCommonizationState()
|
||||||
|
abstract class Const : ConstCommonizationState() {
|
||||||
|
val properties: MutableList<CirProperty> = mutableListOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConstSameValue(val compileTimeInitializer: ConstantValue<*>) : Const()
|
||||||
|
class ConstMultipleValues(previous: ConstSameValue) : Const() {
|
||||||
|
init {
|
||||||
|
properties += previous.properties
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+8
@@ -2,10 +2,18 @@ const val property1 = 42
|
|||||||
expect val property4: Int
|
expect val property4: Int
|
||||||
|
|
||||||
const val property5: Byte = 42
|
const val property5: Byte = 42
|
||||||
|
expect val property6: Byte
|
||||||
const val property7: Short = 42
|
const val property7: Short = 42
|
||||||
|
expect val property8: Short
|
||||||
const val property9: Long = 42
|
const val property9: Long = 42
|
||||||
|
expect val property10: Long
|
||||||
const val property11: Double = 4.2
|
const val property11: Double = 4.2
|
||||||
|
expect val property12: Double
|
||||||
const val property13: Float = 4.2f
|
const val property13: Float = 4.2f
|
||||||
|
expect val property14: Float
|
||||||
const val property15 = true
|
const val property15 = true
|
||||||
|
expect val property16: Boolean
|
||||||
const val property17 = "42"
|
const val property17 = "42"
|
||||||
|
expect val property18: String
|
||||||
const val property19: Char = 42.toChar()
|
const val property19: Char = 42.toChar()
|
||||||
|
expect val property20: Char
|
||||||
|
|||||||
Vendored
+8
-8
@@ -2,14 +2,14 @@ const val property2 = 42
|
|||||||
val property3 = 42 // intentionally left as non-const
|
val property3 = 42 // intentionally left as non-const
|
||||||
actual val property4 = 42
|
actual val property4 = 42
|
||||||
|
|
||||||
const val property6: Byte = 42
|
actual val property6: Byte = 42
|
||||||
const val property8: Short = 42
|
actual val property8: Short = 42
|
||||||
const val property10: Long = 42
|
actual val property10: Long = 42
|
||||||
const val property12: Double = 4.2
|
actual val property12: Double = 4.2
|
||||||
const val property14: Float = 4.2f
|
actual val property14: Float = 4.2f
|
||||||
const val property16 = true
|
actual val property16 = true
|
||||||
const val property18 = "42"
|
actual val property18 = "42"
|
||||||
const val property20: Char = 42.toChar()
|
actual val property20: Char = 42.toChar()
|
||||||
|
|
||||||
const val property21: Byte = 42
|
const val property21: Byte = 42
|
||||||
const val property22: Short = 42
|
const val property22: Short = 42
|
||||||
|
|||||||
Vendored
+8
-8
@@ -2,14 +2,14 @@ val property2 = 42 // intentionally left as non-const
|
|||||||
const val property3 = 42
|
const val property3 = 42
|
||||||
actual val property4 = 42
|
actual val property4 = 42
|
||||||
|
|
||||||
const val property6: Byte = 142
|
actual val property6: Byte = 142
|
||||||
const val property8: Short = 142
|
actual val property8: Short = 142
|
||||||
const val property10: Long = 142
|
actual val property10: Long = 142
|
||||||
const val property12: Double = 14.2
|
actual val property12: Double = 14.2
|
||||||
const val property14: Float = 14.2f
|
actual val property14: Float = 14.2f
|
||||||
const val property16 = false
|
actual val property16 = false
|
||||||
const val property18 = "142"
|
actual val property18 = "142"
|
||||||
const val property20: Char = 142.toChar()
|
actual val property20: Char = 142.toChar()
|
||||||
|
|
||||||
const val property21: Char = 42.toChar()
|
const val property21: Char = 42.toChar()
|
||||||
const val property22: Byte = 42
|
const val property22: Byte = 42
|
||||||
|
|||||||
Reference in New Issue
Block a user