[Commonizer] Move type commonization to single invocation commonizer
^KT-48288
This commit is contained in:
committed by
Space
parent
3ee87f1635
commit
97e37243c6
+41
-39
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -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>(
|
||||
|
||||
+2
-3
@@ -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)
|
||||
}
|
||||
|
||||
+8
-9
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -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) {
|
||||
|
||||
+3
-4
@@ -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
|
||||
}
|
||||
|
||||
+19
-10
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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>()
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+6
-7
@@ -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")
|
||||
|
||||
+13
-21
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -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
|
||||
|
||||
+4
-5
@@ -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() }
|
||||
)
|
||||
|
||||
+2
-3
@@ -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) }
|
||||
)
|
||||
|
||||
+15
-13
@@ -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
|
||||
|
||||
+2
-3
@@ -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()
|
||||
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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(
|
||||
|
||||
+1
-1
@@ -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> {
|
||||
|
||||
+2
-2
@@ -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))
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user