[FIR] Reorganize cone type utilities

Make some overrides of members of Cone types final
This commit is contained in:
Dmitriy Novozhilov
2022-01-28 15:06:59 +03:00
committed by teamcity
parent 0bd3e8f418
commit 10c38ba47c
4 changed files with 84 additions and 80 deletions
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2022 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.fir.types
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds
val ConeKotlinType.isAny: Boolean get() = isBuiltinType(StandardClassIds.Any, false)
val ConeKotlinType.isNullableAny: Boolean get() = isBuiltinType(StandardClassIds.Any, true)
val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, false)
val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
val ConeKotlinType.isNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, true)
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Boolean))
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
val ConeKotlinType.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false)
val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes)
val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
val ConeKotlinType.isArrayType: Boolean
get() {
return isBuiltinType(StandardClassIds.Array, false) ||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
}
// Same as [KotlinBuiltIns#isNonPrimitiveArray]
val ConeKotlinType.isNonPrimitiveArray: Boolean
get() = this is ConeClassLikeType && lookupTag.classId == StandardClassIds.Array
val ConeKotlinType.isPrimitiveArray: Boolean
get() = this is ConeClassLikeType && lookupTag.classId in StandardClassIds.primitiveArrayTypeByElementType.values
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(StandardClassIds.unsignedTypes)
val ConeKotlinType.isUnsignedType: Boolean get() = isUnsignedTypeOrNullableUnsignedType && nullability == ConeNullability.NOT_NULL
val ConeKotlinType.isIntegerTypeOrNullableIntegerTypeOfAnySize: Boolean get() = isAnyOfBuiltinType(builtinIntegerTypes)
private val builtinIntegerTypes = setOf(StandardClassIds.Int, StandardClassIds.Byte, StandardClassIds.Long, StandardClassIds.Short)
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean?): Boolean {
if (this !is ConeClassLikeType) return false
return lookupTag.classId == classId && (isNullable == null || type.isNullable == isNullable)
}
private fun ConeKotlinType.isAnyOfBuiltinType(classIds: Set<ClassId>): Boolean {
if (this !is ConeClassLikeType) return false
return lookupTag.classId in classIds
}
@@ -35,7 +35,3 @@ abstract class ConeIntegerLiteralType(
return 31 * possibleTypes.hashCode() + nullability.hashCode()
}
}
fun ConeIntegerLiteralType.canBeInt(): Boolean {
return value in Int.MIN_VALUE..Int.MAX_VALUE
}
@@ -7,16 +7,13 @@ package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
val ConeKotlinType.isNullable: Boolean get() = nullability != ConeNullability.NOT_NULL
val ConeKotlinType.isMarkedNullable: Boolean get() = nullability == ConeNullability.NULLABLE
val ConeKotlinType.classId: ClassId? get() = this.safeAs<ConeClassLikeType>()?.lookupTag?.classId
val ConeKotlinType.classId: ClassId? get() = (this as? ConeClassLikeType)?.lookupTag?.classId
/**
* Recursively visits each [ConeKotlinType] inside (including itself) and performs the given action.
@@ -52,6 +49,30 @@ private fun ConeKotlinType.contains(predicate: (ConeKotlinType) -> Boolean, visi
}
}
// ----------------------------------- Transformations -----------------------------------
fun ConeKotlinType.upperBoundIfFlexible(): ConeSimpleKotlinType {
return when (this) {
is ConeSimpleKotlinType -> this
is ConeFlexibleType -> upperBound
}
}
fun ConeKotlinType.lowerBoundIfFlexible(): ConeSimpleKotlinType {
return when (this) {
is ConeSimpleKotlinType -> this
is ConeFlexibleType -> lowerBound
}
}
fun ConeIntersectionType.withAlternative(alternativeType: ConeKotlinType): ConeIntersectionType {
return ConeIntersectionType(intersectedTypes, alternativeType)
}
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
return ConeIntersectionType(intersectedTypes.map(func), alternativeType?.let(func))
}
fun ConeClassLikeType.withArguments(typeArguments: Array<out ConeTypeProjection>): ConeClassLikeType = when (this) {
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, isNullable, attributes)
is ConeErrorType -> this
@@ -79,45 +100,3 @@ fun ConeClassLikeType.replaceArgumentsWithStarProjections(): ConeClassLikeType {
val newArguments = Array(typeArguments.size) { ConeStarProjection }
return withArguments(newArguments)
}
val ConeKotlinType.isAny: Boolean get() = isBuiltinType(StandardClassIds.Any, false)
val ConeKotlinType.isNullableAny: Boolean get() = isBuiltinType(StandardClassIds.Any, true)
val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, false)
val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
val ConeKotlinType.isNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, true)
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Boolean))
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
val ConeKotlinType.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false)
val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes)
val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
val ConeKotlinType.isArrayType: Boolean
get() {
return isBuiltinType(StandardClassIds.Array, false) ||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
}
// Same as [KotlinBuiltIns#isNonPrimitiveArray]
val ConeKotlinType.isNonPrimitiveArray: Boolean
get() = this is ConeClassLikeType && lookupTag.classId == StandardClassIds.Array
val ConeKotlinType.isPrimitiveArray: Boolean
get() = this is ConeClassLikeType && lookupTag.classId in StandardClassIds.primitiveArrayTypeByElementType.values
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(StandardClassIds.unsignedTypes)
val ConeKotlinType.isUnsignedType: Boolean get() = isUnsignedTypeOrNullableUnsignedType && nullability == ConeNullability.NOT_NULL
private val builtinIntegerTypes = setOf(StandardClassIds.Int, StandardClassIds.Byte, StandardClassIds.Long, StandardClassIds.Short)
val ConeKotlinType.isIntegerTypeOrNullableIntegerTypeOfAnySize: Boolean get() = isAnyOfBuiltinType(builtinIntegerTypes)
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean?): Boolean {
if (this !is ConeClassLikeType) return false
return lookupTag.classId == classId && (isNullable == null || type.isNullable == isNullable)
}
private fun ConeKotlinType.isAnyOfBuiltinType(classIds: Set<ClassId>): Boolean {
if (this !is ConeClassLikeType) return false
return lookupTag.classId in classIds
}
@@ -15,12 +15,12 @@ import org.jetbrains.kotlin.utils.addToStdlib.foldMap
// We assume type IS an invariant type projection to prevent additional wrapper here
// (more exactly, invariant type projection contains type)
sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, TypeArgumentListMarker {
override val kind: ProjectionKind
final override val kind: ProjectionKind
get() = ProjectionKind.INVARIANT
abstract val typeArguments: Array<out ConeTypeProjection>
override val type: ConeKotlinType
final override val type: ConeKotlinType
get() = this
abstract val nullability: ConeNullability
@@ -69,16 +69,16 @@ open class ConeFlexibleType(
val upperBound: ConeSimpleKotlinType
) : ConeKotlinType(), FlexibleTypeMarker {
override val typeArguments: Array<out ConeTypeProjection>
final override val typeArguments: Array<out ConeTypeProjection>
get() = lowerBound.typeArguments
override val nullability: ConeNullability
final override val nullability: ConeNullability
get() = lowerBound.nullability.takeIf { it == upperBound.nullability } ?: ConeNullability.UNKNOWN
override val attributes: ConeAttributes
final override val attributes: ConeAttributes
get() = lowerBound.attributes
override fun equals(other: Any?): Boolean {
final override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
@@ -90,26 +90,11 @@ open class ConeFlexibleType(
return true
}
override fun hashCode(): Int {
final override fun hashCode(): Int {
var result = lowerBound.hashCode()
result = 31 * result + upperBound.hashCode()
return result
}
}
fun ConeKotlinType.upperBoundIfFlexible(): ConeSimpleKotlinType {
return when (this) {
is ConeSimpleKotlinType -> this
is ConeFlexibleType -> upperBound
}
}
fun ConeKotlinType.lowerBoundIfFlexible(): ConeSimpleKotlinType {
return when (this) {
is ConeSimpleKotlinType -> this
is ConeFlexibleType -> lowerBound
}
}
fun ConeSimpleKotlinType.unwrapDefinitelyNotNull(): ConeSimpleKotlinType {
@@ -232,11 +217,3 @@ class ConeIntersectionType(
return intersectedTypes.hashCode().also { hashCode = it }
}
}
fun ConeIntersectionType.withAlternative(alternativeType: ConeKotlinType): ConeIntersectionType {
return ConeIntersectionType(intersectedTypes, alternativeType)
}
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
return ConeIntersectionType(intersectedTypes.map(func), alternativeType?.let(func))
}