[Commonizer] Implement new ClassOrTypeAliasTypeCommonizer
^KT-47432 Verification Pending ^KT-47434 Verification Pending
This commit is contained in:
committed by
Space
parent
8e2780345c
commit
8f73df0f85
@@ -25,9 +25,12 @@ object CirClassRecursionMarker : CirClass, CirRecursionMarker {
|
|||||||
set(_) = unsupported()
|
set(_) = unsupported()
|
||||||
}
|
}
|
||||||
|
|
||||||
object CirClassifierRecursionMarker : CirClassifier, CirRecursionMarker {
|
object CirTypeAliasRecursionMarker : CirTypeAlias, CirRecursionMarker {
|
||||||
|
override val underlyingType: CirClassOrTypeAliasType get() = unsupported()
|
||||||
|
override val expandedType: CirClassType get() = unsupported()
|
||||||
override val annotations get() = unsupported()
|
override val annotations get() = unsupported()
|
||||||
override val name get() = unsupported()
|
override val name get() = unsupported()
|
||||||
override val typeParameters get() = unsupported()
|
override val typeParameters get() = unsupported()
|
||||||
override val visibility get() = unsupported()
|
override val visibility get() = unsupported()
|
||||||
|
override val isLiftedUp: Boolean get() = unsupported()
|
||||||
}
|
}
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.CirClassOrTypeAliasType
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType
|
||||||
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||||
|
|
||||||
|
internal class ClassOrTypeAliasTypeStatelessCommonizer(
|
||||||
|
private val classifiers: CirKnownClassifiers
|
||||||
|
) : StatelessCommonizer<CirClassOrTypeAliasType, CirClassOrTypeAliasType> {
|
||||||
|
|
||||||
|
override fun commonize(values: List<CirClassOrTypeAliasType>): CirClassOrTypeAliasType? {
|
||||||
|
if (values.isEmpty()) return null
|
||||||
|
values.singleOrNull()?.let { return it }
|
||||||
|
|
||||||
|
val classTypes = values.filterIsInstance<CirClassType>()
|
||||||
|
val typeAliasTypes = values.filterIsInstance<CirTypeAliasType>()
|
||||||
|
val expandedTypeAliasTypes = typeAliasTypes.map { it.expandedType() }
|
||||||
|
|
||||||
|
if (values.all { it is CirClassType }) {
|
||||||
|
return ClassTypeCommonizer(classifiers).commonize(classTypes)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.all { it is CirTypeAliasType }) {
|
||||||
|
/*
|
||||||
|
In case regular type-alias-type commonization fails, we try to expand all type-aliases and
|
||||||
|
try our luck with commonizing those class types
|
||||||
|
*/
|
||||||
|
return TypeAliasTypeCommonizer(classifiers).commonize(typeAliasTypes)
|
||||||
|
?: ClassTypeCommonizer(classifiers).commonize(expandedTypeAliasTypes)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
There are type-alias types & class types enqueued for commonization.
|
||||||
|
We reduce all classes to a common representation and all type aliases to a common representation.
|
||||||
|
*/
|
||||||
|
val commonizedClass = ClassTypeCommonizer(classifiers).commonize(classTypes) ?: return null
|
||||||
|
val commonizedTypeAlias = TypeAliasTypeCommonizer(classifiers).commonize(typeAliasTypes)
|
||||||
|
|
||||||
|
if (commonizedTypeAlias != null) {
|
||||||
|
return ClassTypeCommonizer(classifiers).commonize(listOf(commonizedClass, commonizedTypeAlias.expandedType()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If type-alias type commonization failed:
|
||||||
|
Last attempt: Try to commonize all type-alias expansions with the commonized class
|
||||||
|
*/
|
||||||
|
return ClassTypeCommonizer(classifiers).commonize(expandedTypeAliasTypes + commonizedClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ClassOrTypeAliasTypeCommonizer(classifiers: CirKnownClassifiers) :
|
||||||
|
StatelessCommonizerAdapter<CirClassOrTypeAliasType, CirClassOrTypeAliasType>(ClassOrTypeAliasTypeStatelessCommonizer(classifiers))
|
||||||
|
|
||||||
|
internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) {
|
||||||
|
is CirClassType -> this
|
||||||
|
is CirTypeAliasType -> this.underlyingType.expandedType()
|
||||||
|
}
|
||||||
@@ -10,6 +10,16 @@ interface Commonizer<T, R> {
|
|||||||
fun commonizeWith(next: T): Boolean
|
fun commonizeWith(next: T): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T, R> Commonizer<T, R>.commonize(values: List<T>): R? {
|
||||||
|
/* Fast path: If commonizer supports StatelessCommonizer interface */
|
||||||
|
if (this is StatelessCommonizerAdapter) {
|
||||||
|
return commonize(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
values.forEach { value -> if (!commonizeWith(value)) return null }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractStandardCommonizer<T, R> : Commonizer<T, R> {
|
abstract class AbstractStandardCommonizer<T, R> : Commonizer<T, R> {
|
||||||
private enum class State {
|
private enum class State {
|
||||||
EMPTY,
|
EMPTY,
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
interface StatelessCommonizer<T, R> {
|
||||||
|
fun commonize(values: List<T>): R?
|
||||||
|
}
|
||||||
|
|
||||||
|
open class StatelessCommonizerAdapter<T, R : Any>(
|
||||||
|
private val commonizer: StatelessCommonizer<T, R>
|
||||||
|
) : AbstractStandardCommonizer<T, R>(), StatelessCommonizer<T, R> by commonizer {
|
||||||
|
private val values = mutableListOf<T>()
|
||||||
|
|
||||||
|
override fun commonizationResult(): R {
|
||||||
|
try {
|
||||||
|
return checkNotNull(commonize(values.toList()))
|
||||||
|
} finally {
|
||||||
|
values.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize(first: T) = Unit
|
||||||
|
|
||||||
|
override fun doCommonizeWith(next: T): Boolean {
|
||||||
|
values.add(next)
|
||||||
|
return commonize(values.toList()) != null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,11 +17,11 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
* Secondary (less optimistic) branch:
|
* Secondary (less optimistic) branch:
|
||||||
* - Make sure that all TAs are identical, so the resulting TA can be lifted up into "common" fragment.
|
* - Make sure that all TAs are identical, so the resulting TA can be lifted up into "common" fragment.
|
||||||
*/
|
*/
|
||||||
class TypeAliasCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeAlias, CirClassifier>() {
|
class TypeAliasCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
|
||||||
private val primary = TypeAliasShortCircuitingCommonizer(classifiers)
|
private val primary = TypeAliasShortCircuitingCommonizer(classifiers)
|
||||||
private val secondary = TypeAliasLiftingUpCommonizer(classifiers)
|
private val secondary = TypeAliasLiftingUpCommonizer(classifiers)
|
||||||
|
|
||||||
override fun commonizationResult(): CirClassifier = primary.resultOrNull ?: secondary.result
|
override fun commonizationResult(): CirTypeAlias = primary.resultOrNull ?: secondary.result
|
||||||
|
|
||||||
override fun initialize(first: CirTypeAlias) = Unit
|
override fun initialize(first: CirTypeAlias) = Unit
|
||||||
|
|
||||||
|
|||||||
@@ -14,61 +14,30 @@ import org.jetbrains.kotlin.commonizer.utils.isUnderKotlinNativeSyntheticPackage
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
|
||||||
class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirType, CirType>() {
|
class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirType, CirType>() {
|
||||||
private var typeCommonizer: AbstractStandardCommonizer<*, CirType>? = null
|
private lateinit var typeCommonizer: Commonizer<*, CirType>
|
||||||
private var underlyingTypeCommonizer: TypeCommonizer? = null
|
|
||||||
|
|
||||||
override fun commonizationResult() = typeCommonizer?.resultOrNull
|
override fun commonizationResult() = typeCommonizer.result
|
||||||
?: underlyingTypeCommonizer?.result
|
|
||||||
?: typeCommonizer?.result
|
|
||||||
?: failInErrorState()
|
|
||||||
|
|
||||||
override fun initialize(first: CirType) {
|
override fun initialize(first: CirType) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
typeCommonizer = when (first) {
|
typeCommonizer = when (first) {
|
||||||
is CirClassType -> ClassTypeCommonizer(classifiers)
|
is CirClassOrTypeAliasType -> ClassOrTypeAliasTypeCommonizer(classifiers)
|
||||||
is CirTypeAliasType -> TypeAliasTypeCommonizer(classifiers)
|
|
||||||
is CirTypeParameterType -> TypeParameterTypeCommonizer()
|
is CirTypeParameterType -> TypeParameterTypeCommonizer()
|
||||||
is CirFlexibleType -> FlexibleTypeCommonizer(classifiers)
|
is CirFlexibleType -> FlexibleTypeCommonizer(classifiers)
|
||||||
} as AbstractStandardCommonizer<*, CirType>
|
} as Commonizer<*, CirType>
|
||||||
|
|
||||||
if (first is CirTypeAliasType) {
|
|
||||||
underlyingTypeCommonizer = TypeCommonizer(classifiers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCommonizeWith(next: CirType): Boolean {
|
override fun doCommonizeWith(next: CirType): Boolean {
|
||||||
return when (next) {
|
return when (next) {
|
||||||
is CirClassType -> doCommonizeWithClassType(next)
|
is CirClassOrTypeAliasType -> (typeCommonizer as? ClassOrTypeAliasTypeCommonizer)?.commonizeWith(next) == true
|
||||||
is CirTypeAliasType -> doCommonizeWithTypeAliasType(next)
|
|
||||||
is CirTypeParameterType -> (typeCommonizer as? TypeParameterTypeCommonizer)?.commonizeWith(next) == true
|
is CirTypeParameterType -> (typeCommonizer as? TypeParameterTypeCommonizer)?.commonizeWith(next) == true
|
||||||
is CirFlexibleType -> (typeCommonizer as? FlexibleTypeCommonizer)?.commonizeWith(next) == true
|
is CirFlexibleType -> (typeCommonizer as? FlexibleTypeCommonizer)?.commonizeWith(next) == true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCommonizeWithClassType(next: CirClassType): Boolean {
|
|
||||||
if ((typeCommonizer as? ClassTypeCommonizer) == null) {
|
|
||||||
typeCommonizer = null
|
|
||||||
}
|
|
||||||
|
|
||||||
val firstAnswer = (typeCommonizer as? ClassTypeCommonizer)?.commonizeWith(next) == true
|
|
||||||
val secondAnswer = underlyingTypeCommonizer?.commonizeWith(next) == true
|
|
||||||
return firstAnswer || secondAnswer
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doCommonizeWithTypeAliasType(next: CirTypeAliasType): Boolean {
|
|
||||||
if (typeCommonizer != null && underlyingTypeCommonizer == null) {
|
|
||||||
underlyingTypeCommonizer = TypeCommonizer(classifiers)
|
|
||||||
underlyingTypeCommonizer?.commonizeWith(typeCommonizer?.resultOrNull ?: return false)
|
|
||||||
typeCommonizer = null
|
|
||||||
}
|
|
||||||
|
|
||||||
val firstAnswer = (typeCommonizer as? TypeAliasTypeCommonizer)?.commonizeWith(next) == true
|
|
||||||
val secondAnswer = underlyingTypeCommonizer?.commonizeWith(next.underlyingType) == true
|
|
||||||
return firstAnswer || secondAnswer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirClassType, CirClassType>() {
|
internal class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers) :
|
||||||
|
AbstractStandardCommonizer<CirClassType, CirClassType>() {
|
||||||
private lateinit var classId: CirEntityId
|
private lateinit var classId: CirEntityId
|
||||||
private val outerType = OuterClassTypeCommonizer(classifiers)
|
private val outerType = OuterClassTypeCommonizer(classifiers)
|
||||||
private lateinit var anyVisibility: Visibility
|
private lateinit var anyVisibility: Visibility
|
||||||
@@ -101,14 +70,15 @@ private class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers)
|
|||||||
&& arguments.commonizeWith(next.arguments)
|
&& arguments.commonizeWith(next.arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OuterClassTypeCommonizer(classifiers: CirKnownClassifiers) :
|
// TODO NOW
|
||||||
|
internal class OuterClassTypeCommonizer(classifiers: CirKnownClassifiers) :
|
||||||
AbstractNullableCommonizer<CirClassType, CirClassType, CirClassType, CirClassType>(
|
AbstractNullableCommonizer<CirClassType, CirClassType, CirClassType, CirClassType>(
|
||||||
wrappedCommonizerFactory = { ClassTypeCommonizer(classifiers) },
|
wrappedCommonizerFactory = { ClassTypeCommonizer(classifiers) },
|
||||||
extractor = { it },
|
extractor = { it },
|
||||||
builder = { it }
|
builder = { it }
|
||||||
)
|
)
|
||||||
|
|
||||||
private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifiers) :
|
internal class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifiers) :
|
||||||
AbstractStandardCommonizer<CirTypeAliasType, CirClassOrTypeAliasType>() {
|
AbstractStandardCommonizer<CirTypeAliasType, CirClassOrTypeAliasType>() {
|
||||||
|
|
||||||
private lateinit var typeAliasId: CirEntityId
|
private lateinit var typeAliasId: CirEntityId
|
||||||
@@ -125,11 +95,11 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie
|
|||||||
|
|
||||||
override fun initialize(first: CirTypeAliasType) {
|
override fun initialize(first: CirTypeAliasType) {
|
||||||
typeAliasId = first.classifierId
|
typeAliasId = first.classifierId
|
||||||
isMarkedNullable = first.isMarkedNullable
|
isMarkedNullable = first.expandedType().isMarkedNullable
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCommonizeWith(next: CirTypeAliasType): Boolean {
|
override fun doCommonizeWith(next: CirTypeAliasType): Boolean {
|
||||||
if (isMarkedNullable != next.isMarkedNullable || typeAliasId != next.classifierId)
|
if (isMarkedNullable != next.expandedType().isMarkedNullable || typeAliasId != next.classifierId)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if (commonizedTypeBuilder == null) {
|
if (commonizedTypeBuilder == null) {
|
||||||
@@ -152,7 +122,7 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// builds a new type for "common" library fragment for the given combination of type alias types in "platform" fragments
|
// builds a new type for "common" library fragment for the given combination of type alias types in "platform" fragments
|
||||||
private interface CommonizedTypeAliasTypeBuilder {
|
internal interface CommonizedTypeAliasTypeBuilder {
|
||||||
fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean): CirClassOrTypeAliasType
|
fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean): CirClassOrTypeAliasType
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -161,7 +131,7 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie
|
|||||||
override fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
|
override fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
|
||||||
CirClassType.createInterned(
|
CirClassType.createInterned(
|
||||||
classId = typeAliasId,
|
classId = typeAliasId,
|
||||||
outerType = null, // there can't be outer type
|
outerType = null, // there can't be outer type // TODO NOW!!!
|
||||||
visibility = commonClass.visibility,
|
visibility = commonClass.visibility,
|
||||||
arguments = arguments,
|
arguments = arguments,
|
||||||
isMarkedNullable = isMarkedNullable
|
isMarkedNullable = isMarkedNullable
|
||||||
@@ -257,7 +227,7 @@ private fun commonizeTypeAlias(typeAliasId: CirEntityId, classifiers: CirKnownCl
|
|||||||
return create(typeAliasNode?.commonDeclaration?.invoke() ?: classNode?.commonDeclaration?.invoke())
|
return create(typeAliasNode?.commonDeclaration?.invoke() ?: classNode?.commonDeclaration?.invoke())
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CommonizedTypeAliasAnswer(val commonized: Boolean, val commonClassifier: CirClassifier?) {
|
internal class CommonizedTypeAliasAnswer(val commonized: Boolean, val commonClassifier: CirClassifier?) {
|
||||||
companion object {
|
companion object {
|
||||||
val SUCCESS_FROM_DEPENDENCY_LIBRARY = CommonizedTypeAliasAnswer(true, null)
|
val SUCCESS_FROM_DEPENDENCY_LIBRARY = CommonizedTypeAliasAnswer(true, null)
|
||||||
val FAILURE_MISSING_IN_SOME_TARGET = CommonizedTypeAliasAnswer(false, null)
|
val FAILURE_MISSING_IN_SOME_TARGET = CommonizedTypeAliasAnswer(false, null)
|
||||||
|
|||||||
+2
-3
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.mergedtree
|
package org.jetbrains.kotlin.commonizer.mergedtree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirClassifier
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirTypeAlias
|
import org.jetbrains.kotlin.commonizer.cir.CirTypeAlias
|
||||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||||
@@ -14,8 +13,8 @@ import org.jetbrains.kotlin.storage.NullableLazyValue
|
|||||||
class CirTypeAliasNode(
|
class CirTypeAliasNode(
|
||||||
val id: CirEntityId,
|
val id: CirEntityId,
|
||||||
override val targetDeclarations: CommonizedGroup<CirTypeAlias>,
|
override val targetDeclarations: CommonizedGroup<CirTypeAlias>,
|
||||||
override val commonDeclaration: NullableLazyValue<CirClassifier>,
|
override val commonDeclaration: NullableLazyValue<CirTypeAlias>,
|
||||||
) : CirClassifierNode<CirTypeAlias, CirClassifier>, CirNodeWithLiftingUp<CirTypeAlias, CirClassifier> {
|
) : CirClassifierNode<CirTypeAlias, CirTypeAlias>, CirNodeWithLiftingUp<CirTypeAlias, CirTypeAlias> {
|
||||||
|
|
||||||
override fun <T, R> accept(visitor: CirNodeVisitor<T, R>, data: T): R =
|
override fun <T, R> accept(visitor: CirNodeVisitor<T, R>, data: T): R =
|
||||||
visitor.visitTypeAliasNode(this, data)
|
visitor.visitTypeAliasNode(this, data)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.mergedtree
|
package org.jetbrains.kotlin.commonizer.mergedtree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirClassRecursionMarker
|
import org.jetbrains.kotlin.commonizer.cir.CirClassRecursionMarker
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirClassifierRecursionMarker
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirDeclaration
|
import org.jetbrains.kotlin.commonizer.cir.CirDeclaration
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasRecursionMarker
|
||||||
import org.jetbrains.kotlin.commonizer.core.*
|
import org.jetbrains.kotlin.commonizer.core.*
|
||||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||||
import org.jetbrains.kotlin.storage.NullableLazyValue
|
import org.jetbrains.kotlin.storage.NullableLazyValue
|
||||||
@@ -116,7 +116,7 @@ internal fun buildTypeAliasNode(
|
|||||||
size = size,
|
size = size,
|
||||||
nodeRelationship = null,
|
nodeRelationship = null,
|
||||||
commonizerProducer = { TypeAliasCommonizer(classifiers) },
|
commonizerProducer = { TypeAliasCommonizer(classifiers) },
|
||||||
recursionMarker = CirClassifierRecursionMarker,
|
recursionMarker = CirTypeAliasRecursionMarker,
|
||||||
nodeProducer = { targetDeclarations, commonDeclaration ->
|
nodeProducer = { targetDeclarations, commonDeclaration ->
|
||||||
CirTypeAliasNode(typeAliasId, targetDeclarations, commonDeclaration).also {
|
CirTypeAliasNode(typeAliasId, targetDeclarations, commonDeclaration).also {
|
||||||
classifiers.commonizedNodes.addTypeAliasNode(typeAliasId, it)
|
classifiers.commonizedNodes.addTypeAliasNode(typeAliasId, it)
|
||||||
@@ -148,12 +148,8 @@ internal fun <T : Any, R> commonize(
|
|||||||
targetDeclarations: CommonizedGroup<T>,
|
targetDeclarations: CommonizedGroup<T>,
|
||||||
commonizer: Commonizer<T, R>
|
commonizer: Commonizer<T, R>
|
||||||
): R? {
|
): R? {
|
||||||
for (targetDeclaration in targetDeclarations) {
|
if (targetDeclarations.any { it == null }) return null
|
||||||
if (targetDeclaration == null || !commonizer.commonizeWith(targetDeclaration))
|
return commonizer.commonize(targetDeclarations.filterNotNull())
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return commonizer.result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
@@ -176,4 +172,4 @@ private fun CirNodeRelationship?.shouldCommonize(): Boolean {
|
|||||||
is CirNodeRelationship.PreferredNode -> node.commonDeclaration() == null
|
is CirNodeRelationship.PreferredNode -> node.commonDeclaration() == null
|
||||||
is CirNodeRelationship.Composite -> relationships.all { it.shouldCommonize() }
|
is CirNodeRelationship.Composite -> relationships.all { it.shouldCommonize() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,21 +103,21 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
|
|||||||
fun classTypesInUserPackageWithDifferentNames1() = doTestFailure(
|
fun classTypesInUserPackageWithDifferentNames1() = doTestFailure(
|
||||||
mockClassType("org/sample/Foo"),
|
mockClassType("org/sample/Foo"),
|
||||||
mockClassType("org/fictitiousPackageName/Foo"),
|
mockClassType("org/fictitiousPackageName/Foo"),
|
||||||
shouldFailOnFirstVariant = true
|
shouldFailOnFirstVariant = false
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
@Test(expected = IllegalCommonizerStateException::class)
|
||||||
fun classTypesInUserPackageWithDifferentNames2() = doTestFailure(
|
fun classTypesInUserPackageWithDifferentNames2() = doTestFailure(
|
||||||
mockClassType("org/sample/Foo"),
|
mockClassType("org/sample/Foo"),
|
||||||
mockClassType("org/sample/Bar"),
|
mockClassType("org/sample/Bar"),
|
||||||
shouldFailOnFirstVariant = true
|
shouldFailOnFirstVariant = false
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
@Test(expected = IllegalCommonizerStateException::class)
|
||||||
fun classTypesInUserPackageWithDifferentNames3() = doTestFailure(
|
fun classTypesInUserPackageWithDifferentNames3() = doTestFailure(
|
||||||
mockClassType("org/sample/Foo"),
|
mockClassType("org/sample/Foo"),
|
||||||
mockClassType("kotlin/String"),
|
mockClassType("kotlin/String"),
|
||||||
shouldFailOnFirstVariant = true
|
shouldFailOnFirstVariant = false
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -364,19 +364,17 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
|
|||||||
mockTAType("kotlin/sequences/SequenceBuilder", nullable = false) { mockClassType("kotlin/sequences/SequenceScope") }
|
mockTAType("kotlin/sequences/SequenceBuilder", nullable = false) { mockClassType("kotlin/sequences/SequenceScope") }
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalCommonizerStateException::class)
|
||||||
// why success: nullability of underlying type does not matter if typealias belongs to one of the standard Kotlin packages
|
// why failure: Different nullability in type-expansion can't be commonized by now
|
||||||
fun taTypesInKotlinPackageWithDifferentNullability3() = doTestSuccess(
|
fun taTypesInKotlinPackageWithDifferentNullability3() = doTestFailure(
|
||||||
expected = mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) },
|
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) },
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) },
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) },
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) },
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) }
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) }
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalCommonizerStateException::class)
|
||||||
// why success: nullability of underlying type does not matter if typealias belongs to one of the standard Kotlin packages
|
// why failure: Different nullability in type-expansion can't be commonized by now
|
||||||
fun taTypesInKotlinPackageWithDifferentNullability4() = doTestSuccess(
|
fun taTypesInKotlinPackageWithDifferentNullability4() = doTestFailure(
|
||||||
expected = mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) },
|
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) },
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) },
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) },
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = true) },
|
||||||
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) }
|
mockTAType("kotlin/sequences/SequenceBuilder") { mockClassType("kotlin/sequences/SequenceScope", nullable = false) }
|
||||||
|
|||||||
Reference in New Issue
Block a user