[FIR] Pass data flow to init blocks of local classes
This commit is contained in:
+13
-25
@@ -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)"];
|
||||
|
||||
+14
-7
@@ -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
-2
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user