From b88cb3f84950c54cd027cc84336bcc79a79f44dc Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 19 Mar 2020 16:26:40 +0300 Subject: [PATCH] [FIR] Add visitors for control flow graph --- .../fir/resolve/dfa/cfg/ControlFlowGraph.kt | 380 ++++++++++-- .../dfa/cfg/ControlFlowGraphVisitor.kt | 293 +++++++++ .../dfa/cfg/ControlFlowGraphVisitorVoid.kt | 582 ++++++++++++++++++ 3 files changed, 1194 insertions(+), 61 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt index 0d113d71918..48feb694946 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt @@ -79,7 +79,13 @@ sealed class CFGNode(val owner: ControlFlowGraph, val level: internal fun updateDeadStatus() { isDead = incomingEdges.size == previousNodes.size && incomingEdges.values.all { it == EdgeKind.Dead } } - + + abstract fun accept(visitor: ControlFlowGraphVisitor, data: D): R + + fun accept(visitor: ControlFlowGraphVisitorVoid) { + accept(visitor, null) + } + final override fun equals(other: Any?): Boolean { if (other !is CFGNode<*>) return false return this.id == other.id @@ -98,69 +104,209 @@ interface ExitNodeMarker // ----------------------------------- Named function ----------------------------------- -class FunctionEnterNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), EnterNodeMarker -class FunctionExitNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), ExitNodeMarker +class FunctionEnterNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFunctionEnterNode(this, data) + } +} +class FunctionExitNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFunctionExitNode(this, data) + } +} // ----------------------------------- Anonymous function ----------------------------------- -class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) -class PostponedLambdaExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) -class UnionFunctionCallArgumentsNode(owner: ControlFlowGraph, override val fir: FirElement, level: Int, id: Int) : CFGNode(owner, level, id) +class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitPostponedLambdaEnterNode(this, data) + } +} +class PostponedLambdaExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitPostponedLambdaExitNode(this, data) + } +} +class UnionFunctionCallArgumentsNode(owner: ControlFlowGraph, override val fir: FirElement, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitUnionFunctionCallArgumentsNode(this, data) + } +} // ----------------------------------- Anonymous object ----------------------------------- -class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNode(owner, level, id) +class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitAnonymousObjectExitNode(this, data) + } +} // ----------------------------------- Property ----------------------------------- -class PropertyInitializerEnterNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class PropertyInitializerExitNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class PropertyInitializerEnterNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitPropertyInitializerEnterNode(this, data) + } +} +class PropertyInitializerExitNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitPropertyInitializerExitNode(this, data) + } +} // ----------------------------------- Init ----------------------------------- -class InitBlockEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousInitializer, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class InitBlockExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousInitializer, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class InitBlockEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousInitializer, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitInitBlockEnterNode(this, data) + } +} +class InitBlockExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousInitializer, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitInitBlockExitNode(this, data) + } +} // ----------------------------------- Block ----------------------------------- -class BlockEnterNode(owner: ControlFlowGraph, override val fir: FirBlock, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class BlockExitNode(owner: ControlFlowGraph, override val fir: FirBlock, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class BlockEnterNode(owner: ControlFlowGraph, override val fir: FirBlock, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBlockEnterNode(this, data) + } +} +class BlockExitNode(owner: ControlFlowGraph, override val fir: FirBlock, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBlockExitNode(this, data) + } +} // ----------------------------------- When ----------------------------------- -class WhenEnterNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class WhenExitNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class WhenBranchConditionEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class WhenBranchConditionExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class WhenBranchResultEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id) -class WhenBranchResultExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id) +class WhenEnterNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenEnterNode(this, data) + } +} +class WhenExitNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenExitNode(this, data) + } +} +class WhenBranchConditionEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenBranchConditionEnterNode(this, data) + } +} +class WhenBranchConditionExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenBranchConditionExitNode(this, data) + } +} +class WhenBranchResultEnterNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenBranchResultEnterNode(this, data) + } +} +class WhenBranchResultExitNode(owner: ControlFlowGraph, override val fir: FirWhenBranch, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenBranchResultExitNode(this, data) + } +} class WhenSyntheticElseBranchNode(owner: ControlFlowGraph, override val fir: FirWhenExpression, level: Int, id: Int) : CFGNode(owner, level, id) { init { assert(!fir.isExhaustive) } + + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitWhenSyntheticElseBranchNode(this, data) + } } // ----------------------------------- Loop ----------------------------------- -class LoopEnterNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class LoopBlockEnterNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class LoopBlockExitNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class LoopConditionEnterNode(owner: ControlFlowGraph, override val fir: FirExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class LoopConditionExitNode(owner: ControlFlowGraph, override val fir: FirExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class LoopExitNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class LoopEnterNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopEnterNode(this, data) + } +} +class LoopBlockEnterNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopBlockEnterNode(this, data) + } +} +class LoopBlockExitNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopBlockExitNode(this, data) + } +} +class LoopConditionEnterNode(owner: ControlFlowGraph, override val fir: FirExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopConditionEnterNode(this, data) + } +} +class LoopConditionExitNode(owner: ControlFlowGraph, override val fir: FirExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopConditionExitNode(this, data) + } +} +class LoopExitNode(owner: ControlFlowGraph, override val fir: FirLoop, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitLoopExitNode(this, data) + } +} // ----------------------------------- Try-catch-finally ----------------------------------- -class TryExpressionEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class TryMainBlockEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class TryMainBlockExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class CatchClauseEnterNode(owner: ControlFlowGraph, override val fir: FirCatch, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class CatchClauseExitNode(owner: ControlFlowGraph, override val fir: FirCatch, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class FinallyBlockEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class FinallyBlockExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class FinallyProxyEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class FinallyProxyExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker -class TryExpressionExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class TryExpressionEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitTryExpressionEnterNode(this, data) + } +} +class TryMainBlockEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitTryMainBlockEnterNode(this, data) + } +} +class TryMainBlockExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitTryMainBlockExitNode(this, data) + } +} +class CatchClauseEnterNode(owner: ControlFlowGraph, override val fir: FirCatch, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitCatchClauseEnterNode(this, data) + } +} +class CatchClauseExitNode(owner: ControlFlowGraph, override val fir: FirCatch, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitCatchClauseExitNode(this, data) + } +} +class FinallyBlockEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFinallyBlockEnterNode(this, data) + } +} +class FinallyBlockExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFinallyBlockExitNode(this, data) + } +} +class FinallyProxyEnterNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFinallyProxyEnterNode(this, data) + } +} +class FinallyProxyExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFinallyProxyExitNode(this, data) + } +} +class TryExpressionExitNode(owner: ControlFlowGraph, override val fir: FirTryExpression, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitTryExpressionExitNode(this, data) + } +} // ----------------------------------- Boolean operators ----------------------------------- @@ -169,30 +315,86 @@ abstract class AbstractBinaryExitNode(owner: ControlFlowGraph, l val rightOperandNode: CFGNode<*> get() = previousNodes[1] } -class BinaryAndEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class BinaryAndExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) -class BinaryAndEnterRightOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) -class BinaryAndExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id), ExitNodeMarker +class BinaryAndEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryAndEnterNode(this, data) + } +} +class BinaryAndExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryAndExitLeftOperandNode(this, data) + } +} +class BinaryAndEnterRightOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryAndEnterRightOperandNode(this, data) + } +} +class BinaryAndExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryAndExitNode(this, data) + } +} -class BinaryOrEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class BinaryOrExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) -class BinaryOrEnterRightOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) -class BinaryOrExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id), ExitNodeMarker +class BinaryOrEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryOrEnterNode(this, data) + } +} +class BinaryOrExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryOrExitLeftOperandNode(this, data) + } +} +class BinaryOrEnterRightOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryOrEnterRightOperandNode(this, data) + } +} +class BinaryOrExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitBinaryOrExitNode(this, data) + } +} // ----------------------------------- Operator call ----------------------------------- -class TypeOperatorCallNode(owner: ControlFlowGraph, override val fir: FirTypeOperatorCall, level: Int, id: Int) : CFGNode(owner, level, id) -class OperatorCallNode(owner: ControlFlowGraph, override val fir: FirOperatorCall, level: Int, id: Int) : AbstractBinaryExitNode(owner, level, id) -class ComparisonExpressionNode(owner: ControlFlowGraph, override val fir: FirComparisonExpression, level: Int, id: Int) : CFGNode(owner, level, id) +class TypeOperatorCallNode(owner: ControlFlowGraph, override val fir: FirTypeOperatorCall, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitTypeOperatorCallNode(this, data) + } +} +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) + } +} // ----------------------------------- Jump ----------------------------------- -class JumpNode(owner: ControlFlowGraph, override val fir: FirJump<*>, level: Int, id: Int) : CFGNode>(owner, level, id) -class ConstExpressionNode(owner: ControlFlowGraph, override val fir: FirConstExpression<*>, level: Int, id: Int) : CFGNode>(owner, level, id) +class JumpNode(owner: ControlFlowGraph, override val fir: FirJump<*>, level: Int, id: Int) : CFGNode>(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitJumpNode(this, data) + } +} +class ConstExpressionNode(owner: ControlFlowGraph, override val fir: FirConstExpression<*>, level: Int, id: Int) : CFGNode>(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitConstExpressionNode(this, data) + } +} // ----------------------------------- Check not null call ----------------------------------- -class CheckNotNullCallNode(owner: ControlFlowGraph, override val fir: FirCheckNotNullCall, level: Int, id: Int) : CFGNode(owner, level, id) +class CheckNotNullCallNode(owner: ControlFlowGraph, override val fir: FirCheckNotNullCall, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitCheckNotNullCallNode(this, data) + } +} // ----------------------------------- Resolvable call ----------------------------------- @@ -200,32 +402,52 @@ class QualifiedAccessNode( owner: ControlFlowGraph, override val fir: FirQualifiedAccessExpression, level: Int, id: Int -) : CFGNode(owner, level, id) +) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitQualifiedAccessNode(this, data) + } +} class ResolvedQualifierNode( owner: ControlFlowGraph, override val fir: FirResolvedQualifier, level: Int, id: Int -) : CFGNode(owner, level, id) +) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitResolvedQualifierNode(this, data) + } +} class FunctionCallNode( owner: ControlFlowGraph, override val fir: FirFunctionCall, level: Int, id: Int -) : CFGNode(owner, level, id) +) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFunctionCallNode(this, data) + } +} class DelegatedConstructorCallNode( owner: ControlFlowGraph, override val fir: FirDelegatedConstructorCall, level: Int, id: Int -) : CFGNode(owner, level, id) +) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitDelegatedConstructorCallNode(this, data) + } +} class ThrowExceptionNode( owner: ControlFlowGraph, override val fir: FirThrowExpression, level: Int, id: Int -) : CFGNode(owner, level, id) +) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitThrowExceptionNode(this, data) + } +} class StubNode(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode(owner, level, id) { init { @@ -233,24 +455,60 @@ class StubNode(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode( } override val fir: FirStub get() = FirStub + + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitStubNode(this, data) + } } -class VariableDeclarationNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id) -class VariableAssignmentNode(owner: ControlFlowGraph, override val fir: FirVariableAssignment, level: Int, id: Int) : CFGNode(owner, level, id) +class VariableDeclarationNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitVariableDeclarationNode(this, data) + } +} +class VariableAssignmentNode(owner: ControlFlowGraph, override val fir: FirVariableAssignment, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitVariableAssignmentNode(this, data) + } +} -class EnterContractNode(owner: ControlFlowGraph, override val fir: FirFunctionCall, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class ExitContractNode(owner: ControlFlowGraph, override val fir: FirFunctionCall, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class EnterContractNode(owner: ControlFlowGraph, override val fir: FirFunctionCall, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitEnterContractNode(this, data) + } +} +class ExitContractNode(owner: ControlFlowGraph, override val fir: FirFunctionCall, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitExitContractNode(this, data) + } +} -class EnterSafeCallNode(owner: ControlFlowGraph, override val fir: FirQualifiedAccess, level: Int, id: Int) : CFGNode(owner, level, id) +class EnterSafeCallNode(owner: ControlFlowGraph, override val fir: FirQualifiedAccess, level: Int, id: Int) : CFGNode(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitEnterSafeCallNode(this, data) + } +} class ExitSafeCallNode(owner: ControlFlowGraph, override val fir: FirQualifiedAccess, level: Int, id: Int) : CFGNode(owner, level, id) { val lastPreviousNode: CFGNode<*> get() = previousNodes.last() val secondPreviousNode: CFGNode<*>? get() = previousNodes.getOrNull(1) + + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitExitSafeCallNode(this, data) + } } // ----------------------------------- Other ----------------------------------- -class AnnotationEnterNode(owner: ControlFlowGraph, override val fir: FirAnnotationCall, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker -class AnnotationExitNode(owner: ControlFlowGraph, override val fir: FirAnnotationCall, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker +class AnnotationEnterNode(owner: ControlFlowGraph, override val fir: FirAnnotationCall, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitAnnotationEnterNode(this, data) + } +} +class AnnotationExitNode(owner: ControlFlowGraph, override val fir: FirAnnotationCall, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitAnnotationExitNode(this, data) + } +} // ----------------------------------- Stub ----------------------------------- 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 new file mode 100644 index 00000000000..d228c81418d --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt @@ -0,0 +1,293 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.dfa.cfg + +abstract class ControlFlowGraphVisitor { + abstract fun visitNode(node: CFGNode<*>, data: D): R + + // ----------------------------------- Simple function ----------------------------------- + + open fun visitFunctionEnterNode(node: FunctionEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFunctionExitNode(node: FunctionExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Anonymous function ----------------------------------- + + open fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitPostponedLambdaExitNode(node: PostponedLambdaExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitUnionFunctionCallArgumentsNode(node: UnionFunctionCallArgumentsNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Anonymous object ----------------------------------- + + open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Property ----------------------------------- + + open fun visitPropertyInitializerEnterNode(node: PropertyInitializerEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitPropertyInitializerExitNode(node: PropertyInitializerExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Init ----------------------------------- + + open fun visitInitBlockEnterNode(node: InitBlockEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitInitBlockExitNode(node: InitBlockExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Block ----------------------------------- + + open fun visitBlockEnterNode(node: BlockEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBlockExitNode(node: BlockExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- When ----------------------------------- + + open fun visitWhenEnterNode(node: WhenEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenExitNode(node: WhenExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenBranchConditionEnterNode(node: WhenBranchConditionEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenBranchConditionExitNode(node: WhenBranchConditionExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenBranchResultEnterNode(node: WhenBranchResultEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenBranchResultExitNode(node: WhenBranchResultExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitWhenSyntheticElseBranchNode(node: WhenSyntheticElseBranchNode, data: D): R { + return visitNode(node, data) + } + + + // ----------------------------------- Loop ----------------------------------- + + open fun visitLoopEnterNode(node: LoopEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitLoopBlockEnterNode(node: LoopBlockEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitLoopBlockExitNode(node: LoopBlockExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitLoopConditionEnterNode(node: LoopConditionEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitLoopConditionExitNode(node: LoopConditionExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitLoopExitNode(node: LoopExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Try-catch-finally ----------------------------------- + + open fun visitTryExpressionEnterNode(node: TryExpressionEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitTryMainBlockEnterNode(node: TryMainBlockEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitTryMainBlockExitNode(node: TryMainBlockExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitCatchClauseEnterNode(node: CatchClauseEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitCatchClauseExitNode(node: CatchClauseExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFinallyBlockEnterNode(node: FinallyBlockEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFinallyBlockExitNode(node: FinallyBlockExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFinallyProxyEnterNode(node: FinallyProxyEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFinallyProxyExitNode(node: FinallyProxyExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitTryExpressionExitNode(node: TryExpressionExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Boolean operators ----------------------------------- + + open fun visitBinaryAndEnterNode(node: BinaryAndEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryAndExitLeftOperandNode(node: BinaryAndExitLeftOperandNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryAndEnterRightOperandNode(node: BinaryAndEnterRightOperandNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryAndExitNode(node: BinaryAndExitNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryOrEnterNode(node: BinaryOrEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryOrExitLeftOperandNode(node: BinaryOrExitLeftOperandNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryOrEnterRightOperandNode(node: BinaryOrEnterRightOperandNode, data: D): R { + return visitNode(node, data) + } + + open fun visitBinaryOrExitNode(node: BinaryOrExitNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Operator call ----------------------------------- + + open fun visitTypeOperatorCallNode(node: TypeOperatorCallNode, data: D): R { + return visitNode(node, data) + } + + open fun visitOperatorCallNode(node: OperatorCallNode, data: D): R { + return visitNode(node, data) + } + + open fun visitComparisonExpressionNode(node: ComparisonExpressionNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Jump ----------------------------------- + + open fun visitJumpNode(node: JumpNode, data: D): R { + return visitNode(node, data) + } + + open fun visitConstExpressionNode(node: ConstExpressionNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Check not null call ----------------------------------- + + open fun visitCheckNotNullCallNode(node: CheckNotNullCallNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Resolvable call ----------------------------------- + + open fun visitQualifiedAccessNode(node: QualifiedAccessNode, data: D): R { + return visitNode(node, data) + } + + open fun visitResolvedQualifierNode(node: ResolvedQualifierNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFunctionCallNode(node: FunctionCallNode, data: D): R { + return visitNode(node, data) + } + + open fun visitDelegatedConstructorCallNode(node: DelegatedConstructorCallNode, data: D): R { + return visitNode(node, data) + } + + open fun visitThrowExceptionNode(node: ThrowExceptionNode, data: D): R { + return visitNode(node, data) + } + + open fun visitStubNode(node: StubNode, data: D): R { + return visitNode(node, data) + } + + open fun visitVariableDeclarationNode(node: VariableDeclarationNode, data: D): R { + return visitNode(node, data) + } + + open fun visitVariableAssignmentNode(node: VariableAssignmentNode, data: D): R { + return visitNode(node, data) + } + + open fun visitEnterContractNode(node: EnterContractNode, data: D): R { + return visitNode(node, data) + } + + open fun visitExitContractNode(node: ExitContractNode, data: D): R { + return visitNode(node, data) + } + + open fun visitEnterSafeCallNode(node: EnterSafeCallNode, data: D): R { + return visitNode(node, data) + } + + open fun visitExitSafeCallNode(node: ExitSafeCallNode, data: D): R { + return visitNode(node, data) + } + + // ----------------------------------- Other ----------------------------------- + + open fun visitAnnotationEnterNode(node: AnnotationEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitAnnotationExitNode(node: AnnotationExitNode, 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 new file mode 100644 index 00000000000..419488a6abf --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt @@ -0,0 +1,582 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.dfa.cfg + +abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor() { + abstract fun visitNode(node: CFGNode<*>) + + // ----------------------------------- Simple function ----------------------------------- + + open fun visitFunctionEnterNode(node: FunctionEnterNode) { + visitNode(node) + } + + open fun visitFunctionExitNode(node: FunctionExitNode) { + visitNode(node) + } + + // ----------------------------------- Anonymous function ----------------------------------- + + open fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode) { + visitNode(node) + } + + open fun visitPostponedLambdaExitNode(node: PostponedLambdaExitNode) { + visitNode(node) + } + + open fun visitUnionFunctionCallArgumentsNode(node: UnionFunctionCallArgumentsNode) { + visitNode(node) + } + + // ----------------------------------- Anonymous object ----------------------------------- + + open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode) { + visitNode(node) + } + + // ----------------------------------- Property ----------------------------------- + + open fun visitPropertyInitializerEnterNode(node: PropertyInitializerEnterNode) { + visitNode(node) + } + + open fun visitPropertyInitializerExitNode(node: PropertyInitializerExitNode) { + visitNode(node) + } + + // ----------------------------------- Init ----------------------------------- + + open fun visitInitBlockEnterNode(node: InitBlockEnterNode) { + visitNode(node) + } + + open fun visitInitBlockExitNode(node: InitBlockExitNode) { + visitNode(node) + } + + // ----------------------------------- Block ----------------------------------- + + open fun visitBlockEnterNode(node: BlockEnterNode) { + visitNode(node) + } + + open fun visitBlockExitNode(node: BlockExitNode) { + visitNode(node) + } + + // ----------------------------------- When ----------------------------------- + + open fun visitWhenEnterNode(node: WhenEnterNode) { + visitNode(node) + } + + open fun visitWhenExitNode(node: WhenExitNode) { + visitNode(node) + } + + open fun visitWhenBranchConditionEnterNode(node: WhenBranchConditionEnterNode) { + visitNode(node) + } + + open fun visitWhenBranchConditionExitNode(node: WhenBranchConditionExitNode) { + visitNode(node) + } + + open fun visitWhenBranchResultEnterNode(node: WhenBranchResultEnterNode) { + visitNode(node) + } + + open fun visitWhenBranchResultExitNode(node: WhenBranchResultExitNode) { + visitNode(node) + } + + open fun visitWhenSyntheticElseBranchNode(node: WhenSyntheticElseBranchNode) { + visitNode(node) + } + + + // ----------------------------------- Loop ----------------------------------- + + open fun visitLoopEnterNode(node: LoopEnterNode) { + visitNode(node) + } + + open fun visitLoopBlockEnterNode(node: LoopBlockEnterNode) { + visitNode(node) + } + + open fun visitLoopBlockExitNode(node: LoopBlockExitNode) { + visitNode(node) + } + + open fun visitLoopConditionEnterNode(node: LoopConditionEnterNode) { + visitNode(node) + } + + open fun visitLoopConditionExitNode(node: LoopConditionExitNode) { + visitNode(node) + } + + open fun visitLoopExitNode(node: LoopExitNode) { + visitNode(node) + } + + // ----------------------------------- Try-catch-finally ----------------------------------- + + open fun visitTryExpressionEnterNode(node: TryExpressionEnterNode) { + visitNode(node) + } + + open fun visitTryMainBlockEnterNode(node: TryMainBlockEnterNode) { + visitNode(node) + } + + open fun visitTryMainBlockExitNode(node: TryMainBlockExitNode) { + visitNode(node) + } + + open fun visitCatchClauseEnterNode(node: CatchClauseEnterNode) { + visitNode(node) + } + + open fun visitCatchClauseExitNode(node: CatchClauseExitNode) { + visitNode(node) + } + + open fun visitFinallyBlockEnterNode(node: FinallyBlockEnterNode) { + visitNode(node) + } + + open fun visitFinallyBlockExitNode(node: FinallyBlockExitNode) { + visitNode(node) + } + + open fun visitFinallyProxyEnterNode(node: FinallyProxyEnterNode) { + visitNode(node) + } + + open fun visitFinallyProxyExitNode(node: FinallyProxyExitNode) { + visitNode(node) + } + + open fun visitTryExpressionExitNode(node: TryExpressionExitNode) { + visitNode(node) + } + + // ----------------------------------- Boolean operators ----------------------------------- + + open fun visitBinaryAndEnterNode(node: BinaryAndEnterNode) { + visitNode(node) + } + + open fun visitBinaryAndExitLeftOperandNode(node: BinaryAndExitLeftOperandNode) { + visitNode(node) + } + + open fun visitBinaryAndEnterRightOperandNode(node: BinaryAndEnterRightOperandNode) { + visitNode(node) + } + + open fun visitBinaryAndExitNode(node: BinaryAndExitNode) { + visitNode(node) + } + + open fun visitBinaryOrEnterNode(node: BinaryOrEnterNode) { + visitNode(node) + } + + open fun visitBinaryOrExitLeftOperandNode(node: BinaryOrExitLeftOperandNode) { + visitNode(node) + } + + open fun visitBinaryOrEnterRightOperandNode(node: BinaryOrEnterRightOperandNode) { + visitNode(node) + } + + open fun visitBinaryOrExitNode(node: BinaryOrExitNode) { + visitNode(node) + } + + // ----------------------------------- Operator call ----------------------------------- + + open fun visitTypeOperatorCallNode(node: TypeOperatorCallNode) { + visitNode(node) + } + + open fun visitOperatorCallNode(node: OperatorCallNode) { + visitNode(node) + } + + open fun visitComparisonExpressionNode(node: ComparisonExpressionNode) { + visitNode(node) + } + + // ----------------------------------- Jump ----------------------------------- + + open fun visitJumpNode(node: JumpNode) { + visitNode(node) + } + + open fun visitConstExpressionNode(node: ConstExpressionNode) { + visitNode(node) + } + + // ----------------------------------- Check not null call ----------------------------------- + + open fun visitCheckNotNullCallNode(node: CheckNotNullCallNode) { + visitNode(node) + } + + // ----------------------------------- Resolvable call ----------------------------------- + + open fun visitQualifiedAccessNode(node: QualifiedAccessNode) { + visitNode(node) + } + + open fun visitResolvedQualifierNode(node: ResolvedQualifierNode) { + visitNode(node) + } + + open fun visitFunctionCallNode(node: FunctionCallNode) { + visitNode(node) + } + + open fun visitDelegatedConstructorCallNode(node: DelegatedConstructorCallNode) { + visitNode(node) + } + + open fun visitThrowExceptionNode(node: ThrowExceptionNode) { + visitNode(node) + } + + open fun visitStubNode(node: StubNode) { + visitNode(node) + } + + open fun visitVariableDeclarationNode(node: VariableDeclarationNode) { + visitNode(node) + } + + open fun visitVariableAssignmentNode(node: VariableAssignmentNode) { + visitNode(node) + } + + open fun visitEnterContractNode(node: EnterContractNode) { + visitNode(node) + } + + open fun visitExitContractNode(node: ExitContractNode) { + visitNode(node) + } + + open fun visitEnterSafeCallNode(node: EnterSafeCallNode) { + visitNode(node) + } + + open fun visitExitSafeCallNode(node: ExitSafeCallNode) { + visitNode(node) + } + + // ----------------------------------- Other ----------------------------------- + + open fun visitAnnotationEnterNode(node: AnnotationEnterNode) { + visitNode(node) + } + + open fun visitAnnotationExitNode(node: AnnotationExitNode) { + visitNode(node) + } + + // --------------------------------------------------------------------------------------------------------------------- + + final override fun visitNode(node: CFGNode<*>, data: Nothing?) { + visitNode(node) + } + + // ----------------------------------- Simple function ----------------------------------- + + final override fun visitFunctionEnterNode(node: FunctionEnterNode, data: Nothing?) { + visitFunctionEnterNode(node) + } + + final override fun visitFunctionExitNode(node: FunctionExitNode, data: Nothing?) { + visitFunctionExitNode(node) + } + + // ----------------------------------- Anonymous function ----------------------------------- + + final override fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode, data: Nothing?) { + visitPostponedLambdaEnterNode(node) + } + + final override fun visitPostponedLambdaExitNode(node: PostponedLambdaExitNode, data: Nothing?) { + visitPostponedLambdaExitNode(node) + } + + final override fun visitUnionFunctionCallArgumentsNode(node: UnionFunctionCallArgumentsNode, data: Nothing?) { + visitUnionFunctionCallArgumentsNode(node) + } + + // ----------------------------------- Anonymous object ----------------------------------- + + final override fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: Nothing?) { + visitAnonymousObjectExitNode(node) + } + + // ----------------------------------- Property ----------------------------------- + + final override fun visitPropertyInitializerEnterNode(node: PropertyInitializerEnterNode, data: Nothing?) { + visitPropertyInitializerEnterNode(node) + } + + final override fun visitPropertyInitializerExitNode(node: PropertyInitializerExitNode, data: Nothing?) { + visitPropertyInitializerExitNode(node) + } + + // ----------------------------------- Init ----------------------------------- + + final override fun visitInitBlockEnterNode(node: InitBlockEnterNode, data: Nothing?) { + visitInitBlockEnterNode(node) + } + + final override fun visitInitBlockExitNode(node: InitBlockExitNode, data: Nothing?) { + visitInitBlockExitNode(node) + } + + // ----------------------------------- Block ----------------------------------- + + final override fun visitBlockEnterNode(node: BlockEnterNode, data: Nothing?) { + visitBlockEnterNode(node) + } + + final override fun visitBlockExitNode(node: BlockExitNode, data: Nothing?) { + visitBlockExitNode(node) + } + + // ----------------------------------- When ----------------------------------- + + final override fun visitWhenEnterNode(node: WhenEnterNode, data: Nothing?) { + visitWhenEnterNode(node) + } + + final override fun visitWhenExitNode(node: WhenExitNode, data: Nothing?) { + visitWhenExitNode(node) + } + + final override fun visitWhenBranchConditionEnterNode(node: WhenBranchConditionEnterNode, data: Nothing?) { + visitWhenBranchConditionEnterNode(node) + } + + final override fun visitWhenBranchConditionExitNode(node: WhenBranchConditionExitNode, data: Nothing?) { + visitWhenBranchConditionExitNode(node) + } + + final override fun visitWhenBranchResultEnterNode(node: WhenBranchResultEnterNode, data: Nothing?) { + visitWhenBranchResultEnterNode(node) + } + + final override fun visitWhenBranchResultExitNode(node: WhenBranchResultExitNode, data: Nothing?) { + visitWhenBranchResultExitNode(node) + } + + final override fun visitWhenSyntheticElseBranchNode(node: WhenSyntheticElseBranchNode, data: Nothing?) { + visitWhenSyntheticElseBranchNode(node) + } + + + // ----------------------------------- Loop ----------------------------------- + + final override fun visitLoopEnterNode(node: LoopEnterNode, data: Nothing?) { + visitLoopEnterNode(node) + } + + final override fun visitLoopBlockEnterNode(node: LoopBlockEnterNode, data: Nothing?) { + visitLoopBlockEnterNode(node) + } + + final override fun visitLoopBlockExitNode(node: LoopBlockExitNode, data: Nothing?) { + visitLoopBlockExitNode(node) + } + + final override fun visitLoopConditionEnterNode(node: LoopConditionEnterNode, data: Nothing?) { + visitLoopConditionEnterNode(node) + } + + final override fun visitLoopConditionExitNode(node: LoopConditionExitNode, data: Nothing?) { + visitLoopConditionExitNode(node) + } + + final override fun visitLoopExitNode(node: LoopExitNode, data: Nothing?) { + visitLoopExitNode(node) + } + + // ----------------------------------- Try-catch-finally ----------------------------------- + + final override fun visitTryExpressionEnterNode(node: TryExpressionEnterNode, data: Nothing?) { + visitTryExpressionEnterNode(node) + } + + final override fun visitTryMainBlockEnterNode(node: TryMainBlockEnterNode, data: Nothing?) { + visitTryMainBlockEnterNode(node) + } + + final override fun visitTryMainBlockExitNode(node: TryMainBlockExitNode, data: Nothing?) { + visitTryMainBlockExitNode(node) + } + + final override fun visitCatchClauseEnterNode(node: CatchClauseEnterNode, data: Nothing?) { + visitCatchClauseEnterNode(node) + } + + final override fun visitCatchClauseExitNode(node: CatchClauseExitNode, data: Nothing?) { + visitCatchClauseExitNode(node) + } + + final override fun visitFinallyBlockEnterNode(node: FinallyBlockEnterNode, data: Nothing?) { + visitFinallyBlockEnterNode(node) + } + + final override fun visitFinallyBlockExitNode(node: FinallyBlockExitNode, data: Nothing?) { + visitFinallyBlockExitNode(node) + } + + final override fun visitFinallyProxyEnterNode(node: FinallyProxyEnterNode, data: Nothing?) { + visitFinallyProxyEnterNode(node) + } + + final override fun visitFinallyProxyExitNode(node: FinallyProxyExitNode, data: Nothing?) { + visitFinallyProxyExitNode(node) + } + + final override fun visitTryExpressionExitNode(node: TryExpressionExitNode, data: Nothing?) { + visitTryExpressionExitNode(node) + } + + // ----------------------------------- Boolean operators ----------------------------------- + + final override fun visitBinaryAndEnterNode(node: BinaryAndEnterNode, data: Nothing?) { + visitBinaryAndEnterNode(node) + } + + final override fun visitBinaryAndExitLeftOperandNode(node: BinaryAndExitLeftOperandNode, data: Nothing?) { + visitBinaryAndExitLeftOperandNode(node) + } + + final override fun visitBinaryAndEnterRightOperandNode(node: BinaryAndEnterRightOperandNode, data: Nothing?) { + visitBinaryAndEnterRightOperandNode(node) + } + + final override fun visitBinaryAndExitNode(node: BinaryAndExitNode, data: Nothing?) { + visitBinaryAndExitNode(node) + } + + final override fun visitBinaryOrEnterNode(node: BinaryOrEnterNode, data: Nothing?) { + visitBinaryOrEnterNode(node) + } + + final override fun visitBinaryOrExitLeftOperandNode(node: BinaryOrExitLeftOperandNode, data: Nothing?) { + visitBinaryOrExitLeftOperandNode(node) + } + + final override fun visitBinaryOrEnterRightOperandNode(node: BinaryOrEnterRightOperandNode, data: Nothing?) { + visitBinaryOrEnterRightOperandNode(node) + } + + final override fun visitBinaryOrExitNode(node: BinaryOrExitNode, data: Nothing?) { + visitBinaryOrExitNode(node) + } + + // ----------------------------------- Operator call ----------------------------------- + + final override fun visitTypeOperatorCallNode(node: TypeOperatorCallNode, data: Nothing?) { + visitTypeOperatorCallNode(node) + } + + final override fun visitOperatorCallNode(node: OperatorCallNode, data: Nothing?) { + visitOperatorCallNode(node) + } + + final override fun visitComparisonExpressionNode(node: ComparisonExpressionNode, data: Nothing?) { + visitComparisonExpressionNode(node) + } + + // ----------------------------------- Jump ----------------------------------- + + final override fun visitJumpNode(node: JumpNode, data: Nothing?) { + visitJumpNode(node) + } + + final override fun visitConstExpressionNode(node: ConstExpressionNode, data: Nothing?) { + visitConstExpressionNode(node) + } + + // ----------------------------------- Check not null call ----------------------------------- + + final override fun visitCheckNotNullCallNode(node: CheckNotNullCallNode, data: Nothing?) { + visitCheckNotNullCallNode(node) + } + + // ----------------------------------- Resolvable call ----------------------------------- + + final override fun visitQualifiedAccessNode(node: QualifiedAccessNode, data: Nothing?) { + visitQualifiedAccessNode(node) + } + + final override fun visitResolvedQualifierNode(node: ResolvedQualifierNode, data: Nothing?) { + visitResolvedQualifierNode(node) + } + + final override fun visitFunctionCallNode(node: FunctionCallNode, data: Nothing?) { + visitFunctionCallNode(node) + } + + final override fun visitDelegatedConstructorCallNode(node: DelegatedConstructorCallNode, data: Nothing?) { + visitDelegatedConstructorCallNode(node) + } + + final override fun visitThrowExceptionNode(node: ThrowExceptionNode, data: Nothing?) { + visitThrowExceptionNode(node) + } + + final override fun visitStubNode(node: StubNode, data: Nothing?) { + visitStubNode(node) + } + + final override fun visitVariableDeclarationNode(node: VariableDeclarationNode, data: Nothing?) { + visitVariableDeclarationNode(node) + } + + final override fun visitVariableAssignmentNode(node: VariableAssignmentNode, data: Nothing?) { + visitVariableAssignmentNode(node) + } + + final override fun visitEnterContractNode(node: EnterContractNode, data: Nothing?) { + visitEnterContractNode(node) + } + + final override fun visitExitContractNode(node: ExitContractNode, data: Nothing?) { + visitExitContractNode(node) + } + + final override fun visitEnterSafeCallNode(node: EnterSafeCallNode, data: Nothing?) { + visitEnterSafeCallNode(node) + } + + final override fun visitExitSafeCallNode(node: ExitSafeCallNode, data: Nothing?) { + visitExitSafeCallNode(node) + } + + // ----------------------------------- Other ----------------------------------- + + final override fun visitAnnotationEnterNode(node: AnnotationEnterNode, data: Nothing?) { + visitAnnotationEnterNode(node) + } + + final override fun visitAnnotationExitNode(node: AnnotationExitNode, data: Nothing?) { + visitAnnotationExitNode(node) + } +}