From 7561502956e66e989e550d08bf1faba441ff85a4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 21 Dec 2018 17:11:41 +0100 Subject: [PATCH] Refactor AndFunctor/OrFunction: do not use strictPartition Instead use a filter with a simple check. This seems to be slightly better both for readability (`strictPartition` gave an impression that two its parameters were related in some way, but they were totally independent) and for performance (do not create unnecessary objects, instead decompose the existing objects and check their structure) --- .../contracts/model/functors/AndFunctor.kt | 16 +++++++------- .../contracts/model/functors/FunctorsUtils.kt | 21 +------------------ .../contracts/model/functors/OrFunctor.kt | 17 +++++++-------- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt index 5f22925e5cc..380d4bf0a2a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt @@ -16,14 +16,10 @@ package org.jetbrains.kotlin.contracts.model.functors -import org.jetbrains.kotlin.contracts.model.structure.ESReturns -import org.jetbrains.kotlin.contracts.model.structure.ESAnd -import org.jetbrains.kotlin.contracts.model.structure.ESConstant -import org.jetbrains.kotlin.contracts.model.structure.ESOr -import org.jetbrains.kotlin.contracts.model.structure.lift +import org.jetbrains.kotlin.contracts.model.Computation import org.jetbrains.kotlin.contracts.model.ConditionalEffect import org.jetbrains.kotlin.contracts.model.ESEffect -import org.jetbrains.kotlin.contracts.model.Computation +import org.jetbrains.kotlin.contracts.model.structure.* class AndFunctor : AbstractBinaryFunctor() { override fun invokeWithConstant(computation: Computation, constant: ESConstant): List = when (constant) { @@ -40,8 +36,10 @@ class AndFunctor : AbstractBinaryFunctor() { with Returns(1) (note that they still *return* as guaranteed by AbstractSequentialBinaryFunctor). We will just ignore such clauses in order to make smartcasting robust while typing */ - val (leftTrue, leftFalse) = left.strictPartition(ESReturns(true.lift()), ESReturns(false.lift())) - val (rightTrue, rightFalse) = right.strictPartition(ESReturns(true.lift()), ESReturns(false.lift())) + val leftTrue = left.filter { it.simpleEffect.isReturns { value.isTrue } } + val leftFalse = left.filter { it.simpleEffect.isReturns { value.isFalse } } + val rightTrue = right.filter { it.simpleEffect.isReturns { value.isTrue } } + val rightFalse = right.filter { it.simpleEffect.isReturns { value.isFalse } } val whenLeftReturnsTrue = foldConditionsWithOr(leftTrue) val whenRightReturnsTrue = foldConditionsWithOr(rightTrue) @@ -68,4 +66,4 @@ class AndFunctor : AbstractBinaryFunctor() { return result } -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt index e4ab6b7fe3f..ee6a1a17702 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.contracts.model.functors -import org.jetbrains.kotlin.contracts.model.structure.ESOr import org.jetbrains.kotlin.contracts.model.ConditionalEffect -import org.jetbrains.kotlin.contracts.model.ESEffect import org.jetbrains.kotlin.contracts.model.ESExpression +import org.jetbrains.kotlin.contracts.model.structure.ESOr /** * Applies [operation] to [first] and [second] if both not-null, otherwise returns null @@ -44,21 +43,3 @@ internal fun foldConditionsWithOr(list: List): ESExpression? null else list.map { it.condition }.reduce { acc, condition -> ESOr(acc, condition) } - -/** - * Places all clauses that equal to `firstModel` into first list, and all clauses that equal to `secondModel` into second list - */ -internal fun List.strictPartition( - firstModel: ESEffect, - secondModel: ESEffect -): Pair, List> { - val first = mutableListOf() - val second = mutableListOf() - - forEach { - if (it.simpleEffect == firstModel) first += it - if (it.simpleEffect == secondModel) second += it - } - - return first to second -} \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt index 39675379b07..0cca101a07b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt @@ -16,14 +16,10 @@ package org.jetbrains.kotlin.contracts.model.functors -import org.jetbrains.kotlin.contracts.model.structure.ESReturns -import org.jetbrains.kotlin.contracts.model.structure.ESAnd -import org.jetbrains.kotlin.contracts.model.structure.ESConstant -import org.jetbrains.kotlin.contracts.model.structure.ESOr -import org.jetbrains.kotlin.contracts.model.structure.lift +import org.jetbrains.kotlin.contracts.model.Computation import org.jetbrains.kotlin.contracts.model.ConditionalEffect import org.jetbrains.kotlin.contracts.model.ESEffect -import org.jetbrains.kotlin.contracts.model.Computation +import org.jetbrains.kotlin.contracts.model.structure.* class OrFunctor : AbstractBinaryFunctor() { override fun invokeWithConstant(computation: Computation, constant: ESConstant): List = when (constant) { @@ -39,8 +35,11 @@ class OrFunctor : AbstractBinaryFunctor() { expression wasn't properly typechecked, we could get some senseless clauses here, e.g. with Returns(1) (note that they still *return* as guaranteed by AbstractSequentialBinaryFunctor). We will just ignore such clauses in order to make smartcasting robust while typing */ - val (leftTrue, leftFalse) = left.strictPartition(ESReturns(true.lift()), ESReturns(false.lift())) - val (rightTrue, rightFalse) = right.strictPartition(ESReturns(true.lift()), ESReturns(false.lift())) + + val leftTrue = left.filter { it.simpleEffect.isReturns { value.isTrue } } + val leftFalse = left.filter { it.simpleEffect.isReturns { value.isFalse } } + val rightTrue = right.filter { it.simpleEffect.isReturns { value.isTrue } } + val rightFalse = right.filter { it.simpleEffect.isReturns { value.isFalse } } val whenLeftReturnsTrue = foldConditionsWithOr(leftTrue) val whenRightReturnsTrue = foldConditionsWithOr(rightTrue) @@ -67,4 +66,4 @@ class OrFunctor : AbstractBinaryFunctor() { return result } -} \ No newline at end of file +}