[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?> containingDeclarations: List<DeclarationDescriptor?>
) { ) {
val commonProperty = common() val commonProperty = common()
val markAsExpectAndActual = commonProperty != null && commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, property -> val isLiftedUp = commonProperty?.isLiftedUp == true
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual) 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) commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
@@ -53,5 +53,13 @@ interface CirCallableMemberWithParameters {
val hasSynthesizedParameterNames: Boolean 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. */ /** Indicates presence of recursion in lazy calculations. */
interface CirRecursionMarker : CirDeclaration interface CirRecursionMarker : CirDeclaration
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
interface CirProperty : CirFunctionOrProperty { interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
val isVar: Boolean val isVar: Boolean
val isLateInit: Boolean val isLateInit: Boolean
val isConst: Boolean val isConst: Boolean
@@ -51,7 +51,8 @@ object CirPropertyFactory {
setter = source.setter?.let(CirPropertySetterFactory::create), setter = source.setter?.let(CirPropertySetterFactory::create),
backingFieldAnnotations = source.backingField?.annotations?.map(CirAnnotationFactory::create), backingFieldAnnotations = source.backingField?.annotations?.map(CirAnnotationFactory::create),
delegateFieldAnnotations = source.delegateField?.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?, setter: CirPropertySetter?,
backingFieldAnnotations: List<CirAnnotation>?, backingFieldAnnotations: List<CirAnnotation>?,
delegateFieldAnnotations: List<CirAnnotation>?, delegateFieldAnnotations: List<CirAnnotation>?,
compileTimeInitializer: ConstantValue<*>? compileTimeInitializer: ConstantValue<*>?,
isLiftedUp: Boolean
): CirProperty { ): CirProperty {
return CirPropertyImpl( return CirPropertyImpl(
annotations = annotations, annotations = annotations,
@@ -96,7 +98,8 @@ object CirPropertyFactory {
setter = setter, setter = setter,
backingFieldAnnotations = backingFieldAnnotations, backingFieldAnnotations = backingFieldAnnotations,
delegateFieldAnnotations = delegateFieldAnnotations, delegateFieldAnnotations = delegateFieldAnnotations,
compileTimeInitializer = compileTimeInitializer compileTimeInitializer = compileTimeInitializer,
isLiftedUp = isLiftedUp
) )
} }
} }
@@ -31,5 +31,6 @@ data class CirPropertyImpl(
override val setter: CirPropertySetter?, override val setter: CirPropertySetter?,
override val backingFieldAnnotations: List<CirAnnotation>?, override val backingFieldAnnotations: List<CirAnnotation>?,
override val delegateFieldAnnotations: List<CirAnnotation>?, override val delegateFieldAnnotations: List<CirAnnotation>?,
override val compileTimeInitializer: ConstantValue<*>? override val compileTimeInitializer: ConstantValue<*>?,
override val isLiftedUp: Boolean
) : CirProperty ) : 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.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.mergedtree.CirClassifiersCache import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
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
override fun commonizationResult(): CirProperty { override fun commonizationResult(): CirProperty {
val setter = setter.result val setter = setter.result
val constCompileTimeInitializer = constCompileTimeInitializer
return CirPropertyFactory.create( return CirPropertyFactory.create(
annotations = emptyList(), annotations = emptyList(),
@@ -30,20 +33,43 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
kind = kind, kind = kind,
isVar = setter != null, isVar = setter != null,
isLateInit = false, isLateInit = false,
isConst = false, isConst = constCompileTimeInitializer != null,
isDelegate = false, isDelegate = false,
getter = CirPropertyGetterFactory.DEFAULT_NO_ANNOTATIONS, getter = CirPropertyGetterFactory.DEFAULT_NO_ANNOTATIONS,
setter = setter, setter = setter,
backingFieldAnnotations = null, backingFieldAnnotations = null,
delegateFieldAnnotations = 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 { override fun doCommonizeWith(next: CirProperty): Boolean {
when { if (next.isLateInit) {
next.isConst -> return false // expect property can't be const because expect can't have initializer // expect property can't be lateinit
next.isLateInit -> return false // 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) val result = super.doCommonizeWith(next)