Add FlexibleTypeBoundsChecker which can answer the question: "can two types be different bounds of the same flexible type?"; and provide the base bound for the given bound.
For instance: `MutableList` and `List` may be within the same flexible type.
This commit is contained in:
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererOptions
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.checker.ErrorTypesAreEqualToAnything
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
@@ -147,3 +150,34 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object FlexibleTypeBoundsChecker {
|
||||
private val fqNames = StandardNames.FqNames
|
||||
private val baseTypesToMutableEquivalent = mapOf(
|
||||
fqNames.iterable to fqNames.mutableIterable,
|
||||
fqNames.iterator to fqNames.mutableIterator,
|
||||
fqNames.listIterator to fqNames.mutableListIterator,
|
||||
fqNames.list to fqNames.mutableList,
|
||||
fqNames.collection to fqNames.mutableCollection,
|
||||
fqNames.set to fqNames.mutableSet,
|
||||
fqNames.map to fqNames.mutableMap,
|
||||
fqNames.mapEntry to fqNames.mutableMapEntry
|
||||
)
|
||||
private val mutableToBaseMap = baseTypesToMutableEquivalent.entries.associateBy({ it.value }) { it.key }
|
||||
|
||||
fun areTypesMayBeLowerAndUpperBoundsOfSameFlexibleTypeByMutability(a: KotlinType, b: KotlinType): Boolean {
|
||||
val fqName = a.constructor.declarationDescriptor?.fqNameSafe ?: return false
|
||||
val possiblePairBound = (baseTypesToMutableEquivalent[fqName] ?: mutableToBaseMap[fqName]) ?: return false
|
||||
|
||||
return possiblePairBound == b.constructor.declarationDescriptor?.fqNameSafe
|
||||
}
|
||||
|
||||
// We consider base bounds as not mutable collections
|
||||
fun getBaseBoundFqNameByMutability(a: KotlinType): FqName? {
|
||||
val fqName = a.constructor.declarationDescriptor?.fqNameSafe ?: return null
|
||||
|
||||
if (fqName in baseTypesToMutableEquivalent) return fqName
|
||||
|
||||
return mutableToBaseMap[fqName]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user