From 10c38ba47c1bbb2d4b92cd74357bd2b3508bf787 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 28 Jan 2022 15:06:59 +0300 Subject: [PATCH] [FIR] Reorganize cone type utilities Make some overrides of members of Cone types final --- .../kotlin/fir/types/ConeBuiltinTypeUtils.kt | 52 ++++++++++++++ .../fir/types/ConeIntegerLiteralType.kt | 4 -- .../kotlin/fir/types/ConeTypeUtils.kt | 71 +++++++------------ .../jetbrains/kotlin/fir/types/ConeTypes.kt | 37 ++-------- 4 files changed, 84 insertions(+), 80 deletions(-) create mode 100644 compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeBuiltinTypeUtils.kt diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeBuiltinTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeBuiltinTypeUtils.kt new file mode 100644 index 00000000000..6f04622f679 --- /dev/null +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeBuiltinTypeUtils.kt @@ -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): Boolean { + if (this !is ConeClassLikeType) return false + return lookupTag.classId in classIds +} diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralType.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralType.kt index fcf39552500..79a09769f1f 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralType.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralType.kt @@ -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 -} diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt index 1b6ad0fed9f..1c211b3caac 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt @@ -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()?.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): 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): Boolean { - if (this !is ConeClassLikeType) return false - return lookupTag.classId in classIds -} diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index e1c4c6aa8a2..5ae2e8abab0 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -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 - 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 + final override val typeArguments: Array 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)) -}