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:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-20
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user