[FIR] Refactor Condition classes
This commit is contained in:
@@ -5,69 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.dfa
|
package org.jetbrains.kotlin.fir.resolve.dfa
|
||||||
|
|
||||||
enum class ConditionValue(val token: String) {
|
enum class Condition {
|
||||||
True("true"), False("false"), Null("null");
|
EqTrue, EqFalse, EqNull, NotEqNull;
|
||||||
|
|
||||||
override fun toString(): String {
|
fun invert(): Condition = when (this) {
|
||||||
return token
|
EqTrue -> EqFalse
|
||||||
|
EqFalse -> EqTrue
|
||||||
|
EqNull -> NotEqNull
|
||||||
|
NotEqNull -> EqNull
|
||||||
}
|
}
|
||||||
|
|
||||||
fun invert(): ConditionValue? = when (this) {
|
override fun toString(): String = when (this) {
|
||||||
True -> False
|
EqTrue -> "== True"
|
||||||
False -> True
|
EqFalse -> "== False"
|
||||||
else -> null
|
EqNull -> "== Null"
|
||||||
|
NotEqNull -> "!= Null"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Boolean.toConditionValue(): ConditionValue = if (this) ConditionValue.True else ConditionValue.False
|
fun Boolean.toEqBoolean(): Condition = if (this) Condition.EqTrue else Condition.EqFalse
|
||||||
|
|
||||||
enum class ConditionOperator(val token: String) {
|
|
||||||
Eq("=="), NotEq("!=");
|
|
||||||
|
|
||||||
fun invert(): ConditionOperator = when (this) {
|
|
||||||
Eq -> NotEq
|
|
||||||
NotEq -> Eq
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Condition(val variable: DataFlowVariable, val rhs: ConditionRHS) {
|
|
||||||
val operator: ConditionOperator get() = rhs.operator
|
|
||||||
val value: ConditionValue get() = rhs.value
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
variable: DataFlowVariable,
|
|
||||||
operator: ConditionOperator,
|
|
||||||
value: ConditionValue
|
|
||||||
) : this(variable, ConditionRHS(operator, value))
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return "$variable $rhs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ConditionRHS(val operator: ConditionOperator, val value: ConditionValue) {
|
|
||||||
fun invert(): ConditionRHS {
|
|
||||||
val newValue = value.invert()
|
|
||||||
return if (newValue != null) {
|
|
||||||
ConditionRHS(operator, newValue)
|
|
||||||
} else {
|
|
||||||
ConditionRHS(operator.invert(), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return "$operator $value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal fun eq(value: ConditionValue): ConditionRHS = ConditionRHS(ConditionOperator.Eq, value)
|
|
||||||
internal fun notEq(value: ConditionValue): ConditionRHS = ConditionRHS(ConditionOperator.NotEq, value)
|
|
||||||
internal infix fun DataFlowVariable.eq(value: ConditionValue): Condition =
|
|
||||||
Condition(this, org.jetbrains.kotlin.fir.resolve.dfa.eq(value))
|
|
||||||
internal infix fun DataFlowVariable.notEq(value: ConditionValue): Condition =
|
|
||||||
Condition(this, org.jetbrains.kotlin.fir.resolve.dfa.notEq(value))
|
|
||||||
+1
-1
@@ -26,7 +26,7 @@ interface DataFlowInferenceContext : TypeSystemCommonSuperTypesContext, ConeInfe
|
|||||||
return when (types.size) {
|
return when (types.size) {
|
||||||
0 -> null
|
0 -> null
|
||||||
1 -> types.first()
|
1 -> types.first()
|
||||||
else -> ConeTypeIntersector.intersectTypes(this, types)
|
else -> ConeTypeIntersector.intersectTypes(this as ConeInferenceContext, types)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-36
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.ConditionValue.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.Condition.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirBodyResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
@@ -87,7 +87,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
val previousNode = node.usefulPreviousNodes.singleOrNull() as? WhenBranchConditionExitNode
|
val previousNode = node.usefulPreviousNodes.singleOrNull() as? WhenBranchConditionExitNode
|
||||||
if (previousNode != null) {
|
if (previousNode != null) {
|
||||||
node.flow = logicSystem.approveFactsInsideFlow(previousNode.trueCondition, node.flow)
|
node.flow = logicSystem.approveFactsInsideFlow(previousNode.variable, EqTrue, node.flow)
|
||||||
}
|
}
|
||||||
node.flow.freeze()
|
node.flow.freeze()
|
||||||
}
|
}
|
||||||
@@ -127,14 +127,14 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
eq(True), varVariable, chooseInfo(true)
|
EqTrue, varVariable, chooseInfo(true)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
eq(False), varVariable, chooseInfo(false)
|
EqFalse, varVariable, chooseInfo(false)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -148,12 +148,12 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
notEq(Null), varVariable, FirDataFlowInfo(setOf(type), emptySet())
|
NotEqNull, varVariable, FirDataFlowInfo(setOf(type), emptySet())
|
||||||
)
|
)
|
||||||
).addNotApprovedFact(
|
).addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
eq(Null), varVariable, FirDataFlowInfo(emptySet(), setOf(type))
|
EqNull, varVariable, FirDataFlowInfo(emptySet(), setOf(type))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
operandVariables.forEach { operandVariable ->
|
operandVariables.forEach { operandVariable ->
|
||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable, UnapprovedFirDataFlowInfo(
|
expressionVariable, UnapprovedFirDataFlowInfo(
|
||||||
eq(isEq.toConditionValue()),
|
isEq.toEqBoolean(),
|
||||||
operandVariable,
|
operandVariable,
|
||||||
FirDataFlowInfo(setOf(session.builtinTypes.anyType.coneTypeUnsafe()), emptySet())
|
FirDataFlowInfo(setOf(session.builtinTypes.anyType.coneTypeUnsafe()), emptySet())
|
||||||
)
|
)
|
||||||
@@ -247,22 +247,22 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
val expressionVariable = getVariable(node.fir)
|
val expressionVariable = getVariable(node.fir)
|
||||||
|
|
||||||
variableStorage[operand]?.let { operandVariable ->
|
variableStorage[operand]?.let { operandVariable ->
|
||||||
val operator = when (operation) {
|
val condition = when (operation) {
|
||||||
FirOperation.EQ, FirOperation.IDENTITY -> ConditionOperator.Eq
|
FirOperation.EQ, FirOperation.IDENTITY -> EqNull
|
||||||
FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY -> ConditionOperator.NotEq
|
FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY -> NotEqNull
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
val facts = logicSystem.approveFact(Condition(operandVariable, operator, Null), flow)
|
val facts = logicSystem.approveFact(operandVariable, condition, flow)
|
||||||
facts.forEach { (variable, info) ->
|
facts.forEach { (variable, info) ->
|
||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
eq(True), variable, info
|
EqTrue, variable, info
|
||||||
)
|
)
|
||||||
).addNotApprovedFact(
|
).addNotApprovedFact(
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
UnapprovedFirDataFlowInfo(
|
UnapprovedFirDataFlowInfo(
|
||||||
eq(False), variable, info.invert()
|
EqFalse, variable, info.invert()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -272,16 +272,16 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
val operandVariables = getRealVariablesForSafeCallChain(operand).takeIf { it.isNotEmpty() } ?: return
|
val operandVariables = getRealVariablesForSafeCallChain(operand).takeIf { it.isNotEmpty() } ?: return
|
||||||
|
|
||||||
val conditionValue = when (operation) {
|
val condition = when (operation) {
|
||||||
FirOperation.EQ, FirOperation.IDENTITY -> False
|
FirOperation.EQ, FirOperation.IDENTITY -> EqFalse
|
||||||
FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY -> True
|
FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY -> EqTrue
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
|
|
||||||
operandVariables.forEach { operandVariable ->
|
operandVariables.forEach { operandVariable ->
|
||||||
flow = flow.addNotApprovedFact(
|
flow = flow.addNotApprovedFact(
|
||||||
expressionVariable, UnapprovedFirDataFlowInfo(
|
expressionVariable, UnapprovedFirDataFlowInfo(
|
||||||
eq(conditionValue),
|
condition,
|
||||||
operandVariable,
|
operandVariable,
|
||||||
FirDataFlowInfo(setOf(session.builtinTypes.anyType.coneTypeUnsafe()), emptySet())
|
FirDataFlowInfo(setOf(session.builtinTypes.anyType.coneTypeUnsafe()), emptySet())
|
||||||
)
|
)
|
||||||
@@ -317,7 +317,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
val node = graphBuilder.enterWhenBranchCondition(whenBranch).passFlow(false)
|
val node = graphBuilder.enterWhenBranchCondition(whenBranch).passFlow(false)
|
||||||
val previousNode = node.previousNodes.single()
|
val previousNode = node.previousNodes.single()
|
||||||
if (previousNode is WhenBranchConditionExitNode) {
|
if (previousNode is WhenBranchConditionExitNode) {
|
||||||
node.flow = logicSystem.approveFactsInsideFlow(previousNode.falseCondition, node.flow)
|
node.flow = logicSystem.approveFactsInsideFlow(previousNode.variable, EqFalse, node.flow)
|
||||||
}
|
}
|
||||||
node.flow.freeze()
|
node.flow.freeze()
|
||||||
}
|
}
|
||||||
@@ -326,8 +326,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
val node = graphBuilder.exitWhenBranchCondition(whenBranch).passFlow()
|
val node = graphBuilder.exitWhenBranchCondition(whenBranch).passFlow()
|
||||||
|
|
||||||
val conditionVariable = getVariable(whenBranch.condition)
|
val conditionVariable = getVariable(whenBranch.condition)
|
||||||
node.trueCondition = conditionVariable eq True
|
node.variable = conditionVariable
|
||||||
node.falseCondition = conditionVariable eq False
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitWhenBranchResult(whenBranch: FirWhenBranch) {
|
override fun exitWhenBranchResult(whenBranch: FirWhenBranch) {
|
||||||
@@ -495,7 +494,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
leftNode.passFlow()
|
leftNode.passFlow()
|
||||||
rightNode.passFlow(false)
|
rightNode.passFlow(false)
|
||||||
val leftOperandVariable = getVariable(leftNode.previousNodes.first().fir)
|
val leftOperandVariable = getVariable(leftNode.previousNodes.first().fir)
|
||||||
rightNode.flow = logicSystem.approveFactsInsideFlow(leftOperandVariable eq True, rightNode.flow).also { it.freeze() }
|
rightNode.flow = logicSystem.approveFactsInsideFlow(leftOperandVariable, EqTrue, rightNode.flow).also { it.freeze() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression) {
|
override fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression) {
|
||||||
@@ -508,10 +507,10 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
val andVariable = getVariable(binaryLogicExpression)
|
val andVariable = getVariable(binaryLogicExpression)
|
||||||
|
|
||||||
val leftIsTrue = approveFact(leftVariable, True, flowFromRight)
|
val leftIsTrue = approveFact(leftVariable, EqTrue, flowFromRight)
|
||||||
val leftIsFalse = approveFact(leftVariable, False, flowFromRight)
|
val leftIsFalse = approveFact(leftVariable, EqFalse, flowFromRight)
|
||||||
val rightIsTrue = approveFact(rightVariable, True, flowFromRight) ?: mutableMapOf()
|
val rightIsTrue = approveFact(rightVariable, EqTrue, flowFromRight) ?: mutableMapOf()
|
||||||
val rightIsFalse = approveFact(rightVariable, False, flowFromRight)
|
val rightIsFalse = approveFact(rightVariable, EqFalse, flowFromRight)
|
||||||
|
|
||||||
flowFromRight.approvedFacts.forEach { (variable, info) ->
|
flowFromRight.approvedFacts.forEach { (variable, info) ->
|
||||||
val actualInfo = flowFromLeft.approvedFacts[variable]?.let { info - it } ?: info
|
val actualInfo = flowFromLeft.approvedFacts[variable]?.let { info - it } ?: info
|
||||||
@@ -520,12 +519,12 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
logicSystem.andForVerifiedFacts(leftIsTrue, rightIsTrue)?.let {
|
logicSystem.andForVerifiedFacts(leftIsTrue, rightIsTrue)?.let {
|
||||||
for ((variable, info) in it) {
|
for ((variable, info) in it) {
|
||||||
flow.addNotApprovedFact(andVariable, UnapprovedFirDataFlowInfo(eq(True), variable, info))
|
flow.addNotApprovedFact(andVariable, UnapprovedFirDataFlowInfo(EqTrue, variable, info))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logicSystem.orForVerifiedFacts(leftIsFalse, rightIsFalse)?.let {
|
logicSystem.orForVerifiedFacts(leftIsFalse, rightIsFalse)?.let {
|
||||||
for ((variable, info) in it) {
|
for ((variable, info) in it) {
|
||||||
flow.addNotApprovedFact(andVariable, UnapprovedFirDataFlowInfo(eq(False), variable, info))
|
flow.addNotApprovedFact(andVariable, UnapprovedFirDataFlowInfo(EqFalse, variable, info))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.flow = flow.removeSyntheticVariable(leftVariable).removeSyntheticVariable(rightVariable).also { it.freeze() }
|
node.flow = flow.removeSyntheticVariable(leftVariable).removeSyntheticVariable(rightVariable).also { it.freeze() }
|
||||||
@@ -540,7 +539,7 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
leftNode.passFlow()
|
leftNode.passFlow()
|
||||||
rightNode.passFlow(false)
|
rightNode.passFlow(false)
|
||||||
val leftOperandVariable = getVariable(leftNode.previousNodes.first().fir)
|
val leftOperandVariable = getVariable(leftNode.previousNodes.first().fir)
|
||||||
rightNode.flow = logicSystem.approveFactsInsideFlow(leftOperandVariable eq False, rightNode.flow).also { it.freeze() }
|
rightNode.flow = logicSystem.approveFactsInsideFlow(leftOperandVariable, EqFalse, rightNode.flow).also { it.freeze() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitBinaryOr(binaryLogicExpression: FirBinaryLogicExpression) {
|
override fun exitBinaryOr(binaryLogicExpression: FirBinaryLogicExpression) {
|
||||||
@@ -553,19 +552,19 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
val orVariable = getVariable(binaryLogicExpression)
|
val orVariable = getVariable(binaryLogicExpression)
|
||||||
|
|
||||||
val leftIsTrue = approveFact(leftVariable, True, flowFromLeft)
|
val leftIsTrue = approveFact(leftVariable, EqTrue, flowFromLeft)
|
||||||
val leftIsFalse = approveFact(leftVariable, False, flowFromLeft)
|
val leftIsFalse = approveFact(leftVariable, EqFalse, flowFromLeft)
|
||||||
val rightIsTrue = approveFact(rightVariable, True, flowFromRight)
|
val rightIsTrue = approveFact(rightVariable, EqTrue, flowFromRight)
|
||||||
val rightIsFalse = approveFact(rightVariable, False, flowFromRight)
|
val rightIsFalse = approveFact(rightVariable, EqFalse, flowFromRight)
|
||||||
|
|
||||||
logicSystem.orForVerifiedFacts(leftIsTrue, rightIsTrue)?.let {
|
logicSystem.orForVerifiedFacts(leftIsTrue, rightIsTrue)?.let {
|
||||||
for ((variable, info) in it) {
|
for ((variable, info) in it) {
|
||||||
flow.addNotApprovedFact(orVariable, UnapprovedFirDataFlowInfo(eq(True), variable, info))
|
flow.addNotApprovedFact(orVariable, UnapprovedFirDataFlowInfo(EqTrue, variable, info))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logicSystem.andForVerifiedFacts(leftIsFalse, rightIsFalse)?.let {
|
logicSystem.andForVerifiedFacts(leftIsFalse, rightIsFalse)?.let {
|
||||||
for ((variable, info) in it) {
|
for ((variable, info) in it) {
|
||||||
flow.addNotApprovedFact(orVariable, UnapprovedFirDataFlowInfo(eq(False), variable, info))
|
flow.addNotApprovedFact(orVariable, UnapprovedFirDataFlowInfo(EqFalse, variable, info))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.flow = flow.removeSyntheticVariable(leftVariable).removeSyntheticVariable(rightVariable).also { it.freeze() }
|
node.flow = flow.removeSyntheticVariable(leftVariable).removeSyntheticVariable(rightVariable).also { it.freeze() }
|
||||||
@@ -599,8 +598,8 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
|
|||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private fun approveFact(variable: DataFlowVariable, value: ConditionValue, flow: Flow): MutableMap<DataFlowVariable, FirDataFlowInfo>? =
|
private fun approveFact(variable: DataFlowVariable, condition: Condition, flow: Flow): MutableMap<DataFlowVariable, FirDataFlowInfo>? =
|
||||||
logicSystem.approveFact(variable eq value, flow)
|
logicSystem.approveFact(variable, condition, flow)
|
||||||
|
|
||||||
private fun FirBinaryLogicExpression.getVariables(): Pair<DataFlowVariable, DataFlowVariable> =
|
private fun FirBinaryLogicExpression.getVariables(): Pair<DataFlowVariable, DataFlowVariable> =
|
||||||
getVariable(leftOperand) to getVariable(rightOperand)
|
getVariable(leftOperand) to getVariable(rightOperand)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.render
|
||||||
|
|
||||||
data class UnapprovedFirDataFlowInfo(
|
data class UnapprovedFirDataFlowInfo(
|
||||||
val condition: ConditionRHS,
|
val condition: Condition,
|
||||||
val variable: DataFlowVariable,
|
val variable: DataFlowVariable,
|
||||||
val info: FirDataFlowInfo
|
val info: FirDataFlowInfo
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ class LogicSystem(private val context: DataFlowInferenceContext) {
|
|||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
fun approveFactsInsideFlow(proof: Condition, flow: Flow): Flow {
|
fun approveFactsInsideFlow(variable: DataFlowVariable, condition: Condition, flow: Flow): Flow {
|
||||||
val notApprovedFacts: Set<UnapprovedFirDataFlowInfo> = flow.notApprovedFacts[proof.variable]
|
val notApprovedFacts: Set<UnapprovedFirDataFlowInfo> = flow.notApprovedFacts[variable]
|
||||||
if (notApprovedFacts.isEmpty()) {
|
if (notApprovedFacts.isEmpty()) {
|
||||||
return flow
|
return flow
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ class LogicSystem(private val context: DataFlowInferenceContext) {
|
|||||||
val flow = flow.copyForBuilding()
|
val flow = flow.copyForBuilding()
|
||||||
val newFacts = HashMultimap.create<DataFlowVariable, FirDataFlowInfo>()
|
val newFacts = HashMultimap.create<DataFlowVariable, FirDataFlowInfo>()
|
||||||
notApprovedFacts.forEach {
|
notApprovedFacts.forEach {
|
||||||
if (it.condition == proof.rhs) {
|
if (it.condition == condition) {
|
||||||
newFacts.put(it.variable, it.info)
|
newFacts.put(it.variable, it.info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,14 +93,14 @@ class LogicSystem(private val context: DataFlowInferenceContext) {
|
|||||||
return flow
|
return flow
|
||||||
}
|
}
|
||||||
|
|
||||||
fun approveFact(proof: Condition, flow: Flow): MutableMap<DataFlowVariable, FirDataFlowInfo> {
|
fun approveFact(variable: DataFlowVariable, condition: Condition, flow: Flow): MutableMap<DataFlowVariable, FirDataFlowInfo> {
|
||||||
val notApprovedFacts: Set<UnapprovedFirDataFlowInfo> = flow.notApprovedFacts[proof.variable]
|
val notApprovedFacts: Set<UnapprovedFirDataFlowInfo> = flow.notApprovedFacts[variable]
|
||||||
if (notApprovedFacts.isEmpty()) {
|
if (notApprovedFacts.isEmpty()) {
|
||||||
return mutableMapOf()
|
return mutableMapOf()
|
||||||
}
|
}
|
||||||
val newFacts = HashMultimap.create<DataFlowVariable, FirDataFlowInfo>()
|
val newFacts = HashMultimap.create<DataFlowVariable, FirDataFlowInfo>()
|
||||||
notApprovedFacts.forEach {
|
notApprovedFacts.forEach {
|
||||||
if (it.condition == proof.rhs) {
|
if (it.condition == condition) {
|
||||||
newFacts.put(it.variable, it.info)
|
newFacts.put(it.variable, it.info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.Condition
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowVariable
|
||||||
|
|
||||||
class ControlFlowGraph(val name: String) {
|
class ControlFlowGraph(val name: String) {
|
||||||
val nodes = mutableListOf<CFGNode<*>>()
|
val nodes = mutableListOf<CFGNode<*>>()
|
||||||
@@ -67,8 +67,7 @@ class WhenEnterNode(owner: ControlFlowGraph, override val fir: FirWhenExpression
|
|||||||
class WhenExitNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int) : CFGNode<FirWhenExpression>(owner, level), ExitNode
|
class WhenExitNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int) : CFGNode<FirWhenExpression>(owner, level), ExitNode
|
||||||
class WhenBranchConditionEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level), EnterNode
|
class WhenBranchConditionEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level), EnterNode
|
||||||
class WhenBranchConditionExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level), ExitNode {
|
class WhenBranchConditionExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level), ExitNode {
|
||||||
lateinit var trueCondition: Condition
|
lateinit var variable: DataFlowVariable
|
||||||
lateinit var falseCondition: Condition
|
|
||||||
}
|
}
|
||||||
class WhenBranchResultExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level)
|
class WhenBranchResultExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int) : CFGNode<FirWhenBranch>(owner, level)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user