From 07931451b14302deec0e01ea82c2a03fa2560b6e Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 21 Dec 2018 17:58:24 +0100 Subject: [PATCH] Add utilities to check if ESValue is boolean/wildcard constant --- .../model/functors/AbstractBinaryFunctor.kt | 5 +++-- .../model/functors/AbstractUnaryFunctor.kt | 4 ++-- .../contracts/model/functors/EqualsFunctor.kt | 15 ++++++------- .../model/functors/SubstitutingFunctor.kt | 21 +++++++------------ .../contracts/model/structure/Effects.kt | 3 +-- .../contracts/model/structure/Values.kt | 16 +++++++++++--- .../contracts/model/visitors/Reducer.kt | 18 ++++++++-------- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt index 7ca856f2fbb..039d037a524 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.contracts.model.ConditionalEffect import org.jetbrains.kotlin.contracts.model.ESEffect import org.jetbrains.kotlin.contracts.model.structure.ESConstant import org.jetbrains.kotlin.contracts.model.structure.isReturns +import org.jetbrains.kotlin.contracts.model.structure.isWildcard abstract class AbstractBinaryFunctor : AbstractReducingFunctor() { override fun doInvocation(arguments: List): List { @@ -33,9 +34,9 @@ abstract class AbstractBinaryFunctor : AbstractReducingFunctor() { if (right is ESConstant) return invokeWithConstant(left, right) val leftValueReturning = - left.effects.filterIsInstance().filter { it.simpleEffect.isReturns { value != ESConstant.WILDCARD } } + left.effects.filterIsInstance().filter { it.simpleEffect.isReturns { !value.isWildcard } } val rightValueReturning = - right.effects.filterIsInstance().filter { it.simpleEffect.isReturns { value != ESConstant.WILDCARD } } + right.effects.filterIsInstance().filter { it.simpleEffect.isReturns { !value.isWildcard } } val nonInterestingEffects = left.effects - leftValueReturning + right.effects - rightValueReturning diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractUnaryFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractUnaryFunctor.kt index 9a39f88c606..8e4fc23b7c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractUnaryFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractUnaryFunctor.kt @@ -19,8 +19,8 @@ package org.jetbrains.kotlin.contracts.model.functors 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.structure.ESConstant import org.jetbrains.kotlin.contracts.model.structure.isReturns +import org.jetbrains.kotlin.contracts.model.structure.isWildcard /** * Unary functor that has sequential semantics, i.e. it won't apply to @@ -37,7 +37,7 @@ abstract class AbstractUnaryFunctor : AbstractReducingFunctor() { fun invokeWithArguments(arg: Computation): List { val returning = - arg.effects.filterIsInstance().filter { it.simpleEffect.isReturns { value != ESConstant.WILDCARD } } + arg.effects.filterIsInstance().filter { it.simpleEffect.isReturns { !value.isWildcard } } val rest = arg.effects - returning val evaluatedByFunctor = invokeWithReturningEffects(returning) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt index 7f94b11c81e..cc02569f8c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt @@ -16,15 +16,12 @@ package org.jetbrains.kotlin.contracts.model.functors -import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.contracts.model.structure.ESReturns -import org.jetbrains.kotlin.contracts.model.structure.ESConstant -import org.jetbrains.kotlin.contracts.model.structure.ESEqual -import org.jetbrains.kotlin.contracts.model.ESValue -import org.jetbrains.kotlin.contracts.model.structure.lift -import org.jetbrains.kotlin.contracts.model.* 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.ESValue +import org.jetbrains.kotlin.contracts.model.structure.* class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { /* @@ -74,7 +71,7 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { val resultingClauses = mutableListOf() for (effect in call.effects) { - if (effect !is ConditionalEffect || effect.simpleEffect !is ESReturns || effect.simpleEffect.value == ESConstant.WILDCARD) { + if (effect !is ConditionalEffect || effect.simpleEffect !is ESReturns || effect.simpleEffect.value.isWildcard) { resultingClauses += effect continue } @@ -115,4 +112,4 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { ConditionalEffect(ESEqual(left, right, isNegated.not()), ESReturns(false.lift())) ) } -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt index 456dd6178f4..f0924092b45 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt @@ -16,15 +16,8 @@ package org.jetbrains.kotlin.contracts.model.functors -import org.jetbrains.kotlin.contracts.model.structure.ESCalls -import org.jetbrains.kotlin.contracts.model.structure.ESReturns -import org.jetbrains.kotlin.contracts.model.structure.ESConstant -import org.jetbrains.kotlin.contracts.model.ESValue -import org.jetbrains.kotlin.contracts.model.structure.ESVariable -import org.jetbrains.kotlin.contracts.model.ConditionalEffect -import org.jetbrains.kotlin.contracts.model.ESEffect -import org.jetbrains.kotlin.contracts.model.SimpleEffect -import org.jetbrains.kotlin.contracts.model.Computation +import org.jetbrains.kotlin.contracts.model.* +import org.jetbrains.kotlin.contracts.model.structure.* import org.jetbrains.kotlin.contracts.model.visitors.Substitutor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueDescriptor @@ -54,8 +47,8 @@ class SubstitutingFunctor(private val basicEffects: List, private val } is ESCalls -> { - val subsitutionForCallable = substitutions[effect.callable] as? ESValue ?: continue@effectsLoop - substitutedClauses += ESCalls(subsitutionForCallable, effect.kind) + val substitutionForCallable = substitutions[effect.callable] as? ESValue ?: continue@effectsLoop + substitutedClauses += ESCalls(substitutionForCallable, effect.kind) } else -> substitutedClauses += effect @@ -69,12 +62,12 @@ class SubstitutingFunctor(private val basicEffects: List, private val if (substitutedCondition !is ConditionalEffect) return null val effectFromCondition = substitutedCondition.simpleEffect - if (effectFromCondition !is ESReturns || effectFromCondition.value == ESConstant.WILDCARD) return substitutedCondition + if (effectFromCondition !is ESReturns || effectFromCondition.value.isWildcard) return substitutedCondition - if (effectFromCondition.value != ESConstant.TRUE) return null + if (!effectFromCondition.value.isTrue) return null return ConditionalEffect(substitutedCondition.condition, effect) } private fun ValueDescriptor.toESVariable(): ESVariable = ESVariable(this) -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt index 9df25a7a909..284d6dbe370 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.contracts.model.structure -import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference import org.jetbrains.kotlin.contracts.description.InvocationKind import org.jetbrains.kotlin.contracts.model.ESEffect import org.jetbrains.kotlin.contracts.model.ESValue @@ -40,7 +39,7 @@ data class ESReturns(val value: ESValue) : SimpleEffect() { if (this.value !is ESConstant || other.value !is ESConstant) return this.value == other.value // ESReturns(x) implies ESReturns(?) for any 'x' - if (other.value.constantReference == ConstantReference.WILDCARD) return true + if (other.value.isWildcard) return true return value == other.value } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Values.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Values.kt index 099f4ae3a87..8480cdcfd6c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Values.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Values.kt @@ -17,11 +17,12 @@ package org.jetbrains.kotlin.contracts.model.structure import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.descriptors.ValueDescriptor -import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference import org.jetbrains.kotlin.contracts.description.expressions.BooleanConstantReference +import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference +import org.jetbrains.kotlin.contracts.model.ESExpression import org.jetbrains.kotlin.contracts.model.ESExpressionVisitor import org.jetbrains.kotlin.contracts.model.ESValue +import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.makeNullable import java.util.* @@ -74,4 +75,13 @@ open class ESConstant private constructor(open val constantReference: ConstantRe fun isNullConstant(): Boolean = this == NULL || this == NOT_NULL } -fun Boolean.lift(): ESConstant = if (this) ESConstant.TRUE else ESConstant.FALSE \ No newline at end of file +fun Boolean.lift(): ESConstant = if (this) ESConstant.TRUE else ESConstant.FALSE + +internal val ESExpression.isTrue: Boolean + get() = this is ESConstant && constantReference == BooleanConstantReference.TRUE + +internal val ESExpression.isFalse: Boolean + get() = this is ESConstant && constantReference == BooleanConstantReference.FALSE + +internal val ESValue.isWildcard: Boolean + get() = this is ESConstant && constantReference == ConstantReference.WILDCARD diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt index c7397272531..758508d5b7c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt @@ -36,10 +36,10 @@ class Reducer : ESExpressionVisitor { val reducedCondition = effect.condition.accept(this) ?: return null // Filter never executed conditions - if (reducedCondition is ESConstant && reducedCondition == ESConstant.FALSE) return null + if (reducedCondition.isFalse) return null // Add always firing effects - if (reducedCondition is ESConstant && reducedCondition == ESConstant.TRUE) return effect.simpleEffect + if (reducedCondition.isTrue) return effect.simpleEffect // Leave everything else as is return effect @@ -76,9 +76,9 @@ class Reducer : ESExpressionVisitor { val reducedRight = and.right.accept(this) ?: return null return when { - reducedLeft == false.lift() || reducedRight == false.lift() -> false.lift() - reducedLeft == true.lift() -> reducedRight - reducedRight == true.lift() -> reducedLeft + reducedLeft.isFalse || reducedRight.isFalse -> reducedLeft + reducedLeft.isTrue -> reducedRight + reducedRight.isTrue -> reducedLeft else -> ESAnd(reducedLeft, reducedRight) } } @@ -88,9 +88,9 @@ class Reducer : ESExpressionVisitor { val reducedRight = or.right.accept(this) ?: return null return when { - reducedLeft == true.lift() || reducedRight == true.lift() -> true.lift() - reducedLeft == false.lift() -> reducedRight - reducedRight == false.lift() -> reducedLeft + reducedLeft.isTrue || reducedRight.isTrue -> reducedLeft + reducedLeft.isFalse -> reducedRight + reducedRight.isFalse -> reducedLeft else -> ESOr(reducedLeft, reducedRight) } } @@ -108,4 +108,4 @@ class Reducer : ESExpressionVisitor { override fun visitVariable(esVariable: ESVariable): ESVariable = esVariable override fun visitConstant(esConstant: ESConstant): ESConstant = esConstant -} \ No newline at end of file +}