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)
This commit is contained in:
Alexander Udalov
2018-12-21 17:11:41 +01:00
parent 07931451b1
commit 7561502956
3 changed files with 16 additions and 38 deletions
@@ -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<ESEffect> = 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
}
}
}
@@ -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<ConditionalEffect>): 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<ConditionalEffect>.strictPartition(
firstModel: ESEffect,
secondModel: ESEffect
): Pair<List<ConditionalEffect>, List<ConditionalEffect>> {
val first = mutableListOf<ConditionalEffect>()
val second = mutableListOf<ConditionalEffect>()
forEach {
if (it.simpleEffect == firstModel) first += it
if (it.simpleEffect == secondModel) second += it
}
return first to second
}
@@ -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<ESEffect> = 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
}
}
}