[NI] Correctly compute definitely not null type for intersection one
{ T : Any? & Foo & Bar? }!! -> { T!! & Foo & Bar }
Also, fix bug with loosing non-representative number type.
For example, for type { Byte & SomeType } we lost type `Byte` because
`getDefaultPrimitiveNumberType` returns null for it
Fixes #KT-28334 for NI
This commit is contained in:
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope
|
||||
|
||||
import java.util.*
|
||||
|
||||
class IntersectionTypeConstructor(typesToIntersect: Collection<KotlinType>) : TypeConstructor {
|
||||
@@ -63,3 +62,22 @@ class IntersectionTypeConstructor(typesToIntersect: Collection<KotlinType>) : Ty
|
||||
|
||||
override fun hashCode(): Int = hashCode
|
||||
}
|
||||
|
||||
inline fun IntersectionTypeConstructor.transformComponents(
|
||||
predicate: (KotlinType) -> Boolean = { true },
|
||||
transform: (KotlinType) -> KotlinType
|
||||
): IntersectionTypeConstructor? {
|
||||
var changed = false
|
||||
val newSupertypes = supertypes.map {
|
||||
if (predicate(it)) {
|
||||
changed = true
|
||||
transform(it)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed) return null
|
||||
|
||||
return IntersectionTypeConstructor(newSupertypes)
|
||||
}
|
||||
@@ -111,7 +111,28 @@ val KotlinType.isDefinitelyNotNullType: Boolean
|
||||
get() = unwrap() is DefinitelyNotNullType
|
||||
|
||||
fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleType =
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(this) ?: makeNullableAsSpecified(false)
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(this)
|
||||
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
||||
?: makeNullableAsSpecified(false)
|
||||
|
||||
fun UnwrappedType.makeDefinitelyNotNullOrNotNull(): UnwrappedType =
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(this) ?: makeNullableAsSpecified(false)
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(this)
|
||||
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
||||
?: makeNullableAsSpecified(false)
|
||||
|
||||
private fun KotlinType.makeIntersectionTypeDefinitelyNotNullOrNotNull(): SimpleType? {
|
||||
val typeConstructor = constructor as? IntersectionTypeConstructor ?: return null
|
||||
val definitelyNotNullConstructor = typeConstructor.makeDefinitelyNotNullOrNotNull() ?: return null
|
||||
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
annotations,
|
||||
definitelyNotNullConstructor,
|
||||
listOf(),
|
||||
false,
|
||||
definitelyNotNullConstructor.createScopeForKotlinType()
|
||||
)
|
||||
}
|
||||
|
||||
private fun IntersectionTypeConstructor.makeDefinitelyNotNullOrNotNull(): IntersectionTypeConstructor? {
|
||||
return transformComponents({ TypeUtils.isNullableType(it) }, { it.unwrap().makeDefinitelyNotNullOrNotNull() })
|
||||
}
|
||||
|
||||
@@ -153,8 +153,7 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
|
||||
}
|
||||
|
||||
is IntersectionTypeConstructor -> if (type.isMarkedNullable) {
|
||||
val newSuperTypes = constructor.supertypes.map { it.makeNullable() }
|
||||
val newConstructor = IntersectionTypeConstructor(newSuperTypes)
|
||||
val newConstructor = constructor.transformComponents(transform = { it.makeNullable() }) ?: constructor
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(type.annotations, newConstructor, listOf(), false, newConstructor.createScopeForKotlinType())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user