[FIR] Pass data flow to init blocks of local classes

This commit is contained in:
Dmitriy Novozhilov
2020-03-31 17:53:47 +03:00
parent 16b5b2dcef
commit 20d0e8647d
3 changed files with 34 additions and 34 deletions
@@ -144,27 +144,15 @@ digraph propertiesAndInitBlocks_kt {
50 [label="Exit local class <getter>"];
49 [label="Exit function getter" style="filled" fillcolor=red];
}
subgraph cluster_16 {
color=blue
51 [label="Enter function <init>" style="filled" fillcolor=red];
53 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
52 [label="Exit function <init>" style="filled" fillcolor=red];
}
65 [label="Postponed enter to lambda"];
subgraph cluster_17 {
subgraph cluster_16 {
color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
22 [label="Exit local class <anonymous>"];
23 [label="Function call: R|java/lang/Exception.Exception|()"];
24 [label="Throw: throw R|java/lang/Exception.Exception|()"];
25 [label="Stub" style="filled" fillcolor=gray];
subgraph cluster_18 {
color=blue
35 [label="Enter function <init>" style="filled" fillcolor=red];
37 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
36 [label="Exit function <init>" style="filled" fillcolor=red];
}
subgraph cluster_19 {
subgraph cluster_17 {
color=blue
26 [label="Enter function foo" style="filled" fillcolor=red];
28 [label="Const: Int(1)"];
@@ -188,7 +176,7 @@ digraph propertiesAndInitBlocks_kt {
66 -> {67};
67 -> {64};
20 -> {21 22};
20 -> {26 35} [color=red];
20 -> {26 35 38} [color=red];
21 -> {20};
21 -> {66} [color=green];
22 -> {23};
@@ -206,24 +194,24 @@ digraph propertiesAndInitBlocks_kt {
33 -> {34} [style=dotted];
34 -> {27} [style=dotted];
48 -> {50};
48 -> {51} [color=red];
48 -> {51 54} [color=red];
50 -> {49};
subgraph cluster_20 {
subgraph cluster_18 {
color=red
70 [label="Enter property" style="filled" fillcolor=red];
subgraph cluster_21 {
subgraph cluster_19 {
color=blue
68 [label="Enter function getter" style="filled" fillcolor=red];
69 [label="Exit function getter" style="filled" fillcolor=red];
}
subgraph cluster_22 {
subgraph cluster_20 {
color=blue
72 [label="Try expression enter"];
subgraph cluster_23 {
subgraph cluster_21 {
color=blue
74 [label="Try main block enter"];
subgraph cluster_24 {
subgraph cluster_22 {
color=blue
77 [label="Enter block"];
78 [label="Const: Int(1)"];
@@ -231,10 +219,10 @@ digraph propertiesAndInitBlocks_kt {
}
80 [label="Try main block exit"];
}
subgraph cluster_25 {
subgraph cluster_23 {
color=blue
76 [label="Enter finally"];
subgraph cluster_26 {
subgraph cluster_24 {
color=blue
85 [label="Enter block"];
86 [label="Const: Int(0)"];
@@ -242,10 +230,10 @@ digraph propertiesAndInitBlocks_kt {
}
88 [label="Exit finally"];
}
subgraph cluster_27 {
subgraph cluster_25 {
color=blue
75 [label="Catch enter"];
subgraph cluster_28 {
subgraph cluster_26 {
color=blue
81 [label="Enter block"];
82 [label="Const: Int(2)"];
@@ -7,12 +7,13 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg
import org.jetbrains.kotlin.contracts.description.InvocationKind
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.*
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.isNothing
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
@@ -58,7 +59,7 @@ class ControlFlowGraphBuilder {
private val exitsFromCompletedPostponedAnonymousFunctions: MutableList<PostponedLambdaExitNode> = mutableListOf()
private val enterToLocalClassesMembers: MutableMap<FirCallableSymbol<*>, CFGNode<*>?> = mutableMapOf()
private val enterToLocalClassesMembers: MutableMap<AbstractFirBasedSymbol<*>, CFGNode<*>?> = mutableMapOf()
var levelCounter: Int = 0
private set
@@ -253,19 +254,19 @@ class ControlFlowGraphBuilder {
return graphs.pop()
}
fun prepareForLocalClassMembers(members: Collection<FirCallableMemberDeclaration<*>>) {
fun prepareForLocalClassMembers(members: Collection<FirSymbolOwner<*>>) {
members.forEachMember {
enterToLocalClassesMembers[it.symbol] = lastNodes.topOrNull()
}
}
fun cleanAfterForLocalClassMembers(members: Collection<FirCallableMemberDeclaration<*>>) {
fun cleanAfterForLocalClassMembers(members: Collection<FirSymbolOwner<*>>) {
members.forEachMember {
enterToLocalClassesMembers.remove(it.symbol)
}
}
private inline fun Collection<FirCallableMemberDeclaration<*>>.forEachMember(block: (FirCallableDeclaration<*>) -> Unit) {
private inline fun Collection<FirSymbolOwner<*>>.forEachMember(block: (FirSymbolOwner<*>) -> Unit) {
for (member in this) {
for (callableDeclaration in member.unwrap()) {
block(callableDeclaration)
@@ -273,9 +274,12 @@ class ControlFlowGraphBuilder {
}
}
private fun FirCallableMemberDeclaration<*>.unwrap(): List<FirCallableDeclaration<*>> =
private fun FirSymbolOwner<*>.unwrap(): List<FirSymbolOwner<*>> =
when (this) {
is FirFunction<*> -> listOf(this)
is FirFunction<*>,
is FirAnonymousInitializer
-> listOf(this)
is FirProperty -> listOfNotNull(this.getter, this.setter, this)
else -> emptyList()
}
@@ -824,6 +828,9 @@ class ControlFlowGraphBuilder {
lexicalScopes.push(stackOf(it))
}
val exitNode = createInitBlockExitNode(initBlock)
enterToLocalClassesMembers[initBlock.symbol]?.let {
addEdge(it, enterNode, preferredKind = EdgeKind.Dfg)
}
initBlockExitNodes.push(exitNode)
exitNodes.push(exitNode)
levelCounter++
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
@@ -15,7 +16,7 @@ import org.jetbrains.kotlin.utils.keysToMap
class LocalClassesNavigationInfo(
val parentForClass: Map<FirClass<*>, FirClass<*>?>,
private val parentClassForFunction: Map<FirCallableMemberDeclaration<*>, FirClass<*>>,
val allMembers: List<FirCallableMemberDeclaration<*>>
val allMembers: List<FirSymbolOwner<*>>
) {
val designationMap by lazy {
parentClassForFunction.keys.keysToMap {
@@ -46,7 +47,7 @@ fun FirClass<*>.collectLocalClassesNavigationInfo(): LocalClassesNavigationInfo
private class NavigationInfoVisitor : FirDefaultVisitorVoid() {
val resultingMap = mutableMapOf<FirCallableMemberDeclaration<*>, FirClass<*>>()
val parentForClass = mutableMapOf<FirClass<*>, FirClass<*>?>()
val allMembers = mutableListOf<FirCallableMemberDeclaration<*>>()
val allMembers = mutableListOf<FirSymbolOwner<*>>()
private var currentPath = persistentListOf<FirClass<*>>()
override fun visitElement(element: FirElement) {}
@@ -88,4 +89,8 @@ private class NavigationInfoVisitor : FirDefaultVisitorVoid() {
if (callableMemberDeclaration.returnTypeRef !is FirImplicitTypeRef) return
resultingMap[callableMemberDeclaration] = currentPath.last()
}
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer) {
allMembers += anonymousInitializer
}
}