diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 05d7a5f32c9..00cf41bf9cf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -12,6 +12,7 @@ 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.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.isNothing @@ -54,7 +55,7 @@ class ControlFlowGraphBuilder { private val exitsFromCompletedPostponedAnonymousFunctions: MutableList = mutableListOf() - private val enterToLocalClassesMembers: MutableMap, CFGNode<*>?> = mutableMapOf() + private val enterToLocalClassesMembers: MutableMap, CFGNode<*>?> = mutableMapOf() var levelCounter: Int = 0 private set @@ -256,29 +257,29 @@ class ControlFlowGraphBuilder { } fun prepareForLocalClassMembers(members: Collection>) { - members.forEachFunction { + members.forEachMember { enterToLocalClassesMembers[it.symbol] = lastNodes.topOrNull() } } fun cleanAfterForLocalClassMembers(members: Collection>) { - members.forEachFunction { + members.forEachMember { enterToLocalClassesMembers.remove(it.symbol) } } - private inline fun Collection>.forEachFunction(block: (FirFunction<*>) -> Unit) { + private inline fun Collection>.forEachMember(block: (FirCallableDeclaration<*>) -> Unit) { for (member in this) { - for (function in member.unwrap()) { - block(function) + for (callableDeclaration in member.unwrap()) { + block(callableDeclaration) } } } - private fun FirCallableMemberDeclaration<*>.unwrap(): List> = + private fun FirCallableMemberDeclaration<*>.unwrap(): List> = when (this) { is FirFunction<*> -> listOf(this) - is FirProperty -> listOfNotNull(this.getter, this.setter) + is FirProperty -> listOfNotNull(this.getter, this.setter, this) else -> emptyList() } @@ -332,6 +333,9 @@ class ControlFlowGraphBuilder { val enterNode = createPropertyInitializerEnterNode(property) val exitNode = createPropertyInitializerExitNode(property) topLevelVariableInitializerExitNodes.push(exitNode) + enterToLocalClassesMembers[property.symbol]?.let { + addEdge(it, enterNode, preferredKind = EdgeKind.Dfg) + } exitNodes.push(exitNode) lexicalScopes.push(stackOf(enterNode)) graph.enterNode = enterNode diff --git a/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassDelegatedProperties.fir.kt b/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassDelegatedProperties.fir.kt index d3ad13805bc..8c2903dbaf7 100644 --- a/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassDelegatedProperties.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassDelegatedProperties.fir.kt @@ -11,7 +11,7 @@ fun test(del: Any?) { if (del !is Del) return class Local { - val delegatedVal by df(del) - val delegatedVal1: Int by df(del) + val delegatedVal by df(del) + val delegatedVal1: Int by df(del) } } diff --git a/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassProperty.fir.kt b/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassProperty.fir.kt index 9438e8363d3..1c19c5e01a5 100644 --- a/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassProperty.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlow/local/LocalClassProperty.fir.kt @@ -2,10 +2,10 @@ fun test(x: Any?) { if (x !is String) return class C { - val v = x.length + val v = x.length val vGet: Int - get() = x.length + get() = x.length val s: String = x }