FIR: Add callable references nodes to CFG

Otherwise, they are not being considered as return expressions from lambdas
This commit is contained in:
Denis.Zharkov
2021-01-13 12:16:03 +03:00
parent 6dc0440cd0
commit 5e83e10a72
7 changed files with 35 additions and 2 deletions
@@ -1112,6 +1112,12 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
graphBuilder.exitElvis().mergeIncomingFlow() graphBuilder.exitElvis().mergeIncomingFlow()
} }
// Callable reference
fun exitCallableReference(callableReferenceAccess: FirCallableReferenceAccess) {
graphBuilder.exitCallableReference(callableReferenceAccess).mergeIncomingFlow()
}
// ------------------------------------------------------ Utils ------------------------------------------------------ // ------------------------------------------------------ Utils ------------------------------------------------------
private var CFGNode<*>.flow: FLOW private var CFGNode<*>.flow: FLOW
@@ -564,6 +564,16 @@ class FunctionCallNode(
} }
} }
class CallableReferenceNode(
owner: ControlFlowGraph,
override val fir: FirCallableReferenceAccess,
level: Int, id: Int
) : CFGNode<FirCallableReferenceAccess>(owner, level, id) {
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
return visitor.visitCallableReferenceNode(this, data)
}
}
class DelegatedConstructorCallNode( class DelegatedConstructorCallNode(
owner: ControlFlowGraph, owner: ControlFlowGraph,
override val fir: FirDelegatedConstructorCall, override val fir: FirDelegatedConstructorCall,
@@ -116,6 +116,8 @@ fun CFGNode<*>.render(): String =
is ElvisRhsEnterNode -> "Enter rhs of ?:" is ElvisRhsEnterNode -> "Enter rhs of ?:"
is ElvisExitNode -> "Exit ?:" is ElvisExitNode -> "Exit ?:"
is CallableReferenceNode -> "Callable reference: ${fir.render(CfgRenderMode)}"
is AbstractBinaryExitNode -> throw IllegalStateException() is AbstractBinaryExitNode -> throw IllegalStateException()
}, },
) )
@@ -1039,6 +1039,12 @@ class ControlFlowGraphBuilder {
return node return node
} }
// ----------------------------------- Callable references -----------------------------------
fun exitCallableReference(callableReferenceAccess: FirCallableReferenceAccess): CallableReferenceNode {
return createCallableReferenceNode(callableReferenceAccess).also { addNewSimpleNode(it) }
}
// ----------------------------------- Block ----------------------------------- // ----------------------------------- Block -----------------------------------
fun enterInitBlock(initBlock: FirAnonymousInitializer): Pair<InitBlockEnterNode, CFGNode<*>?> { fun enterInitBlock(initBlock: FirAnonymousInitializer): Pair<InitBlockEnterNode, CFGNode<*>?> {
@@ -119,6 +119,9 @@ fun ControlFlowGraphBuilder.createLoopBlockExitNode(fir: FirLoop): LoopBlockExit
fun ControlFlowGraphBuilder.createFunctionCallNode(fir: FirFunctionCall): FunctionCallNode = fun ControlFlowGraphBuilder.createFunctionCallNode(fir: FirFunctionCall): FunctionCallNode =
FunctionCallNode(currentGraph, fir, levelCounter, createId()) FunctionCallNode(currentGraph, fir, levelCounter, createId())
fun ControlFlowGraphBuilder.createCallableReferenceNode(fir: FirCallableReferenceAccess): CallableReferenceNode =
CallableReferenceNode(currentGraph, fir, levelCounter, createId())
fun ControlFlowGraphBuilder.createDelegatedConstructorCallNode(fir: FirDelegatedConstructorCall): DelegatedConstructorCallNode = fun ControlFlowGraphBuilder.createDelegatedConstructorCallNode(fir: FirDelegatedConstructorCall): DelegatedConstructorCallNode =
DelegatedConstructorCallNode(currentGraph, fir, levelCounter, createId()) DelegatedConstructorCallNode(currentGraph, fir, levelCounter, createId())
@@ -277,6 +277,10 @@ abstract class ControlFlowGraphVisitor<out R, in D> {
return visitNode(node, data) return visitNode(node, data)
} }
open fun visitCallableReferenceNode(node: CallableReferenceNode, data: D): R {
return visitNode(node, data)
}
open fun visitDelegatedConstructorCallNode(node: DelegatedConstructorCallNode, data: D): R { open fun visitDelegatedConstructorCallNode(node: DelegatedConstructorCallNode, data: D): R {
return visitNode(node, data) return visitNode(node, data)
} }
@@ -660,9 +660,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
callableReferenceAccess, data.expectedType, resolutionContext, callableReferenceAccess, data.expectedType, resolutionContext,
) ?: callableReferenceAccess ) ?: callableReferenceAccess
dataFlowAnalyzer.exitCallableReference(resolvedReference)
return resolvedReference.compose() return resolvedReference.compose()
} }
dataFlowAnalyzer.exitCallableReference(callableReferenceAccessWithTransformedLHS)
return callableReferenceAccessWithTransformedLHS.compose() return callableReferenceAccessWithTransformedLHS.compose()
} }