From 6506d35aa6a759bfa7f1b43ff3b0c0489e44f1c4 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 17 Feb 2022 11:49:30 +0300 Subject: [PATCH] FIR: add forgotten ConeIntegerLiteralIntersector (relates to KT-51357) --- .../types/ConeIntegerLiteralIntersector.kt | 36 +++++++++++++++++++ .../kotlin/fir/types/ConeTypeIntersector.kt | 3 +- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralIntersector.kt diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralIntersector.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralIntersector.kt new file mode 100644 index 00000000000..302ed0c15ad --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralIntersector.kt @@ -0,0 +1,36 @@ +/* + * 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 + +object ConeIntegerLiteralIntersector { + fun findCommonIntersectionType(types: Collection): ConeKotlinType? { + if (types.isEmpty()) return null + return types.reduce { left: ConeKotlinType?, right: ConeKotlinType? -> fold(left, right) } + } + + private fun fold(left: ConeKotlinType?, right: ConeKotlinType?): ConeKotlinType? { + if (left == null || right == null) return null + return when { + left is ConeIntegerLiteralType && right is ConeIntegerLiteralType -> + fold(left, right) + + left is ConeIntegerLiteralType -> fold(left, right) + right is ConeIntegerLiteralType -> fold(right, left) + else -> null + } + } + + private fun fold(left: ConeIntegerLiteralType, right: ConeIntegerLiteralType): ConeKotlinType? { + return when { + left.possibleTypes.containsAll(right.possibleTypes) -> right + right.possibleTypes.containsAll(left.possibleTypes) -> left + else -> null + } + } + + private fun fold(left: ConeIntegerLiteralType, right: ConeKotlinType): ConeKotlinType? = + if (right in left.possibleTypes) right else null +} \ No newline at end of file diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt index ab3f348898a..93946100754 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt @@ -69,8 +69,7 @@ object ConeTypeIntersector { } assert(filteredEqualTypes.isNotEmpty(), errorMessage) - // TODO - // IntegerLiteralTypeConstructor.findIntersectionType(filteredEqualTypes)?.let { return it } + ConeIntegerLiteralIntersector.findCommonIntersectionType(filteredEqualTypes)?.let { return it } /* * For the case like it(ft(String..String?), String?), where ft(String..String?) == String?, we prefer to _keep_ flexible type.