diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 3092cabb3fb..06fe7fdac51 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -344,30 +344,29 @@ abstract class FirDataFlowAnalyzer( graphBuilder.exitComparisonExpression(comparisonExpression).mergeIncomingFlow() } - fun exitOperatorCall(operatorCall: FirOperatorCall) { - val node = graphBuilder.exitOperatorCall(operatorCall).mergeIncomingFlow() - when (val operation = operatorCall.operation) { - FirOperation.EQ, FirOperation.NOT_EQ, FirOperation.IDENTITY, FirOperation.NOT_IDENTITY -> { - val leftOperand = operatorCall.arguments[0] - val rightOperand = operatorCall.arguments[1] + fun exitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall) { + val node = graphBuilder.exitEqualityOperatorCall(equalityOperatorCall).mergeIncomingFlow() + val operation = equalityOperatorCall.operation + val leftOperand = equalityOperatorCall.arguments[0] + val rightOperand = equalityOperatorCall.arguments[1] - val leftConst = leftOperand as? FirConstExpression<*> - val rightConst = rightOperand as? FirConstExpression<*> + val leftConst = leftOperand as? FirConstExpression<*> + val rightConst = rightOperand as? FirConstExpression<*> - when { - leftConst != null && rightConst != null -> return - leftConst?.kind == FirConstKind.Null -> processEqNull(node, rightOperand, operation) - rightConst?.kind == FirConstKind.Null -> processEqNull(node, leftOperand, operation) - leftConst != null -> processEqWithConst(node, rightOperand, leftConst, operation) - rightConst != null -> processEqWithConst(node, leftOperand, rightConst, operation) - else -> processEq(node, leftOperand, rightOperand, operation) - } - } + when { + leftConst != null && rightConst != null -> return + leftConst?.kind == FirConstKind.Null -> processEqNull(node, rightOperand, operation) + rightConst?.kind == FirConstKind.Null -> processEqNull(node, leftOperand, operation) + leftConst != null -> processEqWithConst(node, rightOperand, leftConst, operation) + rightConst != null -> processEqWithConst(node, leftOperand, rightConst, operation) + else -> processEq(node, leftOperand, rightOperand, operation) } } // const != null - private fun processEqWithConst(node: OperatorCallNode, operand: FirExpression, const: FirConstExpression<*>, operation: FirOperation) { + private fun processEqWithConst( + node: EqualityOperatorCallNode, operand: FirExpression, const: FirConstExpression<*>, operation: FirOperation + ) { val isEq = operation.isEq() val expressionVariable = variableStorage.createSyntheticVariable(node.fir) val flow = node.flow @@ -402,7 +401,9 @@ abstract class FirDataFlowAnalyzer( } } - private fun processEq(node: OperatorCallNode, leftOperand: FirExpression, rightOperand: FirExpression, operation: FirOperation) { + private fun processEq( + node: EqualityOperatorCallNode, leftOperand: FirExpression, rightOperand: FirExpression, operation: FirOperation + ) { val leftIsNullable = leftOperand.coneType.isMarkedNullable val rightIsNullable = rightOperand.coneType.isMarkedNullable // left == right && right not null -> left != null @@ -417,7 +418,7 @@ abstract class FirDataFlowAnalyzer( } } - private fun processEqNull(node: OperatorCallNode, operand: FirExpression, operation: FirOperation) { + private fun processEqNull(node: EqualityOperatorCallNode, operand: FirExpression, operation: FirOperation) { val flow = node.flow val expressionVariable = variableStorage.createSyntheticVariable(node.fir) val operandVariable = variableStorage.getOrCreateVariable(node.previousFlow, operand) @@ -448,7 +449,9 @@ abstract class FirDataFlowAnalyzer( node.flow = flow } - private fun processIdentity(node: OperatorCallNode, leftOperand: FirExpression, rightOperand: FirExpression, operation: FirOperation) { + private fun processIdentity( + node: EqualityOperatorCallNode, leftOperand: FirExpression, rightOperand: FirExpression, operation: FirOperation + ) { val flow = node.flow val expressionVariable = variableStorage.getOrCreateVariable(node.previousFlow, node.fir) val leftOperandVariable = variableStorage.getOrCreateVariable(node.previousFlow, leftOperand) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt index 5f9913f292c..475921af110 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt @@ -456,18 +456,18 @@ class TypeOperatorCallNode(owner: ControlFlowGraph, override val fir: FirTypeOpe } } -class OperatorCallNode(owner: ControlFlowGraph, override val fir: FirOperatorCall, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id) { - override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { - return visitor.visitOperatorCallNode(this, data) - } -} - class ComparisonExpressionNode(owner: ControlFlowGraph, override val fir: FirComparisonExpression, level: Int, id: Int) : CFGNode(owner, level, id) { override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { return visitor.visitComparisonExpressionNode(this, data) } } +class EqualityOperatorCallNode(owner: ControlFlowGraph, override val fir: FirEqualityOperatorCall, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitEqualityOperatorCallNode(this, data) + } +} + // ----------------------------------- Jump ----------------------------------- class JumpNode(owner: ControlFlowGraph, override val fir: FirJump<*>, level: Int, id: Int) : CFGNode>(owner, level, id) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt index 2ad5c533238..3b54e8b5ae0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt @@ -40,9 +40,9 @@ fun CFGNode<*>.render(): String = is QualifiedAccessNode -> "Access variable ${fir.calleeReference.render(CfgRenderMode)}" is ResolvedQualifierNode -> "Access qualifier ${fir.classId}" - is OperatorCallNode -> "Operator ${fir.operation.operator}" is ComparisonExpressionNode -> "Comparison ${fir.operation.operator}" is TypeOperatorCallNode -> "Type operator: \"${fir.render(CfgRenderMode)}\"" + is EqualityOperatorCallNode -> "Equality operator ${fir.operation.operator}" is JumpNode -> "Jump: ${fir.render()}" is StubNode -> "Stub" is CheckNotNullCallNode -> "Check not null: ${fir.render(CfgRenderMode)}" diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 63493bcd8d0..85ee117125a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -495,14 +495,14 @@ class ControlFlowGraphBuilder { return createTypeOperatorCallNode(typeOperatorCall).also { addNewSimpleNode(it) } } - fun exitOperatorCall(operatorCall: FirOperatorCall): OperatorCallNode { - return createOperatorCallNode(operatorCall).also { addNewSimpleNode(it) } - } - fun exitComparisonExpression(comparisonExpression: FirComparisonExpression): ComparisonExpressionNode { return createComparisonExpressionNode(comparisonExpression).also { addNewSimpleNode(it) } } + fun exitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall): EqualityOperatorCallNode { + return createEqualityOperatorCallNode(equalityOperatorCall).also { addNewSimpleNode(it) } + } + // ----------------------------------- Jump ----------------------------------- fun exitJump(jump: FirJump<*>): JumpNode { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt index 8c3a96455fe..5990f7f35eb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt @@ -27,8 +27,8 @@ fun ControlFlowGraphBuilder.createInitBlockExitNode(fir: FirAnonymousInitializer fun ControlFlowGraphBuilder.createTypeOperatorCallNode(fir: FirTypeOperatorCall): TypeOperatorCallNode = TypeOperatorCallNode(currentGraph, fir, levelCounter, createId()) -fun ControlFlowGraphBuilder.createOperatorCallNode(fir: FirOperatorCall): OperatorCallNode = - OperatorCallNode(currentGraph, fir, levelCounter, createId()) +fun ControlFlowGraphBuilder.createEqualityOperatorCallNode(fir: FirEqualityOperatorCall): EqualityOperatorCallNode = + EqualityOperatorCallNode(currentGraph, fir, levelCounter, createId()) fun ControlFlowGraphBuilder.createWhenBranchConditionExitNode(fir: FirWhenBranch): WhenBranchConditionExitNode = WhenBranchConditionExitNode(currentGraph, fir, levelCounter, createId()) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt index c0fe5172480..63594c75cb8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt @@ -229,11 +229,11 @@ abstract class ControlFlowGraphVisitor { return visitNode(node, data) } - open fun visitOperatorCallNode(node: OperatorCallNode, data: D): R { + open fun visitComparisonExpressionNode(node: ComparisonExpressionNode, data: D): R { return visitNode(node, data) } - open fun visitComparisonExpressionNode(node: ComparisonExpressionNode, data: D): R { + open fun visitEqualityOperatorCallNode(node: EqualityOperatorCallNode, data: D): R { return visitNode(node, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt index 419488a6abf..44e066363e4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt @@ -207,11 +207,11 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor