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
|
package org.jetbrains.kotlin.contracts.model.functors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.contracts.model.structure.ESReturns
|
import org.jetbrains.kotlin.contracts.model.Computation
|
||||||
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.ConditionalEffect
|
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
|
||||||
import org.jetbrains.kotlin.contracts.model.ESEffect
|
import org.jetbrains.kotlin.contracts.model.ESEffect
|
||||||
import org.jetbrains.kotlin.contracts.model.Computation
|
import org.jetbrains.kotlin.contracts.model.structure.*
|
||||||
|
|
||||||
class AndFunctor : AbstractBinaryFunctor() {
|
class AndFunctor : AbstractBinaryFunctor() {
|
||||||
override fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect> = when (constant) {
|
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).
|
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 */
|
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 leftTrue = left.filter { it.simpleEffect.isReturns { value.isTrue } }
|
||||||
val (rightTrue, rightFalse) = right.strictPartition(ESReturns(true.lift()), ESReturns(false.lift()))
|
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 whenLeftReturnsTrue = foldConditionsWithOr(leftTrue)
|
||||||
val whenRightReturnsTrue = foldConditionsWithOr(rightTrue)
|
val whenRightReturnsTrue = foldConditionsWithOr(rightTrue)
|
||||||
@@ -68,4 +66,4 @@ class AndFunctor : AbstractBinaryFunctor() {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-20
@@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.contracts.model.functors
|
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.ConditionalEffect
|
||||||
import org.jetbrains.kotlin.contracts.model.ESEffect
|
|
||||||
import org.jetbrains.kotlin.contracts.model.ESExpression
|
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
|
* 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
|
null
|
||||||
else
|
else
|
||||||
list.map { it.condition }.reduce { acc, condition -> ESOr(acc, condition) }
|
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
|
package org.jetbrains.kotlin.contracts.model.functors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.contracts.model.structure.ESReturns
|
import org.jetbrains.kotlin.contracts.model.Computation
|
||||||
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.ConditionalEffect
|
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
|
||||||
import org.jetbrains.kotlin.contracts.model.ESEffect
|
import org.jetbrains.kotlin.contracts.model.ESEffect
|
||||||
import org.jetbrains.kotlin.contracts.model.Computation
|
import org.jetbrains.kotlin.contracts.model.structure.*
|
||||||
|
|
||||||
class OrFunctor : AbstractBinaryFunctor() {
|
class OrFunctor : AbstractBinaryFunctor() {
|
||||||
override fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect> = when (constant) {
|
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.
|
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).
|
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 */
|
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 whenLeftReturnsTrue = foldConditionsWithOr(leftTrue)
|
||||||
val whenRightReturnsTrue = foldConditionsWithOr(rightTrue)
|
val whenRightReturnsTrue = foldConditionsWithOr(rightTrue)
|
||||||
@@ -67,4 +66,4 @@ class OrFunctor : AbstractBinaryFunctor() {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user