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