[FIR] Fix return expressions calculator
There was a problem that if las statement of lambda was a return expression from that lambda then result of return counted twice
This commit is contained in:
+1
-1
@@ -103,7 +103,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
return result.takeIf { it.isNotEmpty() }
|
return result.takeIf { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): List<FirStatement> {
|
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): Collection<FirStatement> {
|
||||||
return graphBuilder.returnExpressionsOfAnonymousFunction(function)
|
return graphBuilder.returnExpressionsOfAnonymousFunction(function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -161,7 +161,7 @@ class ControlFlowGraphBuilder {
|
|||||||
return exitNode to graph
|
return exitNode to graph
|
||||||
}
|
}
|
||||||
|
|
||||||
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): List<FirStatement> {
|
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): Collection<FirStatement> {
|
||||||
fun FirElement.extractArgument(): FirElement = when {
|
fun FirElement.extractArgument(): FirElement = when {
|
||||||
this is FirReturnExpression && target.labeledElement.symbol == function.symbol -> result.extractArgument()
|
this is FirReturnExpression && target.labeledElement.symbol == function.symbol -> result.extractArgument()
|
||||||
else -> this
|
else -> this
|
||||||
@@ -175,7 +175,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val exitNode = function.controlFlowGraphReference.controlFlowGraph?.exitNode ?: exitsOfAnonymousFunctions.getValue(function)
|
val exitNode = function.controlFlowGraphReference.controlFlowGraph?.exitNode ?: exitsOfAnonymousFunctions.getValue(function)
|
||||||
return exitNode.previousNodes.mapNotNull {
|
return exitNode.previousNodes.mapNotNullTo(mutableSetOf()) {
|
||||||
it.extractArgument() as FirStatement?
|
it.extractArgument() as FirStatement?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -212,7 +212,7 @@ class ResolvedLambdaAtom(
|
|||||||
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?
|
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?
|
||||||
) : PostponedResolvedAtomMarker {
|
) : PostponedResolvedAtomMarker {
|
||||||
override var analyzed: Boolean = false
|
override var analyzed: Boolean = false
|
||||||
lateinit var returnStatements: List<FirStatement>
|
lateinit var returnStatements: Collection<FirStatement>
|
||||||
|
|
||||||
// lateinit var resultArguments: List<KotlinCallArgument>
|
// lateinit var resultArguments: List<KotlinCallArgument>
|
||||||
// private set
|
// private set
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.types.model.freshTypeConstructor
|
|||||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||||
|
|
||||||
data class ReturnArgumentsAnalysisResult(
|
data class ReturnArgumentsAnalysisResult(
|
||||||
val returnArguments: List<FirStatement>,
|
val returnArguments: Collection<FirStatement>,
|
||||||
val inferenceSession: FirInferenceSession?
|
val inferenceSession: FirInferenceSession?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
digraph lambdaAsReturnOfLambda_kt {
|
||||||
|
graph [splines=ortho nodesep=3]
|
||||||
|
node [shape=box penwidth=2]
|
||||||
|
edge [penwidth=2]
|
||||||
|
|
||||||
|
subgraph cluster_0 {
|
||||||
|
color=red
|
||||||
|
0 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||||
|
1 [label="Jump: ^@run lambda@fun <anonymous>(foo: R|ERROR CLASS: No type for parameter|): R|kotlin/Unit| {
|
||||||
|
R|/bar|(R|<local>/foo|)
|
||||||
|
}
|
||||||
|
"];
|
||||||
|
2 [label="Stub" style="filled" fillcolor=gray];
|
||||||
|
3 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
0 -> {1};
|
||||||
|
1 -> {3};
|
||||||
|
1 -> {2} [style=dotted];
|
||||||
|
2 -> {3} [style=dotted];
|
||||||
|
|
||||||
|
subgraph cluster_1 {
|
||||||
|
color=red
|
||||||
|
4 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||||
|
5 [label="Access variable R|<local>/foo|"];
|
||||||
|
6 [label="Function call: R|/bar|(R|<local>/foo|)"];
|
||||||
|
7 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
4 -> {5};
|
||||||
|
5 -> {6};
|
||||||
|
6 -> {7};
|
||||||
|
|
||||||
|
subgraph cluster_2 {
|
||||||
|
color=red
|
||||||
|
8 [label="Enter function getter" style="filled" fillcolor=red];
|
||||||
|
9 [label="Exit function getter" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
8 -> {9};
|
||||||
|
|
||||||
|
subgraph cluster_3 {
|
||||||
|
color=red
|
||||||
|
10 [label="Enter property" style="filled" fillcolor=red];
|
||||||
|
11 [label="Postponed enter to lambda"];
|
||||||
|
12 [label="Postponed exit from lambda"];
|
||||||
|
13 [label="Function call: R|/run|<R|(ERROR CLASS: No type for parameter) -> kotlin/Unit|>(<L> = run@fun <anonymous>(): R|(ERROR CLASS: No type for parameter) -> kotlin/Unit|)"];
|
||||||
|
14 [label="Exit property" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
10 -> {11};
|
||||||
|
11 -> {12 12} [color=green];
|
||||||
|
12 -> {13};
|
||||||
|
13 -> {14};
|
||||||
|
|
||||||
|
subgraph cluster_4 {
|
||||||
|
color=red
|
||||||
|
15 [label="Enter function bar" style="filled" fillcolor=red];
|
||||||
|
16 [label="Exit function bar" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
15 -> {16};
|
||||||
|
|
||||||
|
subgraph cluster_5 {
|
||||||
|
color=red
|
||||||
|
17 [label="Enter function run" style="filled" fillcolor=red];
|
||||||
|
18 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|R|>|()"];
|
||||||
|
19 [label="Jump: ^run R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|R|>|()"];
|
||||||
|
20 [label="Stub" style="filled" fillcolor=gray];
|
||||||
|
21 [label="Exit function run" style="filled" fillcolor=red];
|
||||||
|
}
|
||||||
|
|
||||||
|
17 -> {18};
|
||||||
|
18 -> {19};
|
||||||
|
19 -> {21};
|
||||||
|
19 -> {20} [style=dotted];
|
||||||
|
20 -> {21} [style=dotted];
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// !DUMP_CFG
|
||||||
|
|
||||||
|
val x4: (String) -> Unit = run {
|
||||||
|
return@run (lambda@{ foo ->
|
||||||
|
bar(foo)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(s: String) {}
|
||||||
|
fun <R> run(block: () -> R): R = block()
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
FILE: lambdaAsReturnOfLambda.kt
|
||||||
|
public final val x4: R|(kotlin/String) -> kotlin/Unit| = R|/run|<R|(ERROR CLASS: No type for parameter) -> kotlin/Unit|>(<L> = run@fun <anonymous>(): R|(ERROR CLASS: No type for parameter) -> kotlin/Unit| {
|
||||||
|
^@run lambda@fun <anonymous>(foo: R|ERROR CLASS: No type for parameter|): R|kotlin/Unit| {
|
||||||
|
R|/bar|(R|<local>/foo|)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public get(): R|(kotlin/String) -> kotlin/Unit|
|
||||||
|
public final fun bar(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <R> run(block: R|() -> R|): R|R| {
|
||||||
|
^run R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|R|>|()
|
||||||
|
}
|
||||||
+5
@@ -576,6 +576,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/cfg/jumps.kt");
|
runTest("compiler/fir/resolve/testData/resolve/cfg/jumps.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaAsReturnOfLambda.kt")
|
||||||
|
public void testLambdaAsReturnOfLambda() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdaAsReturnOfLambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdas.kt")
|
@TestMetadata("lambdas.kt")
|
||||||
public void testLambdas() throws Exception {
|
public void testLambdas() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdas.kt");
|
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdas.kt");
|
||||||
|
|||||||
Generated
+5
@@ -576,6 +576,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/cfg/jumps.kt");
|
runTest("compiler/fir/resolve/testData/resolve/cfg/jumps.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaAsReturnOfLambda.kt")
|
||||||
|
public void testLambdaAsReturnOfLambda() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdaAsReturnOfLambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdas.kt")
|
@TestMetadata("lambdas.kt")
|
||||||
public void testLambdas() throws Exception {
|
public void testLambdas() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdas.kt");
|
runTest("compiler/fir/resolve/testData/resolve/cfg/lambdas.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user