[Commonizer] Move type commonization to single invocation commonizer

^KT-48288
This commit is contained in:
sebastian.sellmair
2021-09-09 11:23:49 +02:00
committed by Space
parent 3ee87f1635
commit 97e37243c6
36 changed files with 320 additions and 296 deletions
@@ -5,51 +5,53 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirFunctionOrProperty
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirProperty
import org.jetbrains.kotlin.commonizer.cir.CirType
import org.jetbrains.kotlin.commonizer.core.TypeCommonizer.Options.Companion.default
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.commonizer.utils.singleDistinctValueOrNull
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
abstract class AbstractFunctionOrPropertyCommonizer<T : CirFunctionOrProperty>(
classifiers: CirKnownClassifiers
) : AbstractStandardCommonizer<T, T?>() {
protected lateinit var name: CirName
protected val modality = ModalityCommonizer()
protected val visibility = VisibilityCommonizer.lowering()
protected val extensionReceiver = ExtensionReceiverCommonizer(classifiers)
protected val returnType = ReturnTypeCommonizer(classifiers).asCommonizer()
protected lateinit var kind: CallableMemberDescriptor.Kind
protected val typeParameters = TypeParameterListCommonizer(classifiers)
class FunctionOrPropertyBaseCommonizer(
private val typeCommonizer: TypeCommonizer,
private val extensionReceiverCommonizer: ExtensionReceiverCommonizer = ExtensionReceiverCommonizer(typeCommonizer),
private val returnTypeCommonizer: ReturnTypeCommonizer = ReturnTypeCommonizer(typeCommonizer),
) : NullableContextualSingleInvocationCommonizer<CirFunctionOrProperty, FunctionOrPropertyBaseCommonizer.FunctionOrProperty> {
override fun initialize(first: T) {
name = first.name
kind = first.kind
}
data class FunctionOrProperty(
val name: CirName,
val kind: CallableMemberDescriptor.Kind,
val modality: Modality,
val visibility: Visibility,
val extensionReceiver: CirExtensionReceiver?,
val returnType: CirType,
val typeParameters: List<CirTypeParameter>
)
override fun doCommonizeWith(next: T): Boolean =
next.kind != DELEGATION // delegated members should not be commonized
&& (next.kind != SYNTHESIZED || next.containingClass?.isData != true) // synthesized members of data classes should not be commonized
&& kind == next.kind
&& modality.commonizeWith(next.modality)
&& visibility.commonizeWith(next)
&& extensionReceiver.commonizeWith(next.extensionReceiver)
&& returnType.commonizeWith(next)
&& typeParameters.commonizeWith(next.typeParameters)
}
private class ReturnTypeCommonizer(
private val classifiers: CirKnownClassifiers,
) : NullableContextualSingleInvocationCommonizer<CirFunctionOrProperty, CirType> {
override fun invoke(values: List<CirFunctionOrProperty>): CirType? {
override fun invoke(values: List<CirFunctionOrProperty>): FunctionOrProperty? {
/* Preconditions */
if (values.isEmpty()) return null
val isTopLevel = values.all { it.containingClass == null }
val isCovariant = values.none { it is CirProperty && it.isVar }
return TypeCommonizer(classifiers, default.withCovariantNullabilityCommonizationEnabled(isTopLevel && isCovariant))
.asCommonizer().commonize(values.map { it.returnType })
// delegated members should not be commonized
if (values.any { value -> value.kind == DELEGATION }) {
return null
}
// synthesized members of data classes should not be commonized
if (values.any { value -> value.kind == SYNTHESIZED && value.containingClass?.isData == true }) {
return null
}
return FunctionOrProperty(
name = values.first().name,
kind = values.singleDistinctValueOrNull { it.kind } ?: return null,
modality = ModalityCommonizer().commonize(values.map { it.modality }) ?: return null,
visibility = VisibilityCommonizer.lowering().commonize(values) ?: return null,
extensionReceiver = extensionReceiverCommonizer(values.map { it.extensionReceiver })?.receiver ?: return null,
returnType = returnTypeCommonizer(values) ?: return null,
typeParameters = TypeParameterListCommonizer(typeCommonizer).commonize(values.map { it.typeParameters }) ?: return null
)
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirType
import org.jetbrains.kotlin.commonizer.utils.compactMap
/**
* Unlike [Commonizer] which commonizes only single elements, this [AbstractListCommonizer] commonizes lists of elements using
@@ -16,14 +15,14 @@ import org.jetbrains.kotlin.commonizer.utils.compactMap
* Input: N lists of [CirType]
* Output: list of [CirType]
*/
abstract class AbstractListCommonizer<T, R>(
private val singleElementCommonizerFactory: (Int) -> Commonizer<T, R>
abstract class AbstractListCommonizer<T, R: Any>(
private val singleElementCommonizerFactory: (Int) -> Commonizer<T, R?>
) : Commonizer<List<T>, List<R>> {
private var commonizers: Array<Commonizer<T, R>>? = null
private var commonizers: Array<Commonizer<T, R?>>? = null
private var error = false
final override val result: List<R>
get() = checkState(commonizers, error).compactMap { it.result }
get() = checkState(commonizers, error).mapNotNull { it.result }
final override fun commonizeWith(next: List<T>): Boolean {
if (error)
@@ -53,7 +52,7 @@ abstract class AbstractListCommonizer<T, R>(
return !error
}
protected fun forEachSingleElementCommonizer(action: (index: Int, Commonizer<T, R>) -> Unit) {
protected fun forEachSingleElementCommonizer(action: (index: Int, Commonizer<T, R?>) -> Unit) {
val commonizers = commonizers ?: failInEmptyState()
commonizers.forEachIndexed(action)
}
@@ -9,6 +9,12 @@ interface AssociativeCommonizer<T> {
fun commonize(first: T, second: T): T?
}
fun <T> AssociativeCommonizer<T>.commonize(values: List<T>): T? {
if (values.isEmpty()) return null
if (values.size == 1) return values.first()
return values.reduce { acc, next -> commonize(acc, next) ?: return null }
}
fun <T : Any> AssociativeCommonizer<T>.asCommonizer(): AssociativeCommonizerAdapter<T> = AssociativeCommonizerAdapter(this)
open class AssociativeCommonizerAdapter<T : Any>(
@@ -12,12 +12,11 @@ import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirValueParameter
import org.jetbrains.kotlin.commonizer.core.CallableValueParametersCommonizer.CallableToPatch.Companion.doNothing
import org.jetbrains.kotlin.commonizer.core.CallableValueParametersCommonizer.CallableToPatch.Companion.patchCallables
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.utils.compactMapIndexed
import org.jetbrains.kotlin.commonizer.utils.isObjCInteropCallableAnnotation
class CallableValueParametersCommonizer(
classifiers: CirKnownClassifiers
typeCommonizer: TypeCommonizer,
) : Commonizer<CirCallableMemberWithParameters, CallableValueParametersCommonizer.Result> {
class Result(
val hasStableParameterNames: Boolean,
@@ -116,7 +115,7 @@ class CallableValueParametersCommonizer(
}
}
private val valueParameters = ValueParameterListCommonizer(classifiers)
private val valueParameters = ValueParameterListCommonizer(typeCommonizer)
private val callables: MutableList<CallableToPatch> = mutableListOf()
private var hasStableParameterNames = true
private var valueParameterNames: ValueParameterNames? = null
@@ -7,27 +7,29 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirClass
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.descriptors.ClassKind
class ClassCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirClass, CirClass>() {
class ClassCommonizer internal constructor(
typeCommonizer: TypeCommonizer,
supertypesCommonizer: ClassSuperTypeCommonizer
) : AbstractStandardCommonizer<CirClass, CirClass>() {
private lateinit var name: CirName
private lateinit var kind: ClassKind
private val typeParameters = TypeParameterListCommonizer(classifiers)
private val modality = ModalityCommonizer()
private val visibility = VisibilityCommonizer.equalizing()
private var isInner = false
private var isValue = false
private var isCompanion = false
private val supertypes = ClassSuperTypeCommonizer(classifiers).asCommonizer()
private val supertypesCommonizer = supertypesCommonizer.asCommonizer()
private val typeParameterListCommonizer: TypeParameterListCommonizer = TypeParameterListCommonizer(typeCommonizer)
private val modalityCommonizer: ModalityCommonizer = ModalityCommonizer()
private val visibilityCommonizer: VisibilityCommonizer = VisibilityCommonizer.equalizing()
override fun commonizationResult() = CirClass.create(
annotations = emptyList(),
name = name,
typeParameters = typeParameters.result,
supertypes = supertypes.result,
visibility = visibility.result,
modality = modality.result,
typeParameters = typeParameterListCommonizer.result,
supertypes = supertypesCommonizer.result,
visibility = visibilityCommonizer.result,
modality = modalityCommonizer.result,
kind = kind,
companion = null,
isCompanion = isCompanion,
@@ -50,8 +52,8 @@ class ClassCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommon
&& isInner == next.isInner
&& isValue == next.isValue
&& isCompanion == next.isCompanion
&& modality.commonizeWith(next.modality)
&& visibility.commonizeWith(next)
&& typeParameters.commonizeWith(next.typeParameters)
&& supertypes.commonizeWith(next.supertypes)
&& modalityCommonizer.commonizeWith(next.modality)
&& visibilityCommonizer.commonizeWith(next)
&& typeParameterListCommonizer.commonizeWith(next.typeParameters)
&& supertypesCommonizer.commonizeWith(next.supertypes)
}
@@ -7,26 +7,25 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirClassConstructor
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
class ClassConstructorCommonizer(
classifiers: CirKnownClassifiers
typeCommonizer: TypeCommonizer,
) : AbstractStandardCommonizer<CirClassConstructor, CirClassConstructor>() {
private var isPrimary = false
private val visibility = VisibilityCommonizer.equalizing()
private val typeParameters = TypeParameterListCommonizer(classifiers)
private val valueParameters = CallableValueParametersCommonizer(classifiers)
private val annotationsCommonizer = AnnotationsCommonizer()
private val typeParameterListCommonizer = TypeParameterListCommonizer(typeCommonizer)
private val valueParametersCommonizer = CallableValueParametersCommonizer(typeCommonizer)
private val annotationsCommonizer: AnnotationsCommonizer = AnnotationsCommonizer()
override fun commonizationResult(): CirClassConstructor {
val valueParameters = valueParameters.result
val valueParameters = valueParametersCommonizer.result
valueParameters.patchCallables()
return CirClassConstructor.create(
annotations = annotationsCommonizer.result,
typeParameters = typeParameters.result,
typeParameters = typeParameterListCommonizer.result,
visibility = visibility.result,
containingClass = CONTAINING_CLASS_DOES_NOT_MATTER, // does not matter
valueParameters = valueParameters.valueParameters,
@@ -44,8 +43,8 @@ class ClassConstructorCommonizer(
&& next.containingClass.modality != Modality.SEALED // don't commonize constructors for sealed classes (not not their subclasses)
&& isPrimary == next.isPrimary
&& visibility.commonizeWith(next)
&& typeParameters.commonizeWith(next.typeParameters)
&& valueParameters.commonizeWith(next)
&& typeParameterListCommonizer.commonizeWith(next.typeParameters)
&& valueParametersCommonizer.commonizeWith(next)
&& annotationsCommonizer.commonizeWith(next.annotations)
}
@@ -8,13 +8,16 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirClassOrTypeAliasType
import org.jetbrains.kotlin.commonizer.cir.CirClassType
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
internal class ClassOrTypeAliasTypeCommonizer(
private val classifiers: CirKnownClassifiers,
private val options: TypeCommonizer.Options
) : AssociativeCommonizer<CirClassOrTypeAliasType> {
private val typeCommonizer: TypeCommonizer
) : NullableSingleInvocationCommonizer<CirClassOrTypeAliasType> {
override fun invoke(values: List<CirClassOrTypeAliasType>): CirClassOrTypeAliasType? {
TODO()
}
/*
override fun commonize(first: CirClassOrTypeAliasType, second: CirClassOrTypeAliasType): CirClassOrTypeAliasType? {
if (first is CirClassType && second is CirClassType) {
return ClassTypeCommonizer(classifiers, options).commonize(listOf(first, second))
@@ -53,6 +56,9 @@ internal class ClassOrTypeAliasTypeCommonizer(
return commonize(classType, typeAliasClassType)
}
*/
}
internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) {
@@ -41,11 +41,10 @@ private typealias Supertypes = List<CirType>
* ```
*/
internal class ClassSuperTypeCommonizer(
private val classifiers: CirKnownClassifiers
private val classifiers: CirKnownClassifiers,
private val typeCommonizer: TypeCommonizer
) : SingleInvocationCommonizer<Supertypes> {
private val typeCommonizer = TypeCommonizer(classifiers)
override fun invoke(values: List<Supertypes>): Supertypes {
if (values.isEmpty()) return emptyList()
if (values.all { it.isEmpty() }) return emptyList()
@@ -54,7 +53,7 @@ internal class ClassSuperTypeCommonizer(
val supertypesGroups = buildSupertypesGroups(supertypesTrees)
return supertypesGroups.mapNotNull { supertypesGroup ->
typeCommonizer.asCommonizer().commonize(supertypesGroup.types)
typeCommonizer(supertypesGroup.types)
}
}
@@ -9,42 +9,42 @@ import org.jetbrains.kotlin.commonizer.cir.CirClassType
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.utils.isUnderKotlinNativeSyntheticPackages
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.commonizer.utils.singleDistinctValueOrNull
internal class ClassTypeCommonizer(
class ClassTypeCommonizer internal constructor(
private val classifiers: CirKnownClassifiers,
options: TypeCommonizer.Options = TypeCommonizer.Options.default
) :
AbstractStandardCommonizer<CirClassType, CirClassType>() {
private lateinit var classId: CirEntityId
private val outerType = OuterClassTypeCommonizer(classifiers)
private lateinit var anyVisibility: Visibility
private val arguments = TypeArgumentListCommonizer(classifiers)
private val isMarkedNullable = TypeNullabilityCommonizer(options).asCommonizer()
private val typeCommonizer: TypeCommonizer,
private val isMarkedNullableCommonizer: TypeNullabilityCommonizer
) : NullableSingleInvocationCommonizer<CirClassType> {
override fun invoke(values: List<CirClassType>): CirClassType? {
if (values.isEmpty()) return null
val classId = values.singleDistinctValueOrNull { it.classifierId } ?: return null
val isMarkedNullable = isMarkedNullableCommonizer.commonize(values.map { it.isMarkedNullable }) ?: return null
override fun commonizationResult() = CirClassType.createInterned(
classId = classId,
outerType = outerType.result,
// N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is
// intended to be used in "common" target. It could not participate in TA commonization. So, it does not matter which
// exactly visibility will be recorded for commonized class type. Passing the visibility of the first class type
// to reach better interning rate.
visibility = anyVisibility,
arguments = arguments.result,
isMarkedNullable = isMarkedNullable.result
)
if (values.any { !isClassifierAvailableInCommon(classifiers, it.classifierId) }) {
return null
}
override fun initialize(first: CirClassType) {
classId = first.classifierId
anyVisibility = first.visibility
val outerType = if (values.all { it.outerType == null }) null
else if (values.any { it.outerType == null }) return null
else invoke(values.map { checkNotNull(it.outerType) }) ?: return null
// Commonizer is stateful: Needs to be created per invocation!
val arguments = TypeArgumentListCommonizer(typeCommonizer).commonize(values.map { it.arguments }) ?: return null
return CirClassType.createInterned(
classId = classId,
outerType = outerType,
// N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is
// intended to be used in "common" target. It could not participate in TA commonization. So, it does not matter which
// exactly visibility will be recorded for commonized class type. Passing the visibility of the first class type
// to reach better interning rate.
visibility = values.first().visibility,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
}
override fun doCommonizeWith(next: CirClassType) =
isMarkedNullable.commonizeWith(next.isMarkedNullable)
&& classId == next.classifierId
&& outerType.commonizeWith(next.outerType)
&& isClassifierAvailableInCommon(classifiers, classId)
&& arguments.commonizeWith(next.arguments)
}
private fun isClassifierAvailableInCommon(classifiers: CirKnownClassifiers, classId: CirEntityId): Boolean {
@@ -64,10 +64,3 @@ private fun isClassifierAvailableInCommon(classifiers: CirKnownClassifiers, clas
return (classifiers.commonizedNodes.classNode(classId)?.commonDeclaration?.invoke()
?: classifiers.commonizedNodes.typeAliasNode(classId)?.commonDeclaration?.invoke()) != null
}
private class OuterClassTypeCommonizer(classifiers: CirKnownClassifiers) :
AbstractNullableCommonizer<CirClassType, CirClassType, CirClassType, CirClassType>(
wrappedCommonizerFactory = { ClassTypeCommonizer(classifiers) },
extractor = { it },
builder = { it }
)
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.mergedtree.*
internal class CommonizationVisitor(
private val classifiers: CirKnownClassifiers,
private val root: CirRootNode
) : CirNodeVisitor<Unit, Unit> {
override fun visitRootNode(node: CirRootNode, data: Unit) {
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.commonizer.core
interface Commonizer<T, out R> {
interface Commonizer<in T, out R> {
val result: R
fun commonizeWith(next: T): Boolean
}
@@ -6,17 +6,26 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirExtensionReceiver
import org.jetbrains.kotlin.commonizer.cir.CirType
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class ExtensionReceiverCommonizer(classifiers: CirKnownClassifiers) :
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
wrappedCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() },
extractor = { it.type },
builder = { receiverType ->
class ExtensionReceiverCommonizer(
private val typeCommonizer: TypeCommonizer
) : NullableContextualSingleInvocationCommonizer<CirExtensionReceiver?, ExtensionReceiverCommonizer.Commonized> {
class Commonized(val receiver: CirExtensionReceiver?) {
companion object {
val NULL = Commonized(null)
}
}
override fun invoke(values: List<CirExtensionReceiver?>): Commonized? {
if (values.all { it == null }) return Commonized.NULL
if (values.any { it == null }) return null
return Commonized(
CirExtensionReceiver(
annotations = emptyList(),
type = receiverType
type = typeCommonizer(values.map { checkNotNull(it).type }) ?: return null
)
}
)
)
}
}
@@ -6,37 +6,28 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirFunction
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class FunctionCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirFunction>(classifiers) {
private val annotations = AnnotationsCommonizer()
private val modifiers = FunctionModifiersCommonizer()
private val valueParameters = CallableValueParametersCommonizer(classifiers)
override fun commonizationResult(): CirFunction? {
val valueParameters = valueParameters.result
valueParameters.patchCallables()
class FunctionCommonizer(
private val typeCommonizer: TypeCommonizer,
private val functionOrPropertyBaseCommonizer: FunctionOrPropertyBaseCommonizer,
) : NullableSingleInvocationCommonizer<CirFunction> {
override fun invoke(values: List<CirFunction>): CirFunction? {
if (values.isEmpty()) return null
val functionOrProperty = functionOrPropertyBaseCommonizer(values) ?: return null
val valueParametersResult = CallableValueParametersCommonizer(typeCommonizer).commonize(values) ?: return null
return CirFunction(
annotations = annotations.result,
name = name,
typeParameters = typeParameters.result,
visibility = visibility.result,
modality = modality.result,
annotations = AnnotationsCommonizer().commonize(values.map { it.annotations }) ?: return null,
name = values.first().name,
typeParameters = functionOrProperty.typeParameters,
visibility = functionOrProperty.visibility,
modality = functionOrProperty.modality,
containingClass = null, // does not matter
valueParameters = valueParameters.valueParameters,
hasStableParameterNames = valueParameters.hasStableParameterNames,
extensionReceiver = extensionReceiver.result,
returnType = returnType.result ?: return null,
kind = kind,
modifiers = modifiers.result
valueParameters = valueParametersResult.valueParameters,
hasStableParameterNames = valueParametersResult.hasStableParameterNames,
extensionReceiver = functionOrProperty.extensionReceiver,
returnType = functionOrProperty.returnType,
kind = functionOrProperty.kind,
modifiers = FunctionModifiersCommonizer().commonize(values.map { it.modifiers }) ?: return null
)
}
override fun doCommonizeWith(next: CirFunction): Boolean {
return super.doCommonizeWith(next)
&& annotations.commonizeWith(next.annotations)
&& modifiers.commonizeWith(next.modifiers)
&& valueParameters.commonizeWith(next)
}
}
}
@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.commonizer.core
interface NullableContextualSingleInvocationCommonizer<T : Any, R : Any> {
interface NullableContextualSingleInvocationCommonizer<T, R : Any> {
operator fun invoke(values: List<T>): R?
}
fun <T : Any, R : Any> NullableContextualSingleInvocationCommonizer<T, R>.asCommonizer(): Commonizer<T, R?> =
fun <T, R : Any> NullableContextualSingleInvocationCommonizer<T, R>.asCommonizer(): Commonizer<T, R?> =
object : Commonizer<T, R?> {
private val collectedValues = mutableListOf<T>()
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.commonizer.core
interface NullableSingleInvocationCommonizer<T : Any> {
interface NullableSingleInvocationCommonizer<T> {
operator fun invoke(values: List<T>): T?
}
@@ -9,19 +9,21 @@ import org.jetbrains.kotlin.commonizer.cir.CirConstantValue
import org.jetbrains.kotlin.commonizer.cir.CirProperty
import org.jetbrains.kotlin.commonizer.cir.CirPropertyGetter
import org.jetbrains.kotlin.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.descriptors.Modality
class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirProperty>(classifiers) {
class PropertyCommonizer(
functionOrPropertyBaseCommonizer: FunctionOrPropertyBaseCommonizer
) : AbstractStandardCommonizer<CirProperty, CirProperty?>() {
private val setter = PropertySetterCommonizer.asNullableCommonizer()
private var isExternal = true
private lateinit var constCommonizationState: ConstCommonizationState
private val functionOrPropertyBaseCommonizer = functionOrPropertyBaseCommonizer.asCommonizer()
override fun commonizationResult(): CirProperty? {
val modality = modality.result
val functionOrPropertyBase = functionOrPropertyBaseCommonizer.result ?: return null
val setter = setter.result?.takeIf { setter ->
setter !== PropertySetterCommonizer.privateFallbackSetter || modality == Modality.FINAL
setter !== PropertySetterCommonizer.privateFallbackSetter || functionOrPropertyBase.modality == Modality.FINAL
}
val constCommonizationState = constCommonizationState
@@ -29,15 +31,15 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP
return CirProperty(
annotations = emptyList(),
name = name,
typeParameters = typeParameters.result,
visibility = visibility.result,
modality = modality,
name = functionOrPropertyBase.name,
typeParameters = functionOrPropertyBase.typeParameters,
visibility = functionOrPropertyBase.visibility,
modality = functionOrPropertyBase.modality,
containingClass = null, // does not matter
isExternal = isExternal,
extensionReceiver = extensionReceiver.result,
returnType = returnType.result ?: return null,
kind = kind,
extensionReceiver = functionOrPropertyBase.extensionReceiver,
returnType = functionOrPropertyBase.returnType,
kind = functionOrPropertyBase.kind,
isVar = setter != null,
isLateInit = false,
isConst = constCompileTimeInitializer != null,
@@ -51,8 +53,6 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP
}
override fun initialize(first: CirProperty) {
super.initialize(first)
constCommonizationState = if (first.isConst) {
first.compileTimeInitializer.takeIf { it != CirConstantValue.NullValue }?.let(::ConstSameValue) ?: NonConst
} else {
@@ -89,7 +89,7 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP
this.constCommonizationState = NonConst
}
val result = super.doCommonizeWith(next)
val result = functionOrPropertyBaseCommonizer.commonizeWith(next)
&& setter.commonizeWith(next.setter)
if (result) {
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirFunctionOrProperty
import org.jetbrains.kotlin.commonizer.cir.CirProperty
import org.jetbrains.kotlin.commonizer.cir.CirType
class ReturnTypeCommonizer(
private val typeCommonizer: TypeCommonizer,
) : NullableContextualSingleInvocationCommonizer<CirFunctionOrProperty, CirType> {
override fun invoke(values: List<CirFunctionOrProperty>): CirType? {
if (values.isEmpty()) return null
val isTopLevel = values.all { it.containingClass == null }
val isCovariant = values.none { it is CirProperty && it.isVar }
return typeCommonizer
.withOptions { withCovariantNullabilityCommonizationEnabled(isTopLevel && isCovariant) }
.invoke(values.map { it.returnType })
}
}
@@ -13,17 +13,18 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class TypeAliasCommonizer(
private val classifiers: CirKnownClassifiers
private val typeCommonizer: TypeCommonizer,
private val classifiers: CirKnownClassifiers,
) : NullableSingleInvocationCommonizer<CirTypeAlias> {
override fun invoke(values: List<CirTypeAlias>): CirTypeAlias? {
if (values.isEmpty()) return null
val name = values.map { it.name }.distinct().singleOrNull() ?: return null
val typeParameters = TypeParameterListCommonizer(classifiers).commonize(values.map { it.typeParameters }) ?: return null
val typeParameters = TypeParameterListCommonizer(typeCommonizer).commonize(values.map { it.typeParameters }) ?: return null
val underlyingType = TypeCommonizer(classifiers, TypeCommonizer.Options.default.withOptimisticNumberTypeCommonizationEnabled())
.asCommonizer().commonize(values.map { it.underlyingType }) as? CirClassOrTypeAliasType ?: return null
val underlyingType = typeCommonizer.withOptions { withOptimisticNumberTypeCommonizationEnabled() }
.invoke(values.map { it.underlyingType }) as? CirClassOrTypeAliasType ?: return null
val visibility = VisibilityCommonizer.lowering().commonize(values) ?: return null
@@ -11,15 +11,14 @@ import org.jetbrains.kotlin.commonizer.core.CommonizedTypeAliasAnswer.Companion.
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
internal class TypeAliasTypeCommonizer(
private val typeCommonizer: TypeCommonizer,
private val classifiers: CirKnownClassifiers,
options: TypeCommonizer.Options
) :
AbstractStandardCommonizer<CirTypeAliasType, CirClassOrTypeAliasType>() {
) : AbstractStandardCommonizer<CirTypeAliasType, CirClassOrTypeAliasType>() {
private lateinit var typeAliasId: CirEntityId
private val arguments = TypeArgumentListCommonizer(classifiers)
private val underlyingTypeArguments = TypeArgumentListCommonizer(classifiers)
private val isMarkedNullable = TypeNullabilityCommonizer(options).asCommonizer()
private val arguments = TypeArgumentListCommonizer(typeCommonizer)
private val underlyingTypeArguments = TypeArgumentListCommonizer(typeCommonizer)
private val isMarkedNullable = TypeNullabilityCommonizer(typeCommonizer.options).asCommonizer()
private var commonizedTypeBuilder: CommonizedTypeAliasTypeBuilder? = null // null means not selected yet
override fun commonizationResult() =
@@ -47,7 +46,7 @@ internal class TypeAliasTypeCommonizer(
is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier)
is CirTypeAlias -> CommonizedTypeAliasTypeBuilder.forTypeAlias(commonClassifier)
null -> {
val underlyingType = computeSuitableUnderlyingType(classifiers, next.underlyingType) ?: return false
val underlyingType = computeSuitableUnderlyingType(classifiers, typeCommonizer, next.underlyingType) ?: return false
CommonizedTypeAliasTypeBuilder.forKnownUnderlyingType(underlyingType)
}
else -> error("Unexpected common classifier type: ${commonClassifier::class.java}, $commonClassifier")
@@ -8,30 +8,22 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirRegularTypeProjection
import org.jetbrains.kotlin.commonizer.cir.CirStarTypeProjection
import org.jetbrains.kotlin.commonizer.cir.CirTypeProjection
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.commonizer.utils.safeCastValues
import org.jetbrains.kotlin.commonizer.utils.singleDistinctValueOrNull
class TypeArgumentCommonizer(
classifiers: CirKnownClassifiers
) : AbstractStandardCommonizer<CirTypeProjection, CirTypeProjection>() {
private var isStar = false
private lateinit var projectionKind: Variance
private val type = TypeCommonizer(classifiers).asCommonizer()
private val typeCommonizer: TypeCommonizer
) : NullableSingleInvocationCommonizer<CirTypeProjection> {
override fun invoke(values: List<CirTypeProjection>): CirTypeProjection? {
/* All values are star projections */
values.safeCastValues<CirTypeProjection, CirStarTypeProjection>()?.let { return CirStarTypeProjection }
override fun commonizationResult() = if (isStar) CirStarTypeProjection else CirRegularTypeProjection(
projectionKind = projectionKind,
type = type.result
)
/* All values are regular type projections */
val projections = values.safeCastValues<CirTypeProjection, CirRegularTypeProjection>() ?: return null
override fun initialize(first: CirTypeProjection) {
when (first) {
is CirStarTypeProjection -> isStar = true
is CirRegularTypeProjection -> projectionKind = first.projectionKind
}
}
override fun doCommonizeWith(next: CirTypeProjection) = when (next) {
is CirStarTypeProjection -> isStar
is CirRegularTypeProjection -> !isStar && projectionKind == next.projectionKind && type.commonizeWith(next.type)
return CirRegularTypeProjection(
projectionKind = projections.singleDistinctValueOrNull { it.projectionKind } ?: return null,
type = typeCommonizer(projections.map { it.type }) ?: return null
)
}
}
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirTypeProjection
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class TypeArgumentListCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirTypeProjection, CirTypeProjection>(
singleElementCommonizerFactory = { TypeArgumentCommonizer(classifiers) }
class TypeArgumentListCommonizer(typeCommonizer: TypeCommonizer) : AbstractListCommonizer<CirTypeProjection, CirTypeProjection>(
singleElementCommonizerFactory = { TypeArgumentCommonizer(typeCommonizer).asCommonizer() }
)
@@ -7,23 +7,27 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.utils.safeCastValues
class TypeCommonizer(
private val classifiers: CirKnownClassifiers,
private val options: Options = Options.default
) : AssociativeCommonizer<CirType> {
override fun commonize(first: CirType, second: CirType): CirType? {
if (first is CirClassOrTypeAliasType && second is CirClassOrTypeAliasType) {
return ClassOrTypeAliasTypeCommonizer(classifiers, options).commonize(first, second)
val options: Options = Options.default
) : NullableSingleInvocationCommonizer<CirType> {
private val classOrTypeAliasTypeCommonizer = ClassOrTypeAliasTypeCommonizer(this)
private val flexibleTypeCommonizer = FlexibleTypeAssociativeCommonizer(this)
override fun invoke(values: List<CirType>): CirType? {
values.safeCastValues<CirType, CirClassOrTypeAliasType>()?.let { types ->
return classOrTypeAliasTypeCommonizer(types)
}
if (first is CirTypeParameterType && second is CirTypeParameterType) {
return TypeParameterTypeCommonizer.commonize(first, second)
values.safeCastValues<CirType, CirTypeParameterType>()?.let { types ->
return TypeParameterTypeCommonizer.commonize(types)
}
if (first is CirFlexibleType && second is CirFlexibleType) {
return FlexibleTypeAssociativeCommonizer(classifiers, options).commonize(first, second)
values.safeCastValues<CirType, CirFlexibleType>()?.let { types ->
return flexibleTypeCommonizer(types)
}
return null
@@ -48,6 +52,15 @@ class TypeCommonizer(
val default = Options()
}
}
fun withOptions(options: Options): TypeCommonizer {
return if (this.options == options) this
else TypeCommonizer(classifiers, options)
}
inline fun withOptions(createNewOptions: Options.() -> Options): TypeCommonizer {
return withOptions(options.createNewOptions())
}
}
private object TypeParameterTypeCommonizer : AssociativeCommonizer<CirTypeParameterType> {
@@ -60,14 +73,11 @@ private object TypeParameterTypeCommonizer : AssociativeCommonizer<CirTypeParame
}
private class FlexibleTypeAssociativeCommonizer(
private val classifiers: CirKnownClassifiers,
private val options: TypeCommonizer.Options
) : AssociativeCommonizer<CirFlexibleType> {
override fun commonize(first: CirFlexibleType, second: CirFlexibleType): CirFlexibleType? {
val lowerBound = TypeCommonizer(classifiers, options).commonize(first.lowerBound, second.lowerBound) ?: return null
val upperBound = TypeCommonizer(classifiers, options).commonize(first.upperBound, second.upperBound) ?: return null
private val typeCommonizer: TypeCommonizer
) : NullableSingleInvocationCommonizer<CirFlexibleType> {
override fun invoke(values: List<CirFlexibleType>): CirFlexibleType? {
val lowerBound = typeCommonizer(values.map { it.lowerBound }) ?: return null
val upperBound = typeCommonizer(values.map { it.upperBound }) ?: return null
return CirFlexibleType(
lowerBound = lowerBound as CirSimpleType,
upperBound = upperBound as CirSimpleType
@@ -8,14 +8,13 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirType
import org.jetbrains.kotlin.commonizer.cir.CirTypeParameter
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.types.Variance
class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeParameter, CirTypeParameter>() {
class TypeParameterCommonizer(typeCommonizer: TypeCommonizer) : AbstractStandardCommonizer<CirTypeParameter, CirTypeParameter>() {
private lateinit var name: CirName
private var isReified = false
private lateinit var variance: Variance
private val upperBounds = TypeParameterUpperBoundsCommonizer(classifiers)
private val upperBounds = TypeParameterUpperBoundsCommonizer(typeCommonizer)
override fun commonizationResult() = CirTypeParameter(
annotations = emptyList(),
@@ -38,6 +37,6 @@ class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStanda
&& upperBounds.commonizeWith(next.upperBounds)
}
private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirType, CirType>(
singleElementCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() }
private class TypeParameterUpperBoundsCommonizer(typeCommonizer: TypeCommonizer) : AbstractListCommonizer<CirType, CirType>(
singleElementCommonizerFactory = { typeCommonizer.asCommonizer() }
)
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirTypeParameter
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class TypeParameterListCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirTypeParameter, CirTypeParameter>(
singleElementCommonizerFactory = { TypeParameterCommonizer(classifiers) }
class TypeParameterListCommonizer(typeCommonizer: TypeCommonizer) : AbstractListCommonizer<CirTypeParameter, CirTypeParameter>(
singleElementCommonizerFactory = { TypeParameterCommonizer(typeCommonizer) }
)
@@ -8,25 +8,27 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirType
import org.jetbrains.kotlin.commonizer.cir.CirValueParameter
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.utils.isNull
class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirValueParameter, CirValueParameter>() {
class ValueParameterCommonizer(returnTypeCommonizer: TypeCommonizer) :
AbstractStandardCommonizer<CirValueParameter, CirValueParameter?>() {
private lateinit var name: CirName
private val returnType = TypeCommonizer(classifiers).asCommonizer()
private val returnTypeCommonizer = returnTypeCommonizer.asCommonizer()
private var varargElementType: CirType? = null
private var isCrossinline = true
private var isNoinline = true
override fun commonizationResult() = CirValueParameter.createInterned(
annotations = emptyList(),
name = name,
returnType = returnType.result,
varargElementType = varargElementType,
declaresDefaultValue = false,
isCrossinline = isCrossinline,
isNoinline = isNoinline
)
override fun commonizationResult(): CirValueParameter? {
return CirValueParameter.createInterned(
annotations = emptyList(),
name = name,
returnType = returnTypeCommonizer.result ?: return null,
varargElementType = varargElementType,
declaresDefaultValue = false,
isCrossinline = isCrossinline,
isNoinline = isNoinline
)
}
override fun initialize(first: CirValueParameter) {
name = first.name
@@ -38,7 +40,7 @@ class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStand
override fun doCommonizeWith(next: CirValueParameter): Boolean {
val result = !next.declaresDefaultValue
&& varargElementType.isNull() == next.varargElementType.isNull()
&& returnType.commonizeWith(next.returnType)
&& returnTypeCommonizer.commonizeWith(next.returnType)
if (result) {
isCrossinline = isCrossinline && next.isCrossinline
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirValueParameter
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class ValueParameterListCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirValueParameter, CirValueParameter>(
singleElementCommonizerFactory = { ValueParameterCommonizer(classifiers) }
class ValueParameterListCommonizer(typeCommonizer: TypeCommonizer) : AbstractListCommonizer<CirValueParameter, CirValueParameter>(
singleElementCommonizerFactory = { ValueParameterCommonizer(typeCommonizer) }
) {
fun overwriteNames(names: List<CirName>) {
forEachSingleElementCommonizer { index, singleElementCommonizer ->
@@ -13,24 +13,25 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
internal tailrec fun computeSuitableUnderlyingType(
classifiers: CirKnownClassifiers,
typeCommonizer: TypeCommonizer,
underlyingType: CirClassOrTypeAliasType
): CirClassOrTypeAliasType? {
return when (underlyingType) {
is CirClassType -> underlyingType.withCommonizedArguments(classifiers)
is CirClassType -> underlyingType.withCommonizedArguments(typeCommonizer)
is CirTypeAliasType ->
if (classifiers.commonDependencies.hasClassifier(underlyingType.classifierId) ||
classifiers.commonizedNodes.typeAliasNode(underlyingType.classifierId)?.commonDeclaration?.invoke() != null
) underlyingType.withCommonizedArguments(classifiers)
else computeSuitableUnderlyingType(classifiers, underlyingType.underlyingType)
) underlyingType.withCommonizedArguments(typeCommonizer)
else computeSuitableUnderlyingType(classifiers, typeCommonizer, underlyingType.underlyingType)
}
}
private fun CirClassType.withCommonizedArguments(classifiers: CirKnownClassifiers): CirClassType? {
private fun CirClassType.withCommonizedArguments(typeCommonizer: TypeCommonizer): CirClassType? {
val existingArguments = arguments
val newArguments = existingArguments.toCommonizedArguments(classifiers) ?: return null
val newArguments = existingArguments.toCommonizedArguments(typeCommonizer) ?: return null
val existingOuterType = outerType
val newOuterType = existingOuterType?.let { it.withCommonizedArguments(classifiers) ?: return null }
val newOuterType = existingOuterType?.let { it.withCommonizedArguments(typeCommonizer) ?: return null }
return if (newArguments !== existingArguments || newOuterType !== existingOuterType)
CirClassType.createInterned(
@@ -44,14 +45,14 @@ private fun CirClassType.withCommonizedArguments(classifiers: CirKnownClassifier
this
}
private fun CirTypeAliasType.withCommonizedArguments(classifiers: CirKnownClassifiers): CirTypeAliasType? {
private fun CirTypeAliasType.withCommonizedArguments(typeCommonizer: TypeCommonizer): CirTypeAliasType? {
val existingArguments = arguments
val newArguments = existingArguments.toCommonizedArguments(classifiers) ?: return null
val newArguments = existingArguments.toCommonizedArguments(typeCommonizer) ?: return null
val existingUnderlyingType = underlyingType
val newUnderlyingType = when (existingUnderlyingType) {
is CirClassType -> existingUnderlyingType.withCommonizedArguments(classifiers)
is CirTypeAliasType -> existingUnderlyingType.withCommonizedArguments(classifiers)
is CirClassType -> existingUnderlyingType.withCommonizedArguments(typeCommonizer)
is CirTypeAliasType -> existingUnderlyingType.withCommonizedArguments(typeCommonizer)
} ?: return null
return if (newArguments !== existingArguments || newUnderlyingType !== existingUnderlyingType)
@@ -66,8 +67,6 @@ private fun CirTypeAliasType.withCommonizedArguments(classifiers: CirKnownClassi
}
@Suppress("NOTHING_TO_INLINE")
private inline fun List<CirTypeProjection>.toCommonizedArguments(classifiers: CirKnownClassifiers): List<CirTypeProjection>? =
if (isEmpty())
this
else
TypeArgumentListCommonizer(classifiers).let { if (it.commonizeWith(this)) it.result else null }
private inline fun List<CirTypeProjection>.toCommonizedArguments(typeCommonizer: TypeCommonizer): List<CirTypeProjection>? =
if (isEmpty()) this
else TypeArgumentListCommonizer(typeCommonizer).let { if (it.commonizeWith(this)) it.result else null }
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
import org.jetbrains.kotlin.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
import org.jetbrains.kotlin.commonizer.metadata.CirTreeSerializer
import org.jetbrains.kotlin.commonizer.transformer.AliasedTypeSubstitutor
import org.jetbrains.kotlin.commonizer.transformer.InlineTypeAliasCirNodeTransformer
import org.jetbrains.kotlin.commonizer.transformer.TypeSubstitutionCirNodeTransformer
import org.jetbrains.kotlin.commonizer.transformer.UnderscoredTypeAliasTypeSubstitutor
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
import org.jetbrains.kotlin.commonizer.tree.defaultCirTreeRootDeserializer
import org.jetbrains.kotlin.commonizer.tree.mergeCirTree
@@ -65,17 +62,7 @@ internal fun commonizeTarget(
InlineTypeAliasCirNodeTransformer(parameters.storageManager, classifiers).invoke(mergedTree)
TypeSubstitutionCirNodeTransformer(
parameters.storageManager, classifiers,
AliasedTypeSubstitutor(classifiers.commonDependencies, classifiers.classifierIndices)
).invoke(mergedTree)
TypeSubstitutionCirNodeTransformer(
parameters.storageManager, classifiers,
UnderscoredTypeAliasTypeSubstitutor(classifiers.classifierIndices)
).invoke(mergedTree)
mergedTree.accept(CommonizationVisitor(classifiers, mergedTree), Unit)
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
return mergedTree
}
@@ -57,7 +57,7 @@ internal fun buildPropertyNode(
storageManager = storageManager,
size = size,
nodeRelationship = nodeRelationship,
commonizerProducer = { PropertyCommonizer(classifiers) },
commonizerProducer = { PropertyCommonizer(FunctionOrPropertyBaseCommonizer(TypeCommonizer(classifiers))) },
nodeProducer = ::CirPropertyNode
)
@@ -70,7 +70,10 @@ internal fun buildFunctionNode(
storageManager = storageManager,
size = size,
nodeRelationship = nodeRelationship,
commonizerProducer = { FunctionCommonizer(classifiers) },
commonizerProducer = {
val typeCommonizer = TypeCommonizer(classifiers)
FunctionCommonizer(typeCommonizer, FunctionOrPropertyBaseCommonizer(typeCommonizer)).asCommonizer()
},
nodeProducer = ::CirFunctionNode
)
@@ -84,7 +87,10 @@ internal fun buildClassNode(
storageManager = storageManager,
size = size,
nodeRelationship = nodeRelationship,
commonizerProducer = { ClassCommonizer(classifiers) },
commonizerProducer = {
val typeCommonizer = TypeCommonizer(classifiers)
ClassCommonizer(typeCommonizer, ClassSuperTypeCommonizer(classifiers, typeCommonizer))
},
recursionMarker = CirClassRecursionMarker,
nodeProducer = { targetDeclarations, commonDeclaration ->
CirClassNode(classId, targetDeclarations, commonDeclaration).also {
@@ -103,7 +109,7 @@ internal fun buildClassConstructorNode(
storageManager = storageManager,
size = size,
nodeRelationship = nodeRelationship,
commonizerProducer = { ClassConstructorCommonizer(classifiers) },
commonizerProducer = { ClassConstructorCommonizer(TypeCommonizer(classifiers)) },
nodeProducer = ::CirClassConstructorNode
)
@@ -116,7 +122,7 @@ internal fun buildTypeAliasNode(
storageManager = storageManager,
size = size,
nodeRelationship = null,
commonizerProducer = { TypeAliasCommonizer(classifiers).asCommonizer() },
commonizerProducer = { TypeAliasCommonizer(TypeCommonizer(classifiers), classifiers).asCommonizer() },
recursionMarker = CirTypeAliasRecursionMarker,
nodeProducer = { targetDeclarations, commonDeclaration ->
CirTypeAliasNode(typeAliasId, targetDeclarations, commonDeclaration).also {
@@ -145,12 +151,13 @@ private fun <T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNod
return nodeProducer(targetDeclarations, commonLazyValue)
}
@Suppress("UNCHECKED_CAST")
internal fun <T : Any, R> commonize(
targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R>
): R? {
if (targetDeclarations.any { it == null }) return null
return commonizer.commonize(targetDeclarations.filterNotNull())
return commonizer.commonize(targetDeclarations as List<T>)
}
@Suppress("NOTHING_TO_INLINE")
@@ -34,6 +34,10 @@ internal inline fun <T, R> Array<T>.compactMap(transform: (T) -> R): List<R> =
else -> mapTo(ArrayList(size), transform)
}
internal inline fun <T, R : Any> Array<T>.compactMapNotNull(transform: (T) -> R): List<R> {
return mapNotNullTo(ArrayList<R>(size), transform).also { it.trimToSize() }
}
internal inline fun <T, reified R : Any> Collection<T>.compactMapNotNull(transform: (T) -> R?): List<R> =
if (isEmpty()) emptyList() else mapNotNullTo(ArrayList(size), transform).compact()
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.commonizer.utils.MOCK_CLASSIFIERS
import org.jetbrains.kotlin.commonizer.utils.mockClassType
import org.junit.Test
class ExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionReceiver?, CirExtensionReceiver?>() {
class ExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionReceiver?, ExtensionReceiverCommonizer.Commonized?>() {
@Test
fun nullReceiver() = doTestSuccess(
@@ -20,7 +20,7 @@ class ExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionRecei
@Test
fun sameReceiver() = doTestSuccess(
expected = mockExtensionReceiver("kotlin/String"),
expected = ExtensionReceiverCommonizer.Commonized(mockExtensionReceiver("kotlin/String")),
mockExtensionReceiver("kotlin/String"),
mockExtensionReceiver("kotlin/String"),
mockExtensionReceiver("kotlin/String")
@@ -47,7 +47,7 @@ class ExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionRecei
mockExtensionReceiver("kotlin/String")
)
override fun createCommonizer() = ExtensionReceiverCommonizer(MOCK_CLASSIFIERS)
override fun createCommonizer() = ExtensionReceiverCommonizer(TypeCommonizer(MOCK_CLASSIFIERS)).asCommonizer()
}
private fun mockExtensionReceiver(receiverClassId: String) = CirExtensionReceiver(
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.junit.Before
import org.junit.Test
class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType?>() {
private lateinit var classifiers: CirKnownClassifiers
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.types.Variance
import org.junit.Test
class TypeParameterCommonizerTest : AbstractCommonizerTest<CirTypeParameter, CirTypeParameter>() {
override fun createCommonizer() = TypeParameterCommonizer(MOCK_CLASSIFIERS)
override fun createCommonizer() = TypeParameterCommonizer(TypeCommonizer(MOCK_CLASSIFIERS))
@Test
fun allAreReified() = doTestSuccess(
@@ -108,7 +108,7 @@ class TypeParameterListCommonizerTest : AbstractCommonizerTest<List<CirTypeParam
)
)
override fun createCommonizer() = TypeParameterListCommonizer(MOCK_CLASSIFIERS)
override fun createCommonizer() = TypeParameterListCommonizer(TypeCommonizer(MOCK_CLASSIFIERS))
private companion object {
fun mockTypeParams(vararg params: Pair<String, String>): List<CirTypeParameter> {
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.commonizer.utils.MOCK_CLASSIFIERS
import org.jetbrains.kotlin.commonizer.utils.mockClassType
import org.junit.Test
class ValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParameter, CirValueParameter>() {
class ValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParameter, CirValueParameter?>() {
@Test
fun sameReturnType1() = doTestSuccess(
@@ -137,7 +137,7 @@ class ValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParameter, C
mockValueParam("kotlin/String", declaresDefaultValue = true)
)
override fun createCommonizer() = ValueParameterCommonizer(MOCK_CLASSIFIERS)
override fun createCommonizer() = ValueParameterCommonizer(TypeCommonizer(MOCK_CLASSIFIERS))
override fun areEqual(a: CirValueParameter?, b: CirValueParameter?) =
(a === b) || (a != null && b != null && areEqual(MOCK_CLASSIFIERS, a, b))
@@ -149,7 +149,7 @@ class ValueParameterListCommonizerTest : AbstractCommonizerTest<List<CirValuePar
)
)
override fun createCommonizer() = ValueParameterListCommonizer(MOCK_CLASSIFIERS)
override fun createCommonizer() = ValueParameterListCommonizer(TypeCommonizer(MOCK_CLASSIFIERS))
override fun areEqual(a: List<CirValueParameter>?, b: List<CirValueParameter>?): Boolean {
if (a === b)