[Commonizer] Lift up identical const properties

^KMM-241
This commit is contained in:
Dmitriy Dolovov
2020-05-27 13:38:59 +07:00
parent a2edb9b547
commit 2ce1625989
6 changed files with 57 additions and 13 deletions
@@ -24,10 +24,16 @@ internal fun CirPropertyNode.buildDescriptors(
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonProperty = common()
val markAsExpectAndActual = commonProperty != null && commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
val isLiftedUp = commonProperty?.isLiftedUp == true
val markAsExpectAndActual = commonProperty != null
&& commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
&& !isLiftedUp
if (!isLiftedUp) {
target.forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
}
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
@@ -53,5 +53,13 @@ interface CirCallableMemberWithParameters {
val hasSynthesizedParameterNames: Boolean
}
/**
* Indicates a declaration that could be completely lifted up to "common" fragment.
* NOTE: Interning can't be applied to the whole lifted declaration, only to its parts!
*/
interface CirLiftedUpDeclaration : CirDeclaration {
val isLiftedUp: Boolean
}
/** Indicates presence of recursion in lazy calculations. */
interface CirRecursionMarker : CirDeclaration
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.resolve.constants.ConstantValue
interface CirProperty : CirFunctionOrProperty {
interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
val isVar: Boolean
val isLateInit: Boolean
val isConst: Boolean
@@ -51,7 +51,8 @@ object CirPropertyFactory {
setter = source.setter?.let(CirPropertySetterFactory::create),
backingFieldAnnotations = source.backingField?.annotations?.map(CirAnnotationFactory::create),
delegateFieldAnnotations = source.delegateField?.annotations?.map(CirAnnotationFactory::create),
compileTimeInitializer = source.compileTimeInitializer
compileTimeInitializer = source.compileTimeInitializer,
isLiftedUp = false
)
}
@@ -75,7 +76,8 @@ object CirPropertyFactory {
setter: CirPropertySetter?,
backingFieldAnnotations: List<CirAnnotation>?,
delegateFieldAnnotations: List<CirAnnotation>?,
compileTimeInitializer: ConstantValue<*>?
compileTimeInitializer: ConstantValue<*>?,
isLiftedUp: Boolean
): CirProperty {
return CirPropertyImpl(
annotations = annotations,
@@ -96,7 +98,8 @@ object CirPropertyFactory {
setter = setter,
backingFieldAnnotations = backingFieldAnnotations,
delegateFieldAnnotations = delegateFieldAnnotations,
compileTimeInitializer = compileTimeInitializer
compileTimeInitializer = compileTimeInitializer,
isLiftedUp = isLiftedUp
)
}
}
@@ -31,5 +31,6 @@ data class CirPropertyImpl(
override val setter: CirPropertySetter?,
override val backingFieldAnnotations: List<CirAnnotation>?,
override val delegateFieldAnnotations: List<CirAnnotation>?,
override val compileTimeInitializer: ConstantValue<*>?
override val compileTimeInitializer: ConstantValue<*>?,
override val isLiftedUp: Boolean
) : CirProperty
@@ -9,13 +9,16 @@ 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.CirPropertyGetterFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
import org.jetbrains.kotlin.resolve.constants.ConstantValue
class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirProperty>(cache) {
private val setter = PropertySetterCommonizer()
private var isExternal = true
private var constCompileTimeInitializer: ConstantValue<*>? = null
override fun commonizationResult(): CirProperty {
val setter = setter.result
val constCompileTimeInitializer = constCompileTimeInitializer
return CirPropertyFactory.create(
annotations = emptyList(),
@@ -30,20 +33,43 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
kind = kind,
isVar = setter != null,
isLateInit = false,
isConst = false,
isConst = constCompileTimeInitializer != null,
isDelegate = false,
getter = CirPropertyGetterFactory.DEFAULT_NO_ANNOTATIONS,
setter = setter,
backingFieldAnnotations = null,
delegateFieldAnnotations = null,
compileTimeInitializer = null
compileTimeInitializer = constCompileTimeInitializer,
isLiftedUp = constCompileTimeInitializer != null
)
}
override fun initialize(first: CirProperty) {
super.initialize(first)
if (first.isConst) {
constCompileTimeInitializer = first.compileTimeInitializer
}
}
override fun doCommonizeWith(next: CirProperty): Boolean {
when {
next.isConst -> return false // expect property can't be const because expect can't have initializer
next.isLateInit -> return false // expect property can't be lateinit
if (next.isLateInit) {
// expect property can't be lateinit
return false
}
val constCompileTimeInitializer = constCompileTimeInitializer
if (next.isConst) {
// const properties should be lifted up
// otherwise commonization should fail: expect property can't be const because expect can't have initializer
if (constCompileTimeInitializer == null || constCompileTimeInitializer != next.compileTimeInitializer) {
// previous property was not constant or const properties have different constants
return false
}
} else if (constCompileTimeInitializer != null) {
// previous property was constant but this one is not
return false
}
val result = super.doCommonizeWith(next)