From 25621d699bf7efe9a7eeef980da6de01a01e0911 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 17 Jun 2020 10:21:34 +0300 Subject: [PATCH] Add methods for combine InvocationKind's There is two methods added -- `or` and `and` `or` is used by CFA for combining two kinds that came from different edges of control flow graph `and` is analog of `+` operator for invocation kinds --- .../serialization/FirContractSerializer.kt | 2 +- .../contracts/description/InvocationKind.kt | 33 +++++++++++++++---- .../serialization/ContractSerializer.kt | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt index 288b25ead1c..48776b68c1d 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt @@ -197,7 +197,7 @@ class FirContractSerializer { InvocationKind.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE InvocationKind.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE InvocationKind.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE - InvocationKind.UNKNOWN -> null + else -> null } private fun constantValueProtobufEnum(constantReference: ConeConstantReference): ProtoBuf.Expression.ConstantValue? = diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt index e98d89ee53c..72aef24b2b0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt @@ -5,13 +5,34 @@ package org.jetbrains.kotlin.contracts.description -enum class InvocationKind { - AT_MOST_ONCE, - EXACTLY_ONCE, - AT_LEAST_ONCE, - UNKNOWN +import kotlin.math.max +import kotlin.math.min + +enum class InvocationKind(private val left: Int, private val right: Int) { + ZERO(0, 0), // 0..0 + AT_MOST_ONCE(0, 1), // 0..1 + EXACTLY_ONCE(1, 1), // 1..1 + AT_LEAST_ONCE(1, 2), // 1..* + UNKNOWN(0, 2); // 0..* + + companion object { + private fun fromRange(left: Int, right: Int): InvocationKind = when (min(left, 1) to min(right, 2)) { + 0 to 0 -> ZERO + 0 to 1 -> AT_MOST_ONCE + 1 to 1 -> EXACTLY_ONCE + 1 to 2 -> AT_LEAST_ONCE + 0 to 2 -> UNKNOWN + else -> throw IllegalArgumentException() + } + + fun or(x: InvocationKind, y: InvocationKind): InvocationKind = fromRange(min(x.left, y.left), max(x.right, y.right)) + + fun and(x: InvocationKind, y: InvocationKind): InvocationKind = fromRange(x.left + y.left, x.right + y.right) + } + + infix fun or(other: InvocationKind): InvocationKind = Companion.or(this, other) + infix fun and(other: InvocationKind): InvocationKind = Companion.and(this, other) } fun InvocationKind.isDefinitelyVisited(): Boolean = this == InvocationKind.EXACTLY_ONCE || this == InvocationKind.AT_LEAST_ONCE fun InvocationKind.canBeRevisited(): Boolean = this == InvocationKind.UNKNOWN || this == InvocationKind.AT_LEAST_ONCE - diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt index f4048a33846..72cceb445ae 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt @@ -192,7 +192,7 @@ class ContractSerializer { InvocationKind.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE InvocationKind.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE InvocationKind.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE - InvocationKind.UNKNOWN -> null + else -> null } private fun constantValueProtobufEnum(constantReference: ConstantReference): ProtoBuf.Expression.ConstantValue? =