diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt index 7012226585b..cd27143145f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt @@ -217,7 +217,7 @@ class ConstraintSystemCompleter(val components: InferenceComponents) { primitive.processAllContainingCallCandidates( // TODO: remove this argument and relevant parameter // Currently, it's used because otherwise problem happens with a lambda in a try-block (see tryWithLambdaInside test) - processBlocks = primitive !is FirTryExpression + processBlocks = true ) { candidate -> candidate.postponedAtoms.forEach { notAnalyzedArguments.addIfNotNull(it.safeAs()?.takeUnless { it.analyzed }) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 2efcc163113..e88010eb130 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -127,6 +127,14 @@ abstract class FirDataFlowAnalyzer( return graph } + // ----------------------------------- Anonymous function ----------------------------------- + + fun visitPostponedAnonymousFunction(anonymousFunction: FirAnonymousFunction) { + val (enterNode, exitNode) = graphBuilder.visitPostponedAnonymousFunction(anonymousFunction) + enterNode.mergeIncomingFlow() + exitNode.mergeIncomingFlow() + } + // ----------------------------------- Property ----------------------------------- fun enterProperty(property: FirProperty) { @@ -800,7 +808,7 @@ abstract class FirDataFlowAnalyzer( val previousFlows = if (node.isDead) node.previousNodes.map { it.flow } else - node.previousNodes.mapNotNull { prev -> prev.takeIf { node.incomingEdges[it] != EdgeKind.Dead }?.flow } + node.previousNodes.mapNotNull { prev -> prev.takeIf { node.incomingEdges.getValue(it).usedInDfa }?.flow } val flow = logicSystem.joinFlow(previousFlows) if (updateReceivers) { logicSystem.updateAllReceivers(flow) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt index 0523930ba18..b46a9239465 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt @@ -9,6 +9,7 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirProperty @@ -35,8 +36,11 @@ class ControlFlowGraph(val name: String, val kind: Kind) { } } -enum class EdgeKind { - Simple, Dead +enum class EdgeKind(val usedInDfa: Boolean) { + Simple(usedInDfa = true), + Dead(usedInDfa = false), + Cfg(usedInDfa = false), + Dfg(usedInDfa = true) } sealed class CFGNode(val owner: ControlFlowGraph, val level: Int, private val id: Int) { @@ -99,6 +103,11 @@ interface ExitNodeMarker class FunctionEnterNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), EnterNodeMarker class FunctionExitNode(owner: ControlFlowGraph, override val fir: FirFunction<*>, level: Int, id: Int) : CFGNode>(owner, level, id), ExitNodeMarker +// ----------------------------------- Anonymous function ----------------------------------- + +class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) +class PostponedLambdaExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNode(owner, level, id) + // ----------------------------------- Property ----------------------------------- class PropertyInitializerEnterNode(owner: ControlFlowGraph, override val fir: FirProperty, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker 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 c175b2dd568..3a755642ebe 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,8 @@ 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.FirAnonymousFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.isNothing class ControlFlowGraphBuilder { @@ -48,6 +50,9 @@ class ControlFlowGraphBuilder { private val blocksOfFunctions: MutableMap> = mutableMapOf() private val exitsOfAnonymousFunctions: MutableMap = mutableMapOf() + private val entersToPostponedAnonymousFunctions: MutableMap, PostponedLambdaEnterNode> = mutableMapOf() + private val exitsFromPostponedAnonymousFunctions: MutableMap, PostponedLambdaExitNode> = mutableMapOf() + var levelCounter: Int = 0 private set @@ -75,7 +80,7 @@ class ControlFlowGraphBuilder { val isInplace = invocationKind.isInplace() val previousNode = if (!isInplace && graphs.topOrNull()?.let { it.kind != ControlFlowGraph.Kind.TopLevel } == true) { - lastNodes.top() + entersToPostponedAnonymousFunctions[function.symbol] ?: lastNodes.top() } else { null } @@ -86,7 +91,13 @@ class ControlFlowGraphBuilder { val enterNode = createFunctionEnterNode(function, isInplace).also { if (isInplace) { - addNewSimpleNode(it) + val postponedEnterNode = entersToPostponedAnonymousFunctions[function.symbol] + if (postponedEnterNode != null) { + addEdge(postponedEnterNode, it) + lastNodes.push(it) + } else { + addNewSimpleNode(it) + } } else { lexicalScopes.push(stackOf()) lastNodes.push(it) @@ -120,15 +131,26 @@ class ControlFlowGraphBuilder { if (!isInplace) { exitNodes.pop() } + val postponedEnterNode = entersToPostponedAnonymousFunctions.remove(function.symbol) + val postponedExitNode = exitsFromPostponedAnonymousFunctions.remove(function.symbol) if (isInplace) { val enterNode = functionEnterNodes.pop() + @Suppress("NON_EXHAUSTIVE_WHEN") when (invocationKind) { InvocationKind.AT_LEAST_ONCE, InvocationKind.UNKNOWN -> addEdge(exitNode, enterNode, propagateDeadness = false) } + if (postponedExitNode != null) { + CFGNode.addEdge(lastNodes.pop(), postponedExitNode, propagateDeadness = true, kind = EdgeKind.Cfg) + } } else { if (function.body == null) { addEdge(lastNodes.pop(), exitNode) } + if (postponedExitNode != null) { + requireNotNull(postponedEnterNode) + val kind = if (postponedEnterNode.isDead) EdgeKind.Dead else EdgeKind.Cfg + CFGNode.addEdge(postponedEnterNode, postponedExitNode, kind, propagateDeadness = true) + } lexicalScopes.pop() } exitNode.updateDeadStatus() @@ -157,6 +179,20 @@ class ControlFlowGraphBuilder { } } + // ----------------------------------- Anonymous function ----------------------------------- + + fun visitPostponedAnonymousFunction(anonymousFunction: FirAnonymousFunction): Pair { + val enterNode = createPostponedLambdaEnterNode(anonymousFunction) + val exitNode = createPostponedLambdaExitNode(anonymousFunction) + val symbol = anonymousFunction.symbol + entersToPostponedAnonymousFunctions[symbol] = enterNode + exitsFromPostponedAnonymousFunctions[symbol] = exitNode + CFGNode.addEdge(lastNodes.pop(), enterNode, kind = EdgeKind.Simple, propagateDeadness = true) + CFGNode.addEdge(enterNode, exitNode, kind = EdgeKind.Dfg, propagateDeadness = true) + lastNodes.push(exitNode) + return enterNode to exitNode + } + // ----------------------------------- Block ----------------------------------- fun enterBlock(block: FirBlock): BlockEnterNode? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt index 45acf717941..57cd3ad3240 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg +import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirProperty @@ -179,4 +180,10 @@ fun ControlFlowGraphBuilder.createExitSafeCallNode(fir: FirQualifiedAccess): Exi ExitSafeCallNode(graph, fir, levelCounter, createId()) fun ControlFlowGraphBuilder.createEnterSafeCallNode(fir: FirQualifiedAccess): EnterSafeCallNode = - EnterSafeCallNode(graph, fir, levelCounter, createId()) \ No newline at end of file + EnterSafeCallNode(graph, fir, levelCounter, createId()) + +fun ControlFlowGraphBuilder.createPostponedLambdaExitNode(fir: FirAnonymousFunction): PostponedLambdaExitNode = + PostponedLambdaExitNode(graph, fir, levelCounter, createId()) + +fun ControlFlowGraphBuilder.createPostponedLambdaEnterNode(fir: FirAnonymousFunction): PostponedLambdaEnterNode = + PostponedLambdaEnterNode(graph, fir, levelCounter, createId()) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt index 508c2b693af..f428ff5c50e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt @@ -33,6 +33,8 @@ class FirControlFlowGraphRenderVisitor( mapOf( EdgeKind.Simple to "", EdgeKind.Dead to "[style=dotted]", + EdgeKind.Cfg to "[color=green]", + EdgeKind.Dfg to "[color=red]", ) ) } @@ -204,6 +206,9 @@ private fun CFGNode<*>.render(): String = is EnterSafeCallNode -> "Enter safe call" is ExitSafeCallNode -> "Exit safe call" + is PostponedLambdaEnterNode -> "Postponed enter to lambda" + is PostponedLambdaExitNode -> "Postponed exit from lambda" + else -> TODO(this@render.toString()) }, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index f606a65293e..a133b2e3f22 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -404,6 +404,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } return when (data) { ResolutionMode.ContextDependent -> { + dataFlowAnalyzer.visitPostponedAnonymousFunction(anonymousFunction) anonymousFunction.compose() } is ResolutionMode.LambdaResolution -> { diff --git a/compiler/fir/resolve/testData/resolve/cfg/complex.dot b/compiler/fir/resolve/testData/resolve/cfg/complex.dot index d49ee038bb1..9872468f477 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/complex.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/complex.dot @@ -28,58 +28,60 @@ digraph complex_kt { 14 [label="Access variable R|/url|"]; 15 [label="Access variable R|/url|"]; 16 [label="Function call: #.#(R|/url|)"]; - 17 [label="Function call: #.#(R|/url|).#( = connect@fun (): R|ERROR CLASS: Unresolved name: fromJson| { + 17 [label="Postponed enter to lambda"]; + 18 [label="Postponed exit from lambda"]; + 19 [label="Function call: #.#(R|/url|).#( = connect@fun (): R|ERROR CLASS: Unresolved name: fromJson| { #().#().#(#.#.#(), (Q|kotlin/Array|).R|kotlin/jvm/java|) } )"]; - 18 [label="Exit block"]; + 20 [label="Exit block"]; } - 19 [label="Try main block exit"]; + 21 [label="Try main block exit"]; } subgraph cluster_4 { color=blue - 20 [label="Catch enter"]; + 22 [label="Catch enter"]; subgraph cluster_5 { color=blue - 21 [label="Enter block"]; - 22 [label="Const: String(Can't parse json response)"]; - 23 [label="Access variable R|/syntaxException|"]; - 24 [label="Access variable R|/syntaxException|"]; + 23 [label="Enter block"]; + 24 [label="Const: String(Can't parse json response)"]; 25 [label="Access variable R|/syntaxException|"]; - 26 [label="Function call: #(String(Can't parse json response), R|/syntaxException|)"]; - 27 [label="Throw: throw #(String(Can't parse json response), R|/syntaxException|)"]; - 28 [label="Stub" style="filled" fillcolor=gray]; - 29 [label="Exit block" style="filled" fillcolor=gray]; + 26 [label="Access variable R|/syntaxException|"]; + 27 [label="Access variable R|/syntaxException|"]; + 28 [label="Function call: #(String(Can't parse json response), R|/syntaxException|)"]; + 29 [label="Throw: throw #(String(Can't parse json response), R|/syntaxException|)"]; + 30 [label="Stub" style="filled" fillcolor=gray]; + 31 [label="Exit block" style="filled" fillcolor=gray]; } - 30 [label="Catch exit" style="filled" fillcolor=gray]; + 32 [label="Catch exit" style="filled" fillcolor=gray]; } subgraph cluster_6 { color=blue - 31 [label="Catch enter"]; + 33 [label="Catch enter"]; subgraph cluster_7 { color=blue - 32 [label="Enter block"]; - 33 [label="Access variable R|/ioException|"]; - 34 [label="Access variable R|/ioException|"]; + 34 [label="Enter block"]; 35 [label="Access variable R|/ioException|"]; - 36 [label="Function call: #(R|/ioException|)"]; - 37 [label="Throw: throw #(R|/ioException|)"]; - 38 [label="Stub" style="filled" fillcolor=gray]; - 39 [label="Exit block" style="filled" fillcolor=gray]; + 36 [label="Access variable R|/ioException|"]; + 37 [label="Access variable R|/ioException|"]; + 38 [label="Function call: #(R|/ioException|)"]; + 39 [label="Throw: throw #(R|/ioException|)"]; + 40 [label="Stub" style="filled" fillcolor=gray]; + 41 [label="Exit block" style="filled" fillcolor=gray]; } - 40 [label="Catch exit" style="filled" fillcolor=gray]; + 42 [label="Catch exit" style="filled" fillcolor=gray]; } - 41 [label="Try expression exit"]; + 43 [label="Try expression exit"]; } - 42 [label="Variable declaration: lval pluginDTOs: R|kotlin/Array|"]; - 43 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red]; + 44 [label="Variable declaration: lval pluginDTOs: R|kotlin/Array|"]; + 45 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red]; } subgraph cluster_8 { color=blue - 44 [label="Enter annotation"]; - 45 [label="Access variable #"]; - 46 [label="Access variable #"]; - 47 [label="Exit annotation"]; + 46 [label="Enter annotation"]; + 47 [label="Access variable #"]; + 48 [label="Access variable #"]; + 49 [label="Exit annotation"]; } 0 -> {1}; @@ -92,63 +94,63 @@ digraph complex_kt { 7 -> {8}; 8 -> {9}; 9 -> {10}; - 10 -> {43 31 20 11}; + 10 -> {45 33 22 11}; 11 -> {12}; 12 -> {13}; 13 -> {14}; 14 -> {15}; 15 -> {16}; 16 -> {17}; - 17 -> {18}; + 17 -> {18 18} [color=green]; 18 -> {19}; - 19 -> {41}; - 20 -> {43 21}; - 21 -> {22}; - 22 -> {23}; + 19 -> {20}; + 20 -> {21}; + 21 -> {43}; + 22 -> {45 23}; 23 -> {24}; 24 -> {25}; 25 -> {26}; 26 -> {27}; - 27 -> {43}; - 27 -> {28} [style=dotted]; - 28 -> {29} [style=dotted]; + 27 -> {28}; + 28 -> {29}; + 29 -> {45}; 29 -> {30} [style=dotted]; - 30 -> {41} [style=dotted]; - 31 -> {43 32}; - 32 -> {33}; - 33 -> {34}; + 30 -> {31} [style=dotted]; + 31 -> {32} [style=dotted]; + 32 -> {43} [style=dotted]; + 33 -> {45 34}; 34 -> {35}; 35 -> {36}; 36 -> {37}; - 37 -> {43}; - 37 -> {38} [style=dotted]; - 38 -> {39} [style=dotted]; + 37 -> {38}; + 38 -> {39}; + 39 -> {45}; 39 -> {40} [style=dotted]; 40 -> {41} [style=dotted]; - 41 -> {42}; - 42 -> {43}; + 41 -> {42} [style=dotted]; + 42 -> {43} [style=dotted]; 43 -> {44}; 44 -> {45}; 45 -> {46}; 46 -> {47}; + 47 -> {48}; + 48 -> {49}; subgraph cluster_9 { color=red - 48 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - 49 [label="Function call: #()"]; - 50 [label="Function call: #().#()"]; - 51 [label="Access variable #"]; - 52 [label="Access variable #"]; - 53 [label="Function call: #.#.#()"]; - 54 [label="Access variable R|kotlin/jvm/java|"]; - 55 [label="Access variable R|kotlin/jvm/java|"]; + 50 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 51 [label="Function call: #()"]; + 52 [label="Function call: #().#()"]; + 53 [label="Access variable #"]; + 54 [label="Access variable #"]; + 55 [label="Function call: #.#.#()"]; 56 [label="Access variable R|kotlin/jvm/java|"]; - 57 [label="Function call: #().#().#(#.#.#(), (Q|kotlin/Array|).R|kotlin/jvm/java|)"]; - 58 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 57 [label="Access variable R|kotlin/jvm/java|"]; + 58 [label="Access variable R|kotlin/jvm/java|"]; + 59 [label="Function call: #().#().#(#.#.#(), (Q|kotlin/Array|).R|kotlin/jvm/java|)"]; + 60 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 48 -> {49}; - 49 -> {50}; 50 -> {51}; 51 -> {52}; 52 -> {53}; @@ -157,96 +159,98 @@ digraph complex_kt { 55 -> {56}; 56 -> {57}; 57 -> {58}; + 58 -> {59}; + 59 -> {60}; subgraph cluster_10 { color=red - 59 [label="Enter function close" style="filled" fillcolor=red]; - 60 [label="Exit function close" style="filled" fillcolor=red]; + 61 [label="Enter function close" style="filled" fillcolor=red]; + 62 [label="Exit function close" style="filled" fillcolor=red]; } - 59 -> {60}; + 61 -> {62}; subgraph cluster_11 { color=red - 61 [label="Enter function closeFinally" style="filled" fillcolor=red]; + 63 [label="Enter function closeFinally" style="filled" fillcolor=red]; subgraph cluster_12 { color=blue - 62 [label="Enter when"]; + 64 [label="Enter when"]; subgraph cluster_13 { color=blue - 63 [label="Enter when branch condition "]; - 64 [label="Access variable this@R|/closeFinally|"]; - 65 [label="Const: Null(null)"]; - 66 [label="Operator =="]; - 67 [label="Exit when branch condition"]; + 65 [label="Enter when branch condition "]; + 66 [label="Access variable this@R|/closeFinally|"]; + 67 [label="Const: Null(null)"]; + 68 [label="Operator =="]; + 69 [label="Exit when branch condition"]; } subgraph cluster_14 { color=blue - 68 [label="Enter when branch condition "]; - 69 [label="Access variable R|/cause|"]; - 70 [label="Const: Null(null)"]; - 71 [label="Operator =="]; - 72 [label="Exit when branch condition"]; + 70 [label="Enter when branch condition "]; + 71 [label="Access variable R|/cause|"]; + 72 [label="Const: Null(null)"]; + 73 [label="Operator =="]; + 74 [label="Exit when branch condition"]; } subgraph cluster_15 { color=blue - 73 [label="Enter when branch condition else"]; - 74 [label="Exit when branch condition"]; + 75 [label="Enter when branch condition else"]; + 76 [label="Exit when branch condition"]; } - 75 [label="Enter when branch result"]; + 77 [label="Enter when branch result"]; subgraph cluster_16 { color=blue - 76 [label="Enter block"]; + 78 [label="Enter block"]; subgraph cluster_17 { color=blue - 77 [label="Try expression enter"]; + 79 [label="Try expression enter"]; subgraph cluster_18 { color=blue - 78 [label="Try main block enter"]; + 80 [label="Try main block enter"]; subgraph cluster_19 { color=blue - 79 [label="Enter block"]; - 80 [label="Function call: this@R|/closeFinally|.R|/AutoCloseable.close|()"]; - 81 [label="Exit block"]; + 81 [label="Enter block"]; + 82 [label="Function call: this@R|/closeFinally|.R|/AutoCloseable.close|()"]; + 83 [label="Exit block"]; } - 82 [label="Try main block exit"]; + 84 [label="Try main block exit"]; } subgraph cluster_20 { color=blue - 83 [label="Catch enter"]; + 85 [label="Catch enter"]; subgraph cluster_21 { color=blue - 84 [label="Enter block"]; - 85 [label="Access variable R|/cause|"]; - 86 [label="Access variable R|/closeException|"]; - 87 [label="Function call: R|/cause|.R|kotlin/addSuppressed|(R|/closeException|)"]; - 88 [label="Exit block"]; + 86 [label="Enter block"]; + 87 [label="Access variable R|/cause|"]; + 88 [label="Access variable R|/closeException|"]; + 89 [label="Function call: R|/cause|.R|kotlin/addSuppressed|(R|/closeException|)"]; + 90 [label="Exit block"]; } - 89 [label="Catch exit"]; + 91 [label="Catch exit"]; } - 90 [label="Try expression exit"]; + 92 [label="Try expression exit"]; } - 91 [label="Exit block"]; + 93 [label="Exit block"]; } - 92 [label="Exit when branch result"]; - 93 [label="Enter when branch result"]; + 94 [label="Exit when branch result"]; + 95 [label="Enter when branch result"]; subgraph cluster_22 { color=blue - 94 [label="Enter block"]; - 95 [label="Function call: this@R|/closeFinally|.R|/AutoCloseable.close|()"]; - 96 [label="Exit block"]; + 96 [label="Enter block"]; + 97 [label="Function call: this@R|/closeFinally|.R|/AutoCloseable.close|()"]; + 98 [label="Exit block"]; } - 97 [label="Exit when branch result"]; - 98 [label="Enter when branch result"]; + 99 [label="Exit when branch result"]; + 100 [label="Enter when branch result"]; subgraph cluster_23 { color=blue - 99 [label="Enter block"]; - 100 [label="Exit block"]; + 101 [label="Enter block"]; + 102 [label="Exit block"]; } - 101 [label="Exit when branch result"]; - 102 [label="Exit when"]; + 103 [label="Exit when branch result"]; + 104 [label="Exit when"]; } - 103 [label="Jump: ^closeFinally when () { + 105 [label="Jump: ^closeFinally when () { ==(this@R|/closeFinally|, Null(null)) -> { } ==(R|/cause|, Null(null)) -> { @@ -263,120 +267,118 @@ digraph complex_kt { } } "]; - 104 [label="Stub" style="filled" fillcolor=gray]; - 105 [label="Exit function closeFinally" style="filled" fillcolor=red]; + 106 [label="Stub" style="filled" fillcolor=gray]; + 107 [label="Exit function closeFinally" style="filled" fillcolor=red]; } - 61 -> {62}; - 62 -> {63}; 63 -> {64}; 64 -> {65}; 65 -> {66}; 66 -> {67}; - 67 -> {98 68}; + 67 -> {68}; 68 -> {69}; - 69 -> {70}; + 69 -> {100 70}; 70 -> {71}; 71 -> {72}; - 72 -> {93 73}; + 72 -> {73}; 73 -> {74}; - 74 -> {75}; + 74 -> {95 75}; 75 -> {76}; 76 -> {77}; 77 -> {78}; - 78 -> {105 83 79}; + 78 -> {79}; 79 -> {80}; - 80 -> {81}; + 80 -> {107 85 81}; 81 -> {82}; - 82 -> {90}; - 83 -> {105 84}; - 84 -> {85}; - 85 -> {86}; + 82 -> {83}; + 83 -> {84}; + 84 -> {92}; + 85 -> {107 86}; 86 -> {87}; 87 -> {88}; 88 -> {89}; 89 -> {90}; 90 -> {91}; 91 -> {92}; - 92 -> {102}; + 92 -> {93}; 93 -> {94}; - 94 -> {95}; + 94 -> {104}; 95 -> {96}; 96 -> {97}; - 97 -> {102}; + 97 -> {98}; 98 -> {99}; - 99 -> {100}; + 99 -> {104}; 100 -> {101}; 101 -> {102}; 102 -> {103}; - 103 -> {105}; - 103 -> {104} [style=dotted]; - 104 -> {105} [style=dotted]; + 103 -> {104}; + 104 -> {105}; + 105 -> {107}; + 105 -> {106} [style=dotted]; + 106 -> {107} [style=dotted]; subgraph cluster_24 { color=red - 106 [label="Enter function firstIsInstanceOrNull" style="filled" fillcolor=red]; - 107 [label="Access variable this@R|/firstIsInstanceOrNull|"]; - 108 [label="Variable declaration: lval : R|kotlin/sequences/Sequence<*>|"]; - 109 [label="Access variable R|/|"]; - 110 [label="Function call: R|/|.R|FakeOverride|>|()"]; - 111 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; + 108 [label="Enter function firstIsInstanceOrNull" style="filled" fillcolor=red]; + 109 [label="Access variable this@R|/firstIsInstanceOrNull|"]; + 110 [label="Variable declaration: lval : R|kotlin/sequences/Sequence<*>|"]; + 111 [label="Access variable R|/|"]; + 112 [label="Function call: R|/|.R|FakeOverride|>|()"]; + 113 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; subgraph cluster_25 { color=blue - 112 [label="Enter while loop"]; + 114 [label="Enter while loop"]; subgraph cluster_26 { color=blue - 113 [label="Enter loop condition"]; - 114 [label="Access variable R|/|"]; - 115 [label="Function call: R|/|.R|kotlin/collections/Iterator.hasNext|()"]; - 116 [label="Exit loop condition"]; + 115 [label="Enter loop condition"]; + 116 [label="Access variable R|/|"]; + 117 [label="Function call: R|/|.R|kotlin/collections/Iterator.hasNext|()"]; + 118 [label="Exit loop condition"]; } subgraph cluster_27 { color=blue - 117 [label="Enter loop block"]; + 119 [label="Enter loop block"]; subgraph cluster_28 { color=blue - 118 [label="Enter block"]; - 119 [label="Access variable R|/|"]; - 120 [label="Function call: R|/|.R|FakeOverride|()"]; - 121 [label="Variable declaration: lval element: R|kotlin/Any?|"]; + 120 [label="Enter block"]; + 121 [label="Access variable R|/|"]; + 122 [label="Function call: R|/|.R|FakeOverride|()"]; + 123 [label="Variable declaration: lval element: R|kotlin/Any?|"]; subgraph cluster_29 { color=blue - 122 [label="Enter when"]; + 124 [label="Enter when"]; subgraph cluster_30 { color=blue - 123 [label="Enter when branch condition "]; - 124 [label="Access variable R|/element|"]; - 125 [label="Type operator: element is T"]; - 126 [label="Exit when branch condition"]; + 125 [label="Enter when branch condition "]; + 126 [label="Access variable R|/element|"]; + 127 [label="Type operator: element is T"]; + 128 [label="Exit when branch condition"]; } - 127 [label="Synthetic else branch"]; - 128 [label="Enter when branch result"]; + 129 [label="Synthetic else branch"]; + 130 [label="Enter when branch result"]; subgraph cluster_31 { color=blue - 129 [label="Enter block"]; - 130 [label="Access variable R|/element|"]; - 131 [label="Jump: ^firstIsInstanceOrNull R|/element|"]; - 132 [label="Stub" style="filled" fillcolor=gray]; - 133 [label="Exit block" style="filled" fillcolor=gray]; + 131 [label="Enter block"]; + 132 [label="Access variable R|/element|"]; + 133 [label="Jump: ^firstIsInstanceOrNull R|/element|"]; + 134 [label="Stub" style="filled" fillcolor=gray]; + 135 [label="Exit block" style="filled" fillcolor=gray]; } - 134 [label="Exit when branch result" style="filled" fillcolor=gray]; - 135 [label="Exit when"]; + 136 [label="Exit when branch result" style="filled" fillcolor=gray]; + 137 [label="Exit when"]; } - 136 [label="Exit block"]; + 138 [label="Exit block"]; } - 137 [label="Exit loop block"]; + 139 [label="Exit loop block"]; } - 138 [label="Exit whileloop"]; + 140 [label="Exit whileloop"]; } - 139 [label="Const: Null(null)"]; - 140 [label="Jump: ^firstIsInstanceOrNull Null(null)"]; - 141 [label="Stub" style="filled" fillcolor=gray]; - 142 [label="Exit function firstIsInstanceOrNull" style="filled" fillcolor=red]; + 141 [label="Const: Null(null)"]; + 142 [label="Jump: ^firstIsInstanceOrNull Null(null)"]; + 143 [label="Stub" style="filled" fillcolor=gray]; + 144 [label="Exit function firstIsInstanceOrNull" style="filled" fillcolor=red]; } - 106 -> {107}; - 107 -> {108}; 108 -> {109}; 109 -> {110}; 110 -> {111}; @@ -385,9 +387,9 @@ digraph complex_kt { 113 -> {114}; 114 -> {115}; 115 -> {116}; - 116 -> {138 117}; + 116 -> {117}; 117 -> {118}; - 118 -> {119}; + 118 -> {140 119}; 119 -> {120}; 120 -> {121}; 121 -> {122}; @@ -395,23 +397,25 @@ digraph complex_kt { 123 -> {124}; 124 -> {125}; 125 -> {126}; - 126 -> {128 127}; - 127 -> {135}; - 128 -> {129}; - 129 -> {130}; + 126 -> {127}; + 127 -> {128}; + 128 -> {130 129}; + 129 -> {137}; 130 -> {131}; - 131 -> {142}; - 131 -> {132} [style=dotted]; - 132 -> {133} [style=dotted]; + 131 -> {132}; + 132 -> {133}; + 133 -> {144}; 133 -> {134} [style=dotted]; 134 -> {135} [style=dotted]; - 135 -> {136}; - 136 -> {137}; - 137 -> {113}; + 135 -> {136} [style=dotted]; + 136 -> {137} [style=dotted]; + 137 -> {138}; 138 -> {139}; - 139 -> {140}; - 140 -> {142}; - 140 -> {141} [style=dotted]; - 141 -> {142} [style=dotted]; + 139 -> {115}; + 140 -> {141}; + 141 -> {142}; + 142 -> {144}; + 142 -> {143} [style=dotted]; + 143 -> {144} [style=dotted]; } diff --git a/compiler/fir/resolve/testData/resolve/cfg/jumps.dot b/compiler/fir/resolve/testData/resolve/cfg/jumps.dot index 80f79fac468..6e3b6791d22 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/jumps.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/jumps.dot @@ -334,26 +334,32 @@ digraph jumps_kt { subgraph cluster_31 { color=red 112 [label="Enter function test_6" style="filled" fillcolor=red]; + 113 [label="Postponed enter to lambda"]; subgraph cluster_32 { color=blue - 113 [label="Enter function anonymousFunction"]; - 114 [label="Jump: ^@run Unit"]; - 115 [label="Stub" style="filled" fillcolor=gray]; - 116 [label="Exit function anonymousFunction"]; + 114 [label="Enter function anonymousFunction"]; + 115 [label="Jump: ^@run Unit"]; + 116 [label="Stub" style="filled" fillcolor=gray]; + 117 [label="Exit function anonymousFunction"]; } - 117 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 118 [label="Postponed exit from lambda"]; + 119 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { ^@run Unit } )"]; - 118 [label="Exit function test_6" style="filled" fillcolor=red]; + 120 [label="Exit function test_6" style="filled" fillcolor=red]; } 112 -> {113}; - 113 -> {116 114}; - 114 -> {116}; - 114 -> {115} [style=dotted]; + 113 -> {114}; + 113 -> {118} [color=red]; + 114 -> {117 115}; + 115 -> {117}; 115 -> {116} [style=dotted]; - 116 -> {113 117}; - 117 -> {118}; + 116 -> {117} [style=dotted]; + 117 -> {114}; + 117 -> {118} [color=green]; + 118 -> {119}; + 119 -> {120}; } diff --git a/compiler/fir/resolve/testData/resolve/cfg/lambdas.dot b/compiler/fir/resolve/testData/resolve/cfg/lambdas.dot index 086720ebfff..0179cce32b3 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/lambdas.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/lambdas.dot @@ -31,23 +31,25 @@ digraph lambdas_kt { subgraph cluster_4 { color=blue 11 [label="Enter block"]; + 12 [label="Postponed enter to lambda"]; subgraph cluster_5 { color=blue - 12 [label="Enter function anonymousFunction"]; - 13 [label="Access variable R|/x|"]; - 14 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; - 15 [label="Exit function anonymousFunction"]; + 13 [label="Enter function anonymousFunction"]; + 14 [label="Access variable R|/x|"]; + 15 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; + 16 [label="Exit function anonymousFunction"]; } - 16 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 17 [label="Postponed exit from lambda"]; + 18 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { R|/x|.R|kotlin/Int.inc|() } )"]; - 17 [label="Exit block"]; + 19 [label="Exit block"]; } - 18 [label="Exit when branch result"]; - 19 [label="Exit when"]; + 20 [label="Exit when branch result"]; + 21 [label="Exit when"]; } - 20 [label="Exit function test_1" style="filled" fillcolor=red]; + 22 [label="Exit function test_1" style="filled" fillcolor=red]; } 3 -> {4}; @@ -56,156 +58,172 @@ digraph lambdas_kt { 6 -> {7}; 7 -> {8}; 8 -> {10 9}; - 9 -> {19}; + 9 -> {21}; 10 -> {11}; 11 -> {12}; - 12 -> {15 13}; - 13 -> {14}; + 12 -> {13}; + 12 -> {17} [color=red]; + 13 -> {16 14}; 14 -> {15}; - 15 -> {12 16}; - 16 -> {17}; + 15 -> {16}; + 16 -> {13}; + 16 -> {17} [color=green]; 17 -> {18}; 18 -> {19}; 19 -> {20}; + 20 -> {21}; + 21 -> {22}; subgraph cluster_6 { color=red - 21 [label="Enter function test_2" style="filled" fillcolor=red]; + 23 [label="Enter function test_2" style="filled" fillcolor=red]; subgraph cluster_7 { color=blue - 22 [label="Enter when"]; + 24 [label="Enter when"]; subgraph cluster_8 { color=blue - 23 [label="Enter when branch condition "]; - 24 [label="Access variable R|/x|"]; - 25 [label="Type operator: x is Int"]; - 26 [label="Exit when branch condition"]; + 25 [label="Enter when branch condition "]; + 26 [label="Access variable R|/x|"]; + 27 [label="Type operator: x is Int"]; + 28 [label="Exit when branch condition"]; } - 27 [label="Synthetic else branch"]; - 28 [label="Enter when branch result"]; + 29 [label="Synthetic else branch"]; + 30 [label="Enter when branch result"]; subgraph cluster_9 { color=blue - 29 [label="Enter block"]; - 30 [label="Variable declaration: lval lambda: R|() -> kotlin/Int|"]; - 31 [label="Exit block"]; + 31 [label="Enter block"]; + 32 [label="Variable declaration: lval lambda: R|() -> kotlin/Int|"]; + 33 [label="Exit block"]; } - 32 [label="Exit when branch result"]; - 33 [label="Exit when"]; + 34 [label="Exit when branch result"]; + 35 [label="Exit when"]; } - 34 [label="Exit function test_2" style="filled" fillcolor=red]; + 36 [label="Exit function test_2" style="filled" fillcolor=red]; } - 21 -> {22}; - 22 -> {23}; 23 -> {24}; 24 -> {25}; 25 -> {26}; - 26 -> {28 27}; - 27 -> {33}; - 28 -> {29}; - 29 -> {30}; + 26 -> {27}; + 27 -> {28}; + 28 -> {30 29}; + 29 -> {35}; 30 -> {31}; 31 -> {32}; 32 -> {33}; 33 -> {34}; + 34 -> {35}; + 35 -> {36}; subgraph cluster_10 { color=red - 35 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - 36 [label="Access variable R|/x|"]; - 37 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; - 38 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 37 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 38 [label="Access variable R|/x|"]; + 39 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; + 40 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 35 -> {36}; - 36 -> {37}; 37 -> {38}; + 38 -> {39}; + 39 -> {40}; subgraph cluster_11 { color=red - 39 [label="Enter function getInt" style="filled" fillcolor=red]; - 40 [label="Function call: R|/block|.R|FakeOverride|()"]; - 41 [label="Const: Int(1)"]; - 42 [label="Jump: ^getInt Int(1)"]; - 43 [label="Stub" style="filled" fillcolor=gray]; - 44 [label="Exit function getInt" style="filled" fillcolor=red]; + 41 [label="Enter function getInt" style="filled" fillcolor=red]; + 42 [label="Function call: R|/block|.R|FakeOverride|()"]; + 43 [label="Const: Int(1)"]; + 44 [label="Jump: ^getInt Int(1)"]; + 45 [label="Stub" style="filled" fillcolor=gray]; + 46 [label="Exit function getInt" style="filled" fillcolor=red]; } - 39 -> {40}; - 40 -> {41}; 41 -> {42}; - 42 -> {44}; - 42 -> {43} [style=dotted]; - 43 -> {44} [style=dotted]; + 42 -> {43}; + 43 -> {44}; + 44 -> {46}; + 44 -> {45} [style=dotted]; + 45 -> {46} [style=dotted]; subgraph cluster_12 { color=red - 45 [label="Enter function test_3" style="filled" fillcolor=red]; + 47 [label="Enter function test_3" style="filled" fillcolor=red]; + 48 [label="Postponed enter to lambda"]; subgraph cluster_13 { color=blue - 46 [label="Enter function anonymousFunction"]; - 47 [label="Const: Int(1)"]; - 48 [label="Jump: ^test_3 Int(1)"]; - 49 [label="Stub" style="filled" fillcolor=gray]; - 50 [label="Exit function anonymousFunction"]; + 49 [label="Enter function anonymousFunction"]; + 50 [label="Const: Int(1)"]; + 51 [label="Jump: ^test_3 Int(1)"]; + 52 [label="Stub" style="filled" fillcolor=gray]; + 53 [label="Exit function anonymousFunction"]; } - 51 [label="Function call: R|/getInt|( = getInt@fun (): R|kotlin/Unit| { + 54 [label="Postponed exit from lambda"]; + 55 [label="Function call: R|/getInt|( = getInt@fun (): R|kotlin/Unit| { ^test_3 Int(1) } )"]; - 52 [label="Jump: ^test_3 R|/getInt|( = getInt@fun (): R|kotlin/Unit| { + 56 [label="Jump: ^test_3 R|/getInt|( = getInt@fun (): R|kotlin/Unit| { ^test_3 Int(1) } )"]; - 53 [label="Stub" style="filled" fillcolor=gray]; - 54 [label="Exit function test_3" style="filled" fillcolor=red]; + 57 [label="Stub" style="filled" fillcolor=gray]; + 58 [label="Exit function test_3" style="filled" fillcolor=red]; } - 45 -> {46}; - 46 -> {50 47}; 47 -> {48}; - 48 -> {54}; - 48 -> {49} [style=dotted]; - 49 -> {50} [style=dotted]; - 50 -> {46 51}; - 51 -> {52}; - 52 -> {54}; + 48 -> {49}; + 48 -> {54} [color=red]; + 49 -> {53 50}; + 50 -> {51}; + 51 -> {58}; + 51 -> {52} [style=dotted]; 52 -> {53} [style=dotted]; - 53 -> {54} [style=dotted]; + 53 -> {49}; + 53 -> {54} [color=green]; + 54 -> {55}; + 55 -> {56}; + 56 -> {58}; + 56 -> {57} [style=dotted]; + 57 -> {58} [style=dotted]; subgraph cluster_14 { color=red - 55 [label="Enter function test_4" style="filled" fillcolor=red]; + 59 [label="Enter function test_4" style="filled" fillcolor=red]; + 60 [label="Postponed enter to lambda"]; subgraph cluster_15 { color=blue - 56 [label="Enter function anonymousFunction"]; - 57 [label="Const: Int(1)"]; - 58 [label="Jump: ^test_4 Int(1)"]; - 59 [label="Stub" style="filled" fillcolor=gray]; - 60 [label="Exit function anonymousFunction"]; + 61 [label="Enter function anonymousFunction"]; + 62 [label="Const: Int(1)"]; + 63 [label="Jump: ^test_4 Int(1)"]; + 64 [label="Stub" style="filled" fillcolor=gray]; + 65 [label="Exit function anonymousFunction"]; } - 61 [label="Function call: R|/getInt|(block = getInt@fun (): R|kotlin/Unit| { + 66 [label="Postponed exit from lambda"]; + 67 [label="Function call: R|/getInt|(block = getInt@fun (): R|kotlin/Unit| { ^test_4 Int(1) } )"]; - 62 [label="Jump: ^test_4 R|/getInt|(block = getInt@fun (): R|kotlin/Unit| { + 68 [label="Jump: ^test_4 R|/getInt|(block = getInt@fun (): R|kotlin/Unit| { ^test_4 Int(1) } )"]; - 63 [label="Stub" style="filled" fillcolor=gray]; - 64 [label="Exit function test_4" style="filled" fillcolor=red]; + 69 [label="Stub" style="filled" fillcolor=gray]; + 70 [label="Exit function test_4" style="filled" fillcolor=red]; } - 55 -> {56}; - 56 -> {60 57}; - 57 -> {58}; - 58 -> {64}; - 58 -> {59} [style=dotted]; - 59 -> {60} [style=dotted]; - 60 -> {56 61}; - 61 -> {62}; - 62 -> {64}; - 62 -> {63} [style=dotted]; + 59 -> {60}; + 60 -> {61}; + 60 -> {66} [color=red]; + 61 -> {65 62}; + 62 -> {63}; + 63 -> {70}; 63 -> {64} [style=dotted]; + 64 -> {65} [style=dotted]; + 65 -> {61}; + 65 -> {66} [color=green]; + 66 -> {67}; + 67 -> {68}; + 68 -> {70}; + 68 -> {69} [style=dotted]; + 69 -> {70} [style=dotted]; } diff --git a/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.dot b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.dot new file mode 100644 index 00000000000..2ade4f5ec8c --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.dot @@ -0,0 +1,46 @@ +digraph postponedLambdas_kt { + graph [splines=ortho nodesep=3] + node [shape=box penwidth=2] + edge [penwidth=2] + + subgraph cluster_0 { + color=red + 0 [label="Enter function foo" style="filled" fillcolor=red]; + 1 [label="Exit function foo" style="filled" fillcolor=red]; + } + + 0 -> {1}; + + subgraph cluster_1 { + color=red + 2 [label="Enter function test" style="filled" fillcolor=red]; + 3 [label="Access variable R|/a|"]; + 4 [label="Postponed enter to lambda"]; + subgraph cluster_2 { + color=blue + 5 [label="Enter function anonymousFunction"]; + 6 [label="Const: String()"]; + 7 [label="Exit function anonymousFunction"]; + } + 8 [label="Postponed exit from lambda"]; + 9 [label="Access variable R|/b|"]; + 10 [label="Function call: R|/foo|(R|/a|, foo@fun (): R|kotlin/String| { + String() +} +, R|/b|)"]; + 11 [label="Exit function test" style="filled" fillcolor=red]; + } + + 2 -> {3}; + 3 -> {4}; + 4 -> {5}; + 4 -> {8} [color=red]; + 5 -> {7 6}; + 6 -> {7}; + 7 -> {5}; + 7 -> {8} [color=green]; + 8 -> {9}; + 9 -> {10}; + 10 -> {11}; + +} diff --git a/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.kt b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.kt new file mode 100644 index 00000000000..26b6d504551 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.kt @@ -0,0 +1,5 @@ +inline fun foo(vararg x: Any) {} + +fun test(a: Any, b: Any, c: Any) { + foo(a, { "" }, b) +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.txt b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.txt new file mode 100644 index 00000000000..f54736b7076 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.txt @@ -0,0 +1,9 @@ +FILE: postponedLambdas.kt + public final inline fun foo(vararg x: R|kotlin/Array|): R|kotlin/Unit| { + } + public final fun test(a: R|kotlin/Any|, b: R|kotlin/Any|, c: R|kotlin/Any|): R|kotlin/Unit| { + R|/foo|(R|/a|, foo@fun (): R|kotlin/String| { + String() + } + , R|/b|) + } diff --git a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot index 9c80ab0d4b1..fab2014ddc3 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot @@ -118,15 +118,17 @@ digraph propertiesAndInitBlocks_kt { subgraph cluster_10 { color=red 35 [label="Enter property" style="filled" fillcolor=red]; + 36 [label="Postponed enter to lambda"]; subgraph cluster_11 { color=blue - 36 [label="Enter function anonymousFunction"]; - 37 [label="Function call: R|java/lang/Exception.Exception|()"]; - 38 [label="Throw: throw R|java/lang/Exception.Exception|()"]; - 39 [label="Stub" style="filled" fillcolor=gray]; - 40 [label="Exit function anonymousFunction"]; + 37 [label="Enter function anonymousFunction"]; + 38 [label="Function call: R|java/lang/Exception.Exception|()"]; + 39 [label="Throw: throw R|java/lang/Exception.Exception|()"]; + 40 [label="Stub" style="filled" fillcolor=gray]; + 41 [label="Exit function anonymousFunction"]; } - 41 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 42 [label="Postponed exit from lambda"]; + 43 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { local final fun foo(): R|kotlin/Unit| { lval c: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1)) throw R|java/lang/Exception.Exception|() @@ -147,87 +149,91 @@ digraph propertiesAndInitBlocks_kt { throw R|java/lang/Exception.Exception|() } )"]; - 42 [label="Exit property" style="filled" fillcolor=red]; + 44 [label="Exit property" style="filled" fillcolor=red]; } 35 -> {36}; - 36 -> {40 37}; - 37 -> {38}; - 38 -> {42}; - 38 -> {39} [style=dotted]; + 36 -> {37}; + 36 -> {42} [color=red]; + 37 -> {41 38}; + 38 -> {39}; + 39 -> {44}; 39 -> {40} [style=dotted]; - 40 -> {36 41}; - 41 -> {42}; + 40 -> {41} [style=dotted]; + 41 -> {37}; + 41 -> {42} [color=green]; + 42 -> {43}; + 43 -> {44}; subgraph cluster_12 { color=red - 43 [label="Enter function getter" style="filled" fillcolor=red]; - 44 [label="Exit function getter" style="filled" fillcolor=red]; - } - - 43 -> {44}; - - subgraph cluster_13 { - color=red - 45 [label="Enter property" style="filled" fillcolor=red]; - subgraph cluster_14 { - color=blue - 46 [label="Try expression enter"]; - subgraph cluster_15 { - color=blue - 47 [label="Try main block enter"]; - subgraph cluster_16 { - color=blue - 48 [label="Enter block"]; - 49 [label="Const: Int(1)"]; - 50 [label="Exit block"]; - } - 51 [label="Try main block exit"]; - } - subgraph cluster_17 { - color=blue - 52 [label="Enter finally"]; - subgraph cluster_18 { - color=blue - 53 [label="Enter block"]; - 54 [label="Const: IntegerLiteral(0)"]; - 55 [label="Exit block"]; - } - 56 [label="Exit finally"]; - } - subgraph cluster_19 { - color=blue - 57 [label="Catch enter"]; - subgraph cluster_20 { - color=blue - 58 [label="Enter block"]; - 59 [label="Const: Int(2)"]; - 60 [label="Exit block"]; - } - 61 [label="Catch exit"]; - } - 62 [label="Try expression exit"]; - } - 63 [label="Exit property" style="filled" fillcolor=red]; + 45 [label="Enter function getter" style="filled" fillcolor=red]; + 46 [label="Exit function getter" style="filled" fillcolor=red]; } 45 -> {46}; - 46 -> {47}; - 47 -> {63 57 52 48}; + + subgraph cluster_13 { + color=red + 47 [label="Enter property" style="filled" fillcolor=red]; + subgraph cluster_14 { + color=blue + 48 [label="Try expression enter"]; + subgraph cluster_15 { + color=blue + 49 [label="Try main block enter"]; + subgraph cluster_16 { + color=blue + 50 [label="Enter block"]; + 51 [label="Const: Int(1)"]; + 52 [label="Exit block"]; + } + 53 [label="Try main block exit"]; + } + subgraph cluster_17 { + color=blue + 54 [label="Enter finally"]; + subgraph cluster_18 { + color=blue + 55 [label="Enter block"]; + 56 [label="Const: IntegerLiteral(0)"]; + 57 [label="Exit block"]; + } + 58 [label="Exit finally"]; + } + subgraph cluster_19 { + color=blue + 59 [label="Catch enter"]; + subgraph cluster_20 { + color=blue + 60 [label="Enter block"]; + 61 [label="Const: Int(2)"]; + 62 [label="Exit block"]; + } + 63 [label="Catch exit"]; + } + 64 [label="Try expression exit"]; + } + 65 [label="Exit property" style="filled" fillcolor=red]; + } + + 47 -> {48}; 48 -> {49}; - 49 -> {50}; + 49 -> {65 59 54 50}; 50 -> {51}; - 51 -> {62}; + 51 -> {52}; 52 -> {53}; - 53 -> {54}; + 53 -> {64}; 54 -> {55}; 55 -> {56}; - 56 -> {62}; - 57 -> {63 58}; - 58 -> {59}; - 59 -> {60}; + 56 -> {57}; + 57 -> {58}; + 58 -> {64}; + 59 -> {65 60}; 60 -> {61}; 61 -> {62}; 62 -> {63}; + 63 -> {64}; + 64 -> {65}; } diff --git a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot index 47b4b16de62..e01c73981f5 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot @@ -22,35 +22,37 @@ digraph returnValuesFromLambda_kt { subgraph cluster_2 { color=red 4 [label="Enter function test_1" style="filled" fillcolor=red]; + 5 [label="Postponed enter to lambda"]; subgraph cluster_3 { color=blue - 5 [label="Enter function anonymousFunction"]; + 6 [label="Enter function anonymousFunction"]; subgraph cluster_4 { color=blue - 6 [label="Enter when"]; + 7 [label="Enter when"]; subgraph cluster_5 { color=blue - 7 [label="Enter when branch condition "]; - 8 [label="Access variable R|/b|"]; - 9 [label="Exit when branch condition"]; + 8 [label="Enter when branch condition "]; + 9 [label="Access variable R|/b|"]; + 10 [label="Exit when branch condition"]; } - 10 [label="Synthetic else branch"]; - 11 [label="Enter when branch result"]; + 11 [label="Synthetic else branch"]; + 12 [label="Enter when branch result"]; subgraph cluster_6 { color=blue - 12 [label="Enter block"]; - 13 [label="Function call: R|/B.B|()"]; - 14 [label="Jump: ^@run R|/B.B|()"]; - 15 [label="Stub" style="filled" fillcolor=gray]; - 16 [label="Exit block" style="filled" fillcolor=gray]; + 13 [label="Enter block"]; + 14 [label="Function call: R|/B.B|()"]; + 15 [label="Jump: ^@run R|/B.B|()"]; + 16 [label="Stub" style="filled" fillcolor=gray]; + 17 [label="Exit block" style="filled" fillcolor=gray]; } - 17 [label="Exit when branch result" style="filled" fillcolor=gray]; - 18 [label="Exit when"]; + 18 [label="Exit when branch result" style="filled" fillcolor=gray]; + 19 [label="Exit when"]; } - 19 [label="Function call: R|/C.C|()"]; - 20 [label="Exit function anonymousFunction"]; + 20 [label="Function call: R|/C.C|()"]; + 21 [label="Exit function anonymousFunction"]; } - 21 [label="Function call: R|kotlin/run|( = run@fun (): R|A| { + 22 [label="Postponed exit from lambda"]; + 23 [label="Function call: R|kotlin/run|( = run@fun (): R|A| { when () { R|/b| -> { ^@run R|/B.B|() @@ -60,87 +62,101 @@ digraph returnValuesFromLambda_kt { R|/C.C|() } )"]; - 22 [label="Variable declaration: lval x: R|A|"]; - 23 [label="Exit function test_1" style="filled" fillcolor=red]; + 24 [label="Variable declaration: lval x: R|A|"]; + 25 [label="Exit function test_1" style="filled" fillcolor=red]; } 4 -> {5}; 5 -> {6}; + 5 -> {22} [color=red]; 6 -> {7}; 7 -> {8}; 8 -> {9}; - 9 -> {11 10}; - 10 -> {18}; - 11 -> {12}; + 9 -> {10}; + 10 -> {12 11}; + 11 -> {19}; 12 -> {13}; 13 -> {14}; - 14 -> {20}; - 14 -> {15} [style=dotted]; + 14 -> {15}; + 15 -> {21}; 15 -> {16} [style=dotted]; 16 -> {17} [style=dotted]; 17 -> {18} [style=dotted]; - 18 -> {19}; + 18 -> {19} [style=dotted]; 19 -> {20}; 20 -> {21}; - 21 -> {22}; + 21 -> {22} [color=green]; 22 -> {23}; + 23 -> {24}; + 24 -> {25}; subgraph cluster_7 { color=red - 24 [label="Enter function test_2" style="filled" fillcolor=red]; + 26 [label="Enter function test_2" style="filled" fillcolor=red]; + 27 [label="Postponed enter to lambda"]; subgraph cluster_8 { color=blue - 25 [label="Enter function anonymousFunction"]; - 26 [label="Function call: R|/C.C|()"]; - 27 [label="Jump: ^@run R|/C.C|()"]; - 28 [label="Stub" style="filled" fillcolor=gray]; - 29 [label="Exit function anonymousFunction"]; + 28 [label="Enter function anonymousFunction"]; + 29 [label="Function call: R|/C.C|()"]; + 30 [label="Jump: ^@run R|/C.C|()"]; + 31 [label="Stub" style="filled" fillcolor=gray]; + 32 [label="Exit function anonymousFunction"]; } - 30 [label="Function call: R|kotlin/run|( = run@fun (): R|C| { + 33 [label="Postponed exit from lambda"]; + 34 [label="Function call: R|kotlin/run|( = run@fun (): R|C| { ^@run R|/C.C|() } )"]; - 31 [label="Variable declaration: lval x: R|C|"]; - 32 [label="Exit function test_2" style="filled" fillcolor=red]; + 35 [label="Variable declaration: lval x: R|C|"]; + 36 [label="Exit function test_2" style="filled" fillcolor=red]; } - 24 -> {25}; - 25 -> {26}; 26 -> {27}; - 27 -> {29}; - 27 -> {28} [style=dotted]; - 28 -> {29} [style=dotted]; + 27 -> {28}; + 27 -> {33} [color=red]; + 28 -> {29}; 29 -> {30}; - 30 -> {31}; - 31 -> {32}; + 30 -> {32}; + 30 -> {31} [style=dotted]; + 31 -> {32} [style=dotted]; + 32 -> {33} [color=green]; + 33 -> {34}; + 34 -> {35}; + 35 -> {36}; subgraph cluster_9 { color=red - 33 [label="Enter function test_3" style="filled" fillcolor=red]; + 37 [label="Enter function test_3" style="filled" fillcolor=red]; + 38 [label="Postponed enter to lambda"]; subgraph cluster_10 { color=blue - 34 [label="Enter function anonymousFunction"]; - 35 [label="Jump: ^test_3 Unit"]; - 36 [label="Stub" style="filled" fillcolor=gray]; - 37 [label="Exit function anonymousFunction" style="filled" fillcolor=gray]; + 39 [label="Enter function anonymousFunction"]; + 40 [label="Jump: ^test_3 Unit"]; + 41 [label="Stub" style="filled" fillcolor=gray]; + 42 [label="Exit function anonymousFunction" style="filled" fillcolor=gray]; } - 38 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Nothing| { + 43 [label="Postponed exit from lambda"]; + 44 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Nothing| { ^test_3 Unit } -)" style="filled" fillcolor=gray]; - 39 [label="Stub" style="filled" fillcolor=gray]; - 40 [label="Variable declaration: lval x: R|kotlin/Nothing|" style="filled" fillcolor=gray]; - 41 [label="Exit function test_3" style="filled" fillcolor=red]; +)"]; + 45 [label="Stub" style="filled" fillcolor=gray]; + 46 [label="Variable declaration: lval x: R|kotlin/Nothing|" style="filled" fillcolor=gray]; + 47 [label="Exit function test_3" style="filled" fillcolor=red]; } - 33 -> {34}; - 34 -> {35}; - 35 -> {41}; - 35 -> {36} [style=dotted]; - 36 -> {37} [style=dotted]; - 37 -> {38} [style=dotted]; - 38 -> {41 39} [style=dotted]; - 39 -> {40} [style=dotted]; + 37 -> {38}; + 38 -> {39}; + 38 -> {43} [color=red]; + 39 -> {40}; + 40 -> {47}; 40 -> {41} [style=dotted]; + 41 -> {42} [style=dotted]; + 42 -> {43} [color=green]; + 43 -> {44}; + 44 -> {47}; + 44 -> {45} [style=dotted]; + 45 -> {46} [style=dotted]; + 46 -> {47} [style=dotted]; } diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/implicitReceivers.dot b/compiler/fir/resolve/testData/resolve/smartcasts/implicitReceivers.dot index 95c3e106478..1f4c23bd9d0 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/implicitReceivers.dot +++ b/compiler/fir/resolve/testData/resolve/smartcasts/implicitReceivers.dot @@ -193,36 +193,41 @@ digraph implicitReceivers_kt { color=red 64 [label="Enter function test_3" style="filled" fillcolor=red]; 65 [label="Access variable R|/a|"]; + 66 [label="Postponed enter to lambda"]; subgraph cluster_18 { color=blue - 66 [label="Enter function anonymousFunction"]; - 67 [label="Access variable R|/b|"]; + 67 [label="Enter function anonymousFunction"]; + 68 [label="Access variable R|/b|"]; + 69 [label="Postponed enter to lambda"]; subgraph cluster_19 { color=blue - 68 [label="Enter function anonymousFunction"]; - 69 [label="Access variable R|/c|"]; + 70 [label="Enter function anonymousFunction"]; + 71 [label="Access variable R|/c|"]; + 72 [label="Postponed enter to lambda"]; subgraph cluster_20 { color=blue - 70 [label="Enter function anonymousFunction"]; - 71 [label="Access variable this@R|special/anonymous|"]; - 72 [label="Type operator: this@wb as A"]; - 73 [label="Access variable this@R|special/anonymous|"]; - 74 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; - 75 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; - 76 [label="Exit function anonymousFunction"]; + 73 [label="Enter function anonymousFunction"]; + 74 [label="Access variable this@R|special/anonymous|"]; + 75 [label="Type operator: this@wb as A"]; + 76 [label="Access variable this@R|special/anonymous|"]; + 77 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; + 78 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; + 79 [label="Exit function anonymousFunction"]; } - 77 [label="Function call: R|kotlin/with|(R|/c|, = wc@fun R|kotlin/Any|.(): R|kotlin/Unit| { + 80 [label="Postponed exit from lambda"]; + 81 [label="Function call: R|kotlin/with|(R|/c|, = wc@fun R|kotlin/Any|.(): R|kotlin/Unit| { (this@R|special/anonymous| as R|A|) this@R|special/anonymous|.R|/A.foo|() this@R|special/anonymous|.R|/A.foo|() } )"]; - 78 [label="Access variable this@R|special/anonymous|"]; - 79 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; - 80 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; - 81 [label="Exit function anonymousFunction"]; + 82 [label="Access variable this@R|special/anonymous|"]; + 83 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; + 84 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"]; + 85 [label="Exit function anonymousFunction"]; } - 82 [label="Function call: R|kotlin/with|(R|/b|, = wb@fun R|kotlin/Any|.(): R|kotlin/Unit| { + 86 [label="Postponed exit from lambda"]; + 87 [label="Function call: R|kotlin/with|(R|/b|, = wb@fun R|kotlin/Any|.(): R|kotlin/Unit| { R|kotlin/with|(R|/c|, = wc@fun R|kotlin/Any|.(): R|kotlin/Unit| { (this@R|special/anonymous| as R|A|) this@R|special/anonymous|.R|/A.foo|() @@ -233,9 +238,10 @@ digraph implicitReceivers_kt { this@R|special/anonymous|.R|/A.foo|() } )"]; - 83 [label="Exit function anonymousFunction"]; + 88 [label="Exit function anonymousFunction"]; } - 84 [label="Function call: R|kotlin/with|(R|/a|, = wa@fun R|kotlin/Any|.(): R|kotlin/Unit| { + 89 [label="Postponed exit from lambda"]; + 90 [label="Function call: R|kotlin/with|(R|/a|, = wa@fun R|kotlin/Any|.(): R|kotlin/Unit| { R|kotlin/with|(R|/b|, = wb@fun R|kotlin/Any|.(): R|kotlin/Unit| { R|kotlin/with|(R|/c|, = wc@fun R|kotlin/Any|.(): R|kotlin/Unit| { (this@R|special/anonymous| as R|A|) @@ -249,169 +255,172 @@ digraph implicitReceivers_kt { ) } )"]; - 85 [label="Exit function test_3" style="filled" fillcolor=red]; + 91 [label="Exit function test_3" style="filled" fillcolor=red]; } 64 -> {65}; 65 -> {66}; 66 -> {67}; + 66 -> {89} [color=red]; 67 -> {68}; 68 -> {69}; 69 -> {70}; + 69 -> {86} [color=red]; 70 -> {71}; 71 -> {72}; 72 -> {73}; + 72 -> {80} [color=red]; 73 -> {74}; 74 -> {75}; 75 -> {76}; 76 -> {77}; 77 -> {78}; 78 -> {79}; - 79 -> {80}; + 79 -> {80} [color=green]; 80 -> {81}; 81 -> {82}; 82 -> {83}; 83 -> {84}; 84 -> {85}; + 85 -> {86} [color=green]; + 86 -> {87}; + 87 -> {88}; + 88 -> {89} [color=green]; + 89 -> {90}; + 90 -> {91}; subgraph cluster_21 { color=red - 86 [label="Enter function test_4" style="filled" fillcolor=red]; + 92 [label="Enter function test_4" style="filled" fillcolor=red]; subgraph cluster_22 { color=blue - 87 [label="Enter when"]; + 93 [label="Enter when"]; subgraph cluster_23 { color=blue - 88 [label="Enter when branch condition "]; - 89 [label="Access variable this@R|/test_4|"]; - 90 [label="Type operator: this !is A"]; - 91 [label="Exit when branch condition"]; + 94 [label="Enter when branch condition "]; + 95 [label="Access variable this@R|/test_4|"]; + 96 [label="Type operator: this !is A"]; + 97 [label="Exit when branch condition"]; } subgraph cluster_24 { color=blue - 92 [label="Enter when branch condition else"]; - 93 [label="Exit when branch condition"]; + 98 [label="Enter when branch condition else"]; + 99 [label="Exit when branch condition"]; } - 94 [label="Enter when branch result"]; + 100 [label="Enter when branch result"]; subgraph cluster_25 { color=blue - 95 [label="Enter block"]; + 101 [label="Enter block"]; subgraph cluster_26 { color=blue - 96 [label="Enter when"]; + 102 [label="Enter when"]; subgraph cluster_27 { color=blue - 97 [label="Enter when branch condition "]; - 98 [label="Access variable this@R|/test_4|"]; - 99 [label="Type operator: this !is B"]; - 100 [label="Exit when branch condition"]; + 103 [label="Enter when branch condition "]; + 104 [label="Access variable this@R|/test_4|"]; + 105 [label="Type operator: this !is B"]; + 106 [label="Exit when branch condition"]; } subgraph cluster_28 { color=blue - 101 [label="Enter when branch condition else"]; - 102 [label="Exit when branch condition"]; + 107 [label="Enter when branch condition else"]; + 108 [label="Exit when branch condition"]; } - 103 [label="Enter when branch result"]; + 109 [label="Enter when branch result"]; subgraph cluster_29 { color=blue - 104 [label="Enter block"]; - 105 [label="Access variable this@R|/test_4|"]; - 106 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; - 107 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; - 108 [label="Access variable this@R|/test_4|"]; - 109 [label="Function call: this@R|/test_4|.R|/B.bar|()"]; - 110 [label="Function call: this@R|/test_4|.R|/B.bar|()"]; - 111 [label="Exit block"]; + 110 [label="Enter block"]; + 111 [label="Access variable this@R|/test_4|"]; + 112 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; + 113 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; + 114 [label="Access variable this@R|/test_4|"]; + 115 [label="Function call: this@R|/test_4|.R|/B.bar|()"]; + 116 [label="Function call: this@R|/test_4|.R|/B.bar|()"]; + 117 [label="Exit block"]; } - 112 [label="Exit when branch result"]; - 113 [label="Enter when branch result"]; + 118 [label="Exit when branch result"]; + 119 [label="Enter when branch result"]; subgraph cluster_30 { color=blue - 114 [label="Enter block"]; - 115 [label="Access variable this@R|/test_4|"]; - 116 [label="Function call: this@R|/test_4|.#()"]; - 117 [label="Function call: #()"]; - 118 [label="Access variable this@R|/test_4|"]; - 119 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; - 120 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; - 121 [label="Exit block"]; + 120 [label="Enter block"]; + 121 [label="Access variable this@R|/test_4|"]; + 122 [label="Function call: this@R|/test_4|.#()"]; + 123 [label="Function call: #()"]; + 124 [label="Access variable this@R|/test_4|"]; + 125 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; + 126 [label="Function call: this@R|/test_4|.R|/A.foo|()"]; + 127 [label="Exit block"]; } - 122 [label="Exit when branch result"]; - 123 [label="Exit when"]; + 128 [label="Exit when branch result"]; + 129 [label="Exit when"]; } - 124 [label="Exit block"]; + 130 [label="Exit block"]; } - 125 [label="Exit when branch result"]; - 126 [label="Enter when branch result"]; + 131 [label="Exit when branch result"]; + 132 [label="Enter when branch result"]; subgraph cluster_31 { color=blue - 127 [label="Enter block"]; - 128 [label="Access variable this@R|/test_4|"]; - 129 [label="Function call: this@R|/test_4|.#()"]; - 130 [label="Function call: #()"]; - 131 [label="Access variable this@R|/test_4|"]; - 132 [label="Function call: this@R|/test_4|.#()"]; - 133 [label="Function call: #()"]; - 134 [label="Exit block"]; + 133 [label="Enter block"]; + 134 [label="Access variable this@R|/test_4|"]; + 135 [label="Function call: this@R|/test_4|.#()"]; + 136 [label="Function call: #()"]; + 137 [label="Access variable this@R|/test_4|"]; + 138 [label="Function call: this@R|/test_4|.#()"]; + 139 [label="Function call: #()"]; + 140 [label="Exit block"]; } - 135 [label="Exit when branch result"]; - 136 [label="Exit when"]; + 141 [label="Exit when branch result"]; + 142 [label="Exit when"]; } - 137 [label="Access variable this@R|/test_4|"]; - 138 [label="Function call: this@R|/test_4|.#()"]; - 139 [label="Function call: #()"]; - 140 [label="Access variable this@R|/test_4|"]; - 141 [label="Function call: this@R|/test_4|.#()"]; - 142 [label="Function call: #()"]; - 143 [label="Exit function test_4" style="filled" fillcolor=red]; + 143 [label="Access variable this@R|/test_4|"]; + 144 [label="Function call: this@R|/test_4|.#()"]; + 145 [label="Function call: #()"]; + 146 [label="Access variable this@R|/test_4|"]; + 147 [label="Function call: this@R|/test_4|.#()"]; + 148 [label="Function call: #()"]; + 149 [label="Exit function test_4" style="filled" fillcolor=red]; } - 86 -> {87}; - 87 -> {88}; - 88 -> {89}; - 89 -> {90}; - 90 -> {91}; - 91 -> {126 92}; 92 -> {93}; 93 -> {94}; 94 -> {95}; 95 -> {96}; 96 -> {97}; - 97 -> {98}; + 97 -> {132 98}; 98 -> {99}; 99 -> {100}; - 100 -> {113 101}; + 100 -> {101}; 101 -> {102}; 102 -> {103}; 103 -> {104}; 104 -> {105}; 105 -> {106}; - 106 -> {107}; + 106 -> {119 107}; 107 -> {108}; 108 -> {109}; 109 -> {110}; 110 -> {111}; 111 -> {112}; - 112 -> {123}; + 112 -> {113}; 113 -> {114}; 114 -> {115}; 115 -> {116}; 116 -> {117}; 117 -> {118}; - 118 -> {119}; + 118 -> {129}; 119 -> {120}; 120 -> {121}; 121 -> {122}; 122 -> {123}; 123 -> {124}; 124 -> {125}; - 125 -> {136}; + 125 -> {126}; 126 -> {127}; 127 -> {128}; 128 -> {129}; 129 -> {130}; 130 -> {131}; - 131 -> {132}; + 131 -> {142}; 132 -> {133}; 133 -> {134}; 134 -> {135}; @@ -423,59 +432,65 @@ digraph implicitReceivers_kt { 140 -> {141}; 141 -> {142}; 142 -> {143}; + 143 -> {144}; + 144 -> {145}; + 145 -> {146}; + 146 -> {147}; + 147 -> {148}; + 148 -> {149}; subgraph cluster_32 { color=red - 144 [label="Enter function test_5" style="filled" fillcolor=red]; + 150 [label="Enter function test_5" style="filled" fillcolor=red]; subgraph cluster_33 { color=blue - 145 [label="Enter when"]; + 151 [label="Enter when"]; subgraph cluster_34 { color=blue - 146 [label="Enter when branch condition "]; - 147 [label="Access variable this@R|/test_5|"]; - 148 [label="Type operator: this is List<*>"]; - 149 [label="Exit when branch condition"]; + 152 [label="Enter when branch condition "]; + 153 [label="Access variable this@R|/test_5|"]; + 154 [label="Type operator: this is List<*>"]; + 155 [label="Exit when branch condition"]; } subgraph cluster_35 { color=blue - 150 [label="Enter when branch condition "]; - 151 [label="Access variable this@R|/test_5|"]; - 152 [label="Type operator: this is String"]; - 153 [label="Exit when branch condition"]; + 156 [label="Enter when branch condition "]; + 157 [label="Access variable this@R|/test_5|"]; + 158 [label="Type operator: this is String"]; + 159 [label="Exit when branch condition"]; } subgraph cluster_36 { color=blue - 154 [label="Enter when branch condition else"]; - 155 [label="Exit when branch condition"]; + 160 [label="Enter when branch condition else"]; + 161 [label="Exit when branch condition"]; } - 156 [label="Enter when branch result"]; + 162 [label="Enter when branch result"]; subgraph cluster_37 { color=blue - 157 [label="Enter block"]; - 158 [label="Const: Int(0)"]; - 159 [label="Exit block"]; + 163 [label="Enter block"]; + 164 [label="Const: Int(0)"]; + 165 [label="Exit block"]; } - 160 [label="Exit when branch result"]; - 161 [label="Enter when branch result"]; + 166 [label="Exit when branch result"]; + 167 [label="Enter when branch result"]; subgraph cluster_38 { color=blue - 162 [label="Enter block"]; - 163 [label="Access variable R|kotlin/String.length|"]; - 164 [label="Exit block"]; + 168 [label="Enter block"]; + 169 [label="Access variable R|kotlin/String.length|"]; + 170 [label="Exit block"]; } - 165 [label="Exit when branch result"]; - 166 [label="Enter when branch result"]; + 171 [label="Exit when branch result"]; + 172 [label="Enter when branch result"]; subgraph cluster_39 { color=blue - 167 [label="Enter block"]; - 168 [label="Access variable R|kotlin/collections/List.size|"]; - 169 [label="Exit block"]; + 173 [label="Enter block"]; + 174 [label="Access variable R|kotlin/collections/List.size|"]; + 175 [label="Exit block"]; } - 170 [label="Exit when branch result"]; - 171 [label="Exit when"]; + 176 [label="Exit when branch result"]; + 177 [label="Exit when"]; } - 172 [label="Jump: ^test_5 when () { + 178 [label="Jump: ^test_5 when () { (this@R|/test_5| is R|kotlin/collections/List<*>|) -> { this@R|/test_5|.R|kotlin/collections/List.size| } @@ -487,60 +502,60 @@ digraph implicitReceivers_kt { } } "]; - 173 [label="Stub" style="filled" fillcolor=gray]; - 174 [label="Exit function test_5" style="filled" fillcolor=red]; + 179 [label="Stub" style="filled" fillcolor=gray]; + 180 [label="Exit function test_5" style="filled" fillcolor=red]; } - 144 -> {145}; - 145 -> {146}; - 146 -> {147}; - 147 -> {148}; - 148 -> {149}; - 149 -> {166 150}; 150 -> {151}; 151 -> {152}; 152 -> {153}; - 153 -> {161 154}; + 153 -> {154}; 154 -> {155}; - 155 -> {156}; + 155 -> {172 156}; 156 -> {157}; 157 -> {158}; 158 -> {159}; - 159 -> {160}; - 160 -> {171}; + 159 -> {167 160}; + 160 -> {161}; 161 -> {162}; 162 -> {163}; 163 -> {164}; 164 -> {165}; - 165 -> {171}; - 166 -> {167}; + 165 -> {166}; + 166 -> {177}; 167 -> {168}; 168 -> {169}; 169 -> {170}; 170 -> {171}; - 171 -> {172}; - 172 -> {174}; - 172 -> {173} [style=dotted]; - 173 -> {174} [style=dotted]; - - subgraph cluster_40 { - color=red - 175 [label="Enter function test_6" style="filled" fillcolor=red]; - 176 [label="Access variable this@R|/test_6|"]; - 177 [label="Type operator: this as List<*>"]; - 178 [label="Access variable R|kotlin/collections/List.size|"]; - 179 [label="Access variable this@R|/test_6|"]; - 180 [label="Type operator: this as String"]; - 181 [label="Access variable R|kotlin/String.length|"]; - 182 [label="Exit function test_6" style="filled" fillcolor=red]; - } - + 171 -> {177}; + 172 -> {173}; + 173 -> {174}; + 174 -> {175}; 175 -> {176}; 176 -> {177}; 177 -> {178}; - 178 -> {179}; - 179 -> {180}; - 180 -> {181}; + 178 -> {180}; + 178 -> {179} [style=dotted]; + 179 -> {180} [style=dotted]; + + subgraph cluster_40 { + color=red + 181 [label="Enter function test_6" style="filled" fillcolor=red]; + 182 [label="Access variable this@R|/test_6|"]; + 183 [label="Type operator: this as List<*>"]; + 184 [label="Access variable R|kotlin/collections/List.size|"]; + 185 [label="Access variable this@R|/test_6|"]; + 186 [label="Type operator: this as String"]; + 187 [label="Access variable R|kotlin/String.length|"]; + 188 [label="Exit function test_6" style="filled" fillcolor=red]; + } + 181 -> {182}; + 182 -> {183}; + 183 -> {184}; + 184 -> {185}; + 185 -> {186}; + 186 -> {187}; + 187 -> {188}; } diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/inPlaceLambdas.dot b/compiler/fir/resolve/testData/resolve/smartcasts/inPlaceLambdas.dot index 03b412c9035..cfb6f147803 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/inPlaceLambdas.dot +++ b/compiler/fir/resolve/testData/resolve/smartcasts/inPlaceLambdas.dot @@ -47,23 +47,25 @@ digraph inPlaceLambdas_kt { subgraph cluster_6 { color=blue 15 [label="Enter block"]; + 16 [label="Postponed enter to lambda"]; subgraph cluster_7 { color=blue - 16 [label="Enter function anonymousFunction"]; - 17 [label="Access variable R|/x|"]; - 18 [label="Function call: R|/x|.R|/A.foo|()"]; - 19 [label="Exit function anonymousFunction"]; + 17 [label="Enter function anonymousFunction"]; + 18 [label="Access variable R|/x|"]; + 19 [label="Function call: R|/x|.R|/A.foo|()"]; + 20 [label="Exit function anonymousFunction"]; } - 20 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 21 [label="Postponed exit from lambda"]; + 22 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { R|/x|.R|/A.foo|() } )"]; - 21 [label="Exit block"]; + 23 [label="Exit block"]; } - 22 [label="Exit when branch result"]; - 23 [label="Exit when"]; + 24 [label="Exit when branch result"]; + 25 [label="Exit when"]; } - 24 [label="Exit function test_1" style="filled" fillcolor=red]; + 26 [label="Exit function test_1" style="filled" fillcolor=red]; } 7 -> {8}; @@ -72,108 +74,124 @@ digraph inPlaceLambdas_kt { 10 -> {11}; 11 -> {12}; 12 -> {14 13}; - 13 -> {23}; + 13 -> {25}; 14 -> {15}; 15 -> {16}; - 16 -> {19 17}; - 17 -> {18}; + 16 -> {17}; + 16 -> {21} [color=red]; + 17 -> {20 18}; 18 -> {19}; - 19 -> {16 20}; - 20 -> {21}; + 19 -> {20}; + 20 -> {17}; + 20 -> {21} [color=green]; 21 -> {22}; 22 -> {23}; 23 -> {24}; + 24 -> {25}; + 25 -> {26}; subgraph cluster_8 { color=red - 25 [label="Enter function test_2" style="filled" fillcolor=red]; + 27 [label="Enter function test_2" style="filled" fillcolor=red]; + 28 [label="Postponed enter to lambda"]; subgraph cluster_9 { color=blue - 26 [label="Enter function anonymousFunction"]; - 27 [label="Access variable R|/x|"]; - 28 [label="Type operator: x as B"]; - 29 [label="Exit function anonymousFunction"]; + 29 [label="Enter function anonymousFunction"]; + 30 [label="Access variable R|/x|"]; + 31 [label="Type operator: x as B"]; + 32 [label="Exit function anonymousFunction"]; } - 30 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 33 [label="Postponed exit from lambda"]; + 34 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { (R|/x| as R|B|) } )"]; - 31 [label="Access variable R|/x|"]; - 32 [label="Function call: R|/x|.R|/B.bar|()"]; - 33 [label="Exit function test_2" style="filled" fillcolor=red]; + 35 [label="Access variable R|/x|"]; + 36 [label="Function call: R|/x|.R|/B.bar|()"]; + 37 [label="Exit function test_2" style="filled" fillcolor=red]; } - 25 -> {26}; - 26 -> {29 27}; 27 -> {28}; 28 -> {29}; - 29 -> {26 30}; + 28 -> {33} [color=red]; + 29 -> {32 30}; 30 -> {31}; 31 -> {32}; - 32 -> {33}; + 32 -> {29}; + 32 -> {33} [color=green]; + 33 -> {34}; + 34 -> {35}; + 35 -> {36}; + 36 -> {37}; subgraph cluster_10 { color=red - 34 [label="Enter function test_3" style="filled" fillcolor=red]; + 38 [label="Enter function test_3" style="filled" fillcolor=red]; subgraph cluster_11 { color=blue - 35 [label="Enter when"]; + 39 [label="Enter when"]; subgraph cluster_12 { color=blue - 36 [label="Enter when branch condition "]; - 37 [label="Access variable R|/x|"]; - 38 [label="Type operator: x is A"]; - 39 [label="Exit when branch condition"]; + 40 [label="Enter when branch condition "]; + 41 [label="Access variable R|/x|"]; + 42 [label="Type operator: x is A"]; + 43 [label="Exit when branch condition"]; } - 40 [label="Synthetic else branch"]; - 41 [label="Enter when branch result"]; + 44 [label="Synthetic else branch"]; + 45 [label="Enter when branch result"]; subgraph cluster_13 { color=blue - 42 [label="Enter block"]; + 46 [label="Enter block"]; + 47 [label="Postponed enter to lambda"]; subgraph cluster_14 { color=blue - 43 [label="Enter function anonymousFunction"]; - 44 [label="Access variable R|/x|"]; - 45 [label="Function call: R|/x|.R|/A.foo|()"]; - 46 [label="Access variable R|/x|"]; - 47 [label="Type operator: x as B"]; - 48 [label="Exit function anonymousFunction"]; + 48 [label="Enter function anonymousFunction"]; + 49 [label="Access variable R|/x|"]; + 50 [label="Function call: R|/x|.R|/A.foo|()"]; + 51 [label="Access variable R|/x|"]; + 52 [label="Type operator: x as B"]; + 53 [label="Exit function anonymousFunction"]; } - 49 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { + 54 [label="Postponed exit from lambda"]; + 55 [label="Function call: R|/run|( = run@fun (): R|kotlin/Unit| { R|/x|.R|/A.foo|() (R|/x| as R|B|) } )"]; - 50 [label="Access variable R|/x|"]; - 51 [label="Function call: R|/x|.R|/B.bar|()"]; - 52 [label="Exit block"]; + 56 [label="Access variable R|/x|"]; + 57 [label="Function call: R|/x|.R|/B.bar|()"]; + 58 [label="Exit block"]; } - 53 [label="Exit when branch result"]; - 54 [label="Exit when"]; + 59 [label="Exit when branch result"]; + 60 [label="Exit when"]; } - 55 [label="Exit function test_3" style="filled" fillcolor=red]; + 61 [label="Exit function test_3" style="filled" fillcolor=red]; } - 34 -> {35}; - 35 -> {36}; - 36 -> {37}; - 37 -> {38}; 38 -> {39}; - 39 -> {41 40}; - 40 -> {54}; + 39 -> {40}; + 40 -> {41}; 41 -> {42}; 42 -> {43}; - 43 -> {48 44}; - 44 -> {45}; + 43 -> {45 44}; + 44 -> {60}; 45 -> {46}; 46 -> {47}; 47 -> {48}; - 48 -> {43 49}; + 47 -> {54} [color=red]; + 48 -> {53 49}; 49 -> {50}; 50 -> {51}; 51 -> {52}; 52 -> {53}; - 53 -> {54}; + 53 -> {48}; + 53 -> {54} [color=green]; 54 -> {55}; + 55 -> {56}; + 56 -> {57}; + 57 -> {58}; + 58 -> {59}; + 59 -> {60}; + 60 -> {61}; } diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot index 90524b55e2a..3ffb6585279 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot +++ b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot @@ -113,14 +113,16 @@ digraph safeCalls_kt { 43 [label="Function call: (R|/x| as? R|A|)?.R|/A.bar|(R|/x|)?.R|/foo|(R|/x|.R|/A.bool|())"]; 44 [label="Exit safe call"]; 45 [label="Enter safe call"]; - 46 [label="Function call: (R|/x| as? R|A|)?.R|/A.bar|(R|/x|)?.R|/foo|(R|/x|.R|/A.bool|())?.R|/let|( = let@fun (): R|kotlin/Unit| { + 46 [label="Postponed enter to lambda"]; + 47 [label="Postponed exit from lambda"]; + 48 [label="Function call: (R|/x| as? R|A|)?.R|/A.bar|(R|/x|)?.R|/foo|(R|/x|.R|/A.bool|())?.R|/let|( = let@fun (): R|kotlin/Unit| { R|/x|.R|/A.bool|() } )"]; - 47 [label="Exit safe call"]; - 48 [label="Access variable R|/x|"]; - 49 [label="Function call: R|/x|.#()"]; - 50 [label="Exit function test_3" style="filled" fillcolor=red]; + 49 [label="Exit safe call"]; + 50 [label="Access variable R|/x|"]; + 51 [label="Function call: R|/x|.#()"]; + 52 [label="Exit function test_3" style="filled" fillcolor=red]; } 33 -> {34}; @@ -134,105 +136,112 @@ digraph safeCalls_kt { 41 -> {42}; 42 -> {43}; 43 -> {44}; - 44 -> {45 47}; + 44 -> {45 49}; 45 -> {46}; - 46 -> {47}; + 46 -> {47 47} [color=green]; 47 -> {48}; 48 -> {49}; 49 -> {50}; + 50 -> {51}; + 51 -> {52}; subgraph cluster_8 { color=red - 51 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - 52 [label="Access variable R|/x|"]; - 53 [label="Function call: R|/x|.R|/A.bool|()"]; - 54 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 53 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 54 [label="Access variable R|/x|"]; + 55 [label="Function call: R|/x|.R|/A.bool|()"]; + 56 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 51 -> {52}; - 52 -> {53}; 53 -> {54}; + 54 -> {55}; + 55 -> {56}; subgraph cluster_9 { color=red - 55 [label="Enter function test_4" style="filled" fillcolor=red]; - 56 [label="Access variable R|/x|"]; - 57 [label="Enter safe call"]; - 58 [label="Function call: R|/x|?.R|/A.id|()"]; - 59 [label="Exit safe call"]; - 60 [label="Enter safe call"]; - 61 [label="Function call: R|/x|?.R|/A.id|()?.R|/A.bool|()"]; - 62 [label="Exit safe call"]; - 63 [label="Access variable R|/x|"]; - 64 [label="Function call: R|/x|.#()"]; - 65 [label="Exit function test_4" style="filled" fillcolor=red]; + 57 [label="Enter function test_4" style="filled" fillcolor=red]; + 58 [label="Access variable R|/x|"]; + 59 [label="Enter safe call"]; + 60 [label="Function call: R|/x|?.R|/A.id|()"]; + 61 [label="Exit safe call"]; + 62 [label="Enter safe call"]; + 63 [label="Function call: R|/x|?.R|/A.id|()?.R|/A.bool|()"]; + 64 [label="Exit safe call"]; + 65 [label="Access variable R|/x|"]; + 66 [label="Function call: R|/x|.#()"]; + 67 [label="Exit function test_4" style="filled" fillcolor=red]; } - 55 -> {56}; - 56 -> {57 59}; 57 -> {58}; - 58 -> {59}; - 59 -> {60 62}; + 58 -> {59 61}; + 59 -> {60}; 60 -> {61}; - 61 -> {62}; + 61 -> {62 64}; 62 -> {63}; 63 -> {64}; 64 -> {65}; + 65 -> {66}; + 66 -> {67}; subgraph cluster_10 { color=red - 66 [label="Enter function boo" style="filled" fillcolor=red]; - 67 [label="Exit function boo" style="filled" fillcolor=red]; - } - - 66 -> {67}; - - subgraph cluster_11 { - color=red - 68 [label="Enter function test_5" style="filled" fillcolor=red]; - 69 [label="Access variable R|/x|"]; - 70 [label="Enter safe call"]; - subgraph cluster_12 { - color=blue - 71 [label="Enter function anonymousFunction"]; - 72 [label="Jump: ^test_5 Unit"]; - 73 [label="Stub" style="filled" fillcolor=gray]; - 74 [label="Exit function anonymousFunction" style="filled" fillcolor=gray]; - } - 75 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { - ^test_5 Unit -} -)" style="filled" fillcolor=gray]; - 76 [label="Exit safe call"]; - 77 [label="Enter safe call"]; - 78 [label="Access variable R|/x|"]; - 79 [label="Function call: R|/x|.R|/A.bool|()"]; - 80 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { - ^test_5 Unit -} -)?.R|/boo|(R|/x|.R|/A.bool|())"]; - 81 [label="Exit safe call"]; - 82 [label="Access variable R|/x|"]; - 83 [label="Function call: R|/x|.#()"]; - 84 [label="Exit function test_5" style="filled" fillcolor=red]; + 68 [label="Enter function boo" style="filled" fillcolor=red]; + 69 [label="Exit function boo" style="filled" fillcolor=red]; } 68 -> {69}; - 69 -> {70 76}; + + subgraph cluster_11 { + color=red + 70 [label="Enter function test_5" style="filled" fillcolor=red]; + 71 [label="Access variable R|/x|"]; + 72 [label="Enter safe call"]; + 73 [label="Postponed enter to lambda"]; + subgraph cluster_12 { + color=blue + 74 [label="Enter function anonymousFunction"]; + 75 [label="Jump: ^test_5 Unit"]; + 76 [label="Stub" style="filled" fillcolor=gray]; + 77 [label="Exit function anonymousFunction" style="filled" fillcolor=gray]; + } + 78 [label="Postponed exit from lambda"]; + 79 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { + ^test_5 Unit +} +)"]; + 80 [label="Exit safe call"]; + 81 [label="Enter safe call"]; + 82 [label="Access variable R|/x|"]; + 83 [label="Function call: R|/x|.R|/A.bool|()"]; + 84 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { + ^test_5 Unit +} +)?.R|/boo|(R|/x|.R|/A.bool|())"]; + 85 [label="Exit safe call"]; + 86 [label="Access variable R|/x|"]; + 87 [label="Function call: R|/x|.#()"]; + 88 [label="Exit function test_5" style="filled" fillcolor=red]; + } + 70 -> {71}; - 71 -> {72}; - 72 -> {84}; - 72 -> {73} [style=dotted]; - 73 -> {74} [style=dotted]; - 74 -> {75} [style=dotted]; + 71 -> {72 80}; + 72 -> {73}; + 73 -> {74}; + 73 -> {78} [color=red]; + 74 -> {75}; + 75 -> {88}; 75 -> {76} [style=dotted]; - 76 -> {77 81}; - 77 -> {78}; + 76 -> {77} [style=dotted]; + 77 -> {78} [color=green]; 78 -> {79}; 79 -> {80}; - 80 -> {81}; + 80 -> {81 85}; 81 -> {82}; 82 -> {83}; 83 -> {84}; + 84 -> {85}; + 85 -> {86}; + 86 -> {87}; + 87 -> {88}; } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.dot b/compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.dot index ad94cd9f1e7..e94ed3472df 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.dot +++ b/compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.dot @@ -7,253 +7,308 @@ digraph callsInPlace_kt { color=red 0 [label="Enter function test" style="filled" fillcolor=red]; 1 [label="Variable declaration: lval x: R|kotlin/Int|"]; + 2 [label="Postponed enter to lambda"]; subgraph cluster_1 { color=blue - 2 [label="Enter function anonymousFunction"]; - 3 [label="Const: Int(1)"]; - 4 [label="Assignmenet: R|/x|"]; - 5 [label="Exit function anonymousFunction"]; + 3 [label="Enter function anonymousFunction"]; + 4 [label="Const: Int(1)"]; + 5 [label="Assignmenet: R|/x|"]; + 6 [label="Exit function anonymousFunction"]; } - 6 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Unit| { + 7 [label="Postponed exit from lambda"]; + 8 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Unit| { R|/x| = Int(1) } )"]; - 7 [label="Access variable R|/x|"]; - 8 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; - 9 [label="Exit function test" style="filled" fillcolor=red]; + 9 [label="Access variable R|/x|"]; + 10 [label="Function call: R|/x|.R|kotlin/Int.inc|()"]; + 11 [label="Exit function test" style="filled" fillcolor=red]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; + 2 -> {7} [color=red]; 3 -> {4}; 4 -> {5}; 5 -> {6}; - 6 -> {7}; + 6 -> {7} [color=green]; 7 -> {8}; 8 -> {9}; + 9 -> {10}; + 10 -> {11}; subgraph cluster_2 { color=red - 10 [label="Enter function test_2" style="filled" fillcolor=red]; - 11 [label="Const: Int(10)"]; + 12 [label="Enter function test_2" style="filled" fillcolor=red]; + 13 [label="Const: Int(10)"]; + 14 [label="Postponed enter to lambda"]; subgraph cluster_3 { color=blue - 12 [label="Enter function anonymousFunction"]; - 13 [label="Const: String(test_2)"]; - 14 [label="Exit function anonymousFunction"]; + 15 [label="Enter function anonymousFunction"]; + 16 [label="Const: String(test_2)"]; + 17 [label="Exit function anonymousFunction"]; } - 15 [label="Function call: R|kotlin/repeat|(Int(10), = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| { + 18 [label="Postponed exit from lambda"]; + 19 [label="Function call: R|kotlin/repeat|(Int(10), = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| { String(test_2) } )"]; - 16 [label="Exit function test_2" style="filled" fillcolor=red]; + 20 [label="Exit function test_2" style="filled" fillcolor=red]; } - 10 -> {11}; - 11 -> {12}; - 12 -> {14 13}; + 12 -> {13}; 13 -> {14}; - 14 -> {12 15}; - 15 -> {16}; + 14 -> {15}; + 14 -> {18} [color=red]; + 15 -> {17 16}; + 16 -> {17}; + 17 -> {15}; + 17 -> {18} [color=green]; + 18 -> {19}; + 19 -> {20}; subgraph cluster_4 { color=red - 17 [label="Enter function test_3" style="filled" fillcolor=red]; - 18 [label="Const: Int(10)"]; + 21 [label="Enter function test_3" style="filled" fillcolor=red]; + 22 [label="Postponed enter to lambda"]; subgraph cluster_5 { color=blue - 19 [label="Enter function anonymousFunction"]; - 20 [label="Const: String(test_3)"]; - 21 [label="Exit function anonymousFunction"]; + 23 [label="Enter function anonymousFunction"]; + 24 [label="Const: String(test_3)"]; + 25 [label="Exit function anonymousFunction"]; } - 22 [label="Function call: R|kotlin/repeat|(action = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| { + 26 [label="Postponed exit from lambda"]; + 27 [label="Const: Int(10)"]; + 28 [label="Function call: R|kotlin/repeat|(action = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| { String(test_3) } , times = Int(10))"]; - 23 [label="Exit function test_3" style="filled" fillcolor=red]; + 29 [label="Exit function test_3" style="filled" fillcolor=red]; } - 17 -> {18}; - 18 -> {19}; - 19 -> {21 20}; - 20 -> {21}; - 21 -> {19 22}; + 21 -> {22}; 22 -> {23}; + 22 -> {26} [color=red]; + 23 -> {25 24}; + 24 -> {25}; + 25 -> {23}; + 25 -> {26} [color=green]; + 26 -> {27}; + 27 -> {28}; + 28 -> {29}; subgraph cluster_6 { color=red - 24 [label="Enter function test_4" style="filled" fillcolor=red]; - 25 [label="Const: Int(1)"]; + 30 [label="Enter function test_4" style="filled" fillcolor=red]; + 31 [label="Const: Int(1)"]; + 32 [label="Postponed enter to lambda"]; subgraph cluster_7 { color=blue - 26 [label="Enter function anonymousFunction"]; - 27 [label="Const: String(test_4)"]; - 28 [label="Access variable R|/it|"]; - 29 [label="Const: Int(0)"]; - 30 [label="Operator >"]; - 31 [label="Exit function anonymousFunction"]; + 33 [label="Enter function anonymousFunction"]; + 34 [label="Const: String(test_4)"]; + 35 [label="Access variable R|/it|"]; + 36 [label="Const: Int(0)"]; + 37 [label="Operator >"]; + 38 [label="Exit function anonymousFunction"]; } - 32 [label="Function call: Int(1).R|kotlin/takeUnless|( = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| { + 39 [label="Postponed exit from lambda"]; + 40 [label="Function call: Int(1).R|kotlin/takeUnless|( = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| { String(test_4) >(R|/it|, Int(0)) } )"]; - 33 [label="Exit function test_4" style="filled" fillcolor=red]; + 41 [label="Exit function test_4" style="filled" fillcolor=red]; } - 24 -> {25}; - 25 -> {26}; - 26 -> {27}; - 27 -> {28}; - 28 -> {29}; - 29 -> {30}; 30 -> {31}; 31 -> {32}; 32 -> {33}; - - subgraph cluster_8 { - color=red - 34 [label="Enter function test_5" style="filled" fillcolor=red]; - 35 [label="Const: Int(1)"]; - subgraph cluster_9 { - color=blue - 36 [label="Enter function anonymousFunction"]; - 37 [label="Const: String(test_5)"]; - 38 [label="Access variable R|/it|"]; - 39 [label="Const: Int(0)"]; - 40 [label="Operator >"]; - 41 [label="Exit function anonymousFunction"]; - } - 42 [label="Function call: Int(1).R|kotlin/takeUnless|(predicate = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| { - String(test_5) - >(R|/it|, Int(0)) -} -)"]; - 43 [label="Exit function test_5" style="filled" fillcolor=red]; - } - + 32 -> {39} [color=red]; + 33 -> {34}; 34 -> {35}; 35 -> {36}; 36 -> {37}; 37 -> {38}; - 38 -> {39}; + 38 -> {39} [color=green]; 39 -> {40}; 40 -> {41}; - 41 -> {42}; + + subgraph cluster_8 { + color=red + 42 [label="Enter function test_5" style="filled" fillcolor=red]; + 43 [label="Const: Int(1)"]; + 44 [label="Postponed enter to lambda"]; + subgraph cluster_9 { + color=blue + 45 [label="Enter function anonymousFunction"]; + 46 [label="Const: String(test_5)"]; + 47 [label="Access variable R|/it|"]; + 48 [label="Const: Int(0)"]; + 49 [label="Operator >"]; + 50 [label="Exit function anonymousFunction"]; + } + 51 [label="Postponed exit from lambda"]; + 52 [label="Function call: Int(1).R|kotlin/takeUnless|(predicate = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| { + String(test_5) + >(R|/it|, Int(0)) +} +)"]; + 53 [label="Exit function test_5" style="filled" fillcolor=red]; + } + 42 -> {43}; + 43 -> {44}; + 44 -> {45}; + 44 -> {51} [color=red]; + 45 -> {46}; + 46 -> {47}; + 47 -> {48}; + 48 -> {49}; + 49 -> {50}; + 50 -> {51} [color=green]; + 51 -> {52}; + 52 -> {53}; subgraph cluster_10 { color=red - 44 [label="Enter function myRun" style="filled" fillcolor=red]; - 45 [label="Function call: R|/block1|.R|FakeOverride|()"]; - 46 [label="Function call: R|/block2|.R|FakeOverride|()"]; - 47 [label="Exit function myRun" style="filled" fillcolor=red]; + 54 [label="Enter function myRun" style="filled" fillcolor=red]; + 55 [label="Function call: R|/block1|.R|FakeOverride|()"]; + 56 [label="Function call: R|/block2|.R|FakeOverride|()"]; + 57 [label="Exit function myRun" style="filled" fillcolor=red]; } - 44 -> {45}; - 45 -> {46}; - 46 -> {47}; + 54 -> {55}; + 55 -> {56}; + 56 -> {57}; subgraph cluster_11 { color=red - 48 [label="Enter function test_6" style="filled" fillcolor=red]; + 58 [label="Enter function test_6" style="filled" fillcolor=red]; + 59 [label="Postponed enter to lambda"]; subgraph cluster_12 { color=blue - 49 [label="Enter function anonymousFunction"]; - 50 [label="Const: String(test_6_1)"]; - 51 [label="Exit function anonymousFunction"]; + 60 [label="Enter function anonymousFunction"]; + 61 [label="Const: String(test_6_1)"]; + 62 [label="Exit function anonymousFunction"]; } + 63 [label="Postponed exit from lambda"]; + 64 [label="Postponed enter to lambda"]; subgraph cluster_13 { color=blue - 52 [label="Enter function anonymousFunction"]; - 53 [label="Const: String(test_6_2)"]; - 54 [label="Exit function anonymousFunction"]; + 65 [label="Enter function anonymousFunction"]; + 66 [label="Const: String(test_6_2)"]; + 67 [label="Exit function anonymousFunction"]; } - 55 [label="Function call: R|/myRun|(myRun@fun (): R|kotlin/Unit| { + 68 [label="Postponed exit from lambda"]; + 69 [label="Function call: R|/myRun|(myRun@fun (): R|kotlin/Unit| { String(test_6_1) } , = myRun@fun (): R|kotlin/Unit| { String(test_6_2) } )"]; - 56 [label="Exit function test_6" style="filled" fillcolor=red]; + 70 [label="Exit function test_6" style="filled" fillcolor=red]; } - 48 -> {49}; - 49 -> {51 50}; - 50 -> {51}; - 51 -> {49 52}; - 52 -> {54 53}; - 53 -> {54}; - 54 -> {52 55}; - 55 -> {56}; + 58 -> {59}; + 59 -> {60}; + 59 -> {63} [color=red]; + 60 -> {62 61}; + 61 -> {62}; + 62 -> {60}; + 62 -> {63} [color=green]; + 63 -> {64}; + 64 -> {65}; + 64 -> {68} [color=red]; + 65 -> {67 66}; + 66 -> {67}; + 67 -> {65}; + 67 -> {68} [color=green]; + 68 -> {69}; + 69 -> {70}; subgraph cluster_14 { color=red - 57 [label="Enter function test_7" style="filled" fillcolor=red]; + 71 [label="Enter function test_7" style="filled" fillcolor=red]; + 72 [label="Postponed enter to lambda"]; subgraph cluster_15 { color=blue - 58 [label="Enter function anonymousFunction"]; - 59 [label="Const: String(test_7_2)"]; - 60 [label="Exit function anonymousFunction"]; + 73 [label="Enter function anonymousFunction"]; + 74 [label="Const: String(test_7_2)"]; + 75 [label="Exit function anonymousFunction"]; } + 76 [label="Postponed exit from lambda"]; + 77 [label="Postponed enter to lambda"]; subgraph cluster_16 { color=blue - 61 [label="Enter function anonymousFunction"]; - 62 [label="Const: String(test_7_1)"]; - 63 [label="Exit function anonymousFunction"]; + 78 [label="Enter function anonymousFunction"]; + 79 [label="Const: String(test_7_1)"]; + 80 [label="Exit function anonymousFunction"]; } - 64 [label="Function call: R|/myRun|(block2 = myRun@fun (): R|kotlin/Unit| { + 81 [label="Postponed exit from lambda"]; + 82 [label="Function call: R|/myRun|(block2 = myRun@fun (): R|kotlin/Unit| { String(test_7_2) } , block1 = myRun@fun (): R|kotlin/Unit| { String(test_7_1) } )"]; - 65 [label="Exit function test_7" style="filled" fillcolor=red]; + 83 [label="Exit function test_7" style="filled" fillcolor=red]; } - 57 -> {58}; - 58 -> {60 59}; - 59 -> {60}; - 60 -> {58 61}; - 61 -> {63 62}; - 62 -> {63}; - 63 -> {61 64}; - 64 -> {65}; + 71 -> {72}; + 72 -> {73}; + 72 -> {76} [color=red]; + 73 -> {75 74}; + 74 -> {75}; + 75 -> {73}; + 75 -> {76} [color=green]; + 76 -> {77}; + 77 -> {78}; + 77 -> {81} [color=red]; + 78 -> {80 79}; + 79 -> {80}; + 80 -> {78}; + 80 -> {81} [color=green]; + 81 -> {82}; + 82 -> {83}; subgraph cluster_17 { color=red - 66 [label="Enter function myDummyRun" style="filled" fillcolor=red]; - 67 [label="Function call: R|/block|.R|FakeOverride|()"]; - 68 [label="Exit function myDummyRun" style="filled" fillcolor=red]; + 84 [label="Enter function myDummyRun" style="filled" fillcolor=red]; + 85 [label="Function call: R|/block|.R|FakeOverride|()"]; + 86 [label="Exit function myDummyRun" style="filled" fillcolor=red]; } - 66 -> {67}; - 67 -> {68}; + 84 -> {85}; + 85 -> {86}; subgraph cluster_18 { color=red - 69 [label="Enter function test_8" style="filled" fillcolor=red]; - 70 [label="Function call: R|/myDummyRun|( = myDummyRun@fun (): R|kotlin/Unit| { + 87 [label="Enter function test_8" style="filled" fillcolor=red]; + 88 [label="Postponed enter to lambda"]; + 89 [label="Postponed exit from lambda"]; + 90 [label="Function call: R|/myDummyRun|( = myDummyRun@fun (): R|kotlin/Unit| { String(test_8) } )"]; - 71 [label="Exit function test_8" style="filled" fillcolor=red]; + 91 [label="Exit function test_8" style="filled" fillcolor=red]; } - 69 -> {70}; - 70 -> {71}; + 87 -> {88}; + 88 -> {89 89} [color=green]; + 89 -> {90}; + 90 -> {91}; subgraph cluster_19 { color=red - 72 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - 73 [label="Const: String(test_8)"]; - 74 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 92 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 93 [label="Const: String(test_8)"]; + 94 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 72 -> {73}; - 73 -> {74}; + 92 -> {93}; + 93 -> {94}; } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt b/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt deleted file mode 100644 index cc46170259c..00000000000 --- a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt +++ /dev/null @@ -1,15 +0,0 @@ -// FULL_JDK - -fun foo(): List = TODO() - -fun ba(): List = TODO() - -fun bar() = - try { - foo().filter { - // Lambda remains effectively unresolved - it.length > 2 - } - } finally { - ba() - } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt b/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt deleted file mode 100644 index 59605e78960..00000000000 --- a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt +++ /dev/null @@ -1,19 +0,0 @@ -FILE: tryWithLambdaInside.kt - public final fun foo(): R|kotlin/collections/List| { - ^foo R|kotlin/TODO|() - } - public final fun ba(): R|kotlin/collections/List| { - ^ba R|kotlin/TODO|() - } - public final fun bar(): R|kotlin/collections/List| { - ^bar try { - R|/foo|().R|kotlin/collections/filter|( = filter@fun .(): { - >(it#.length#, IntegerLiteral(2)) - } - ) - } - finally { - R|/ba|() - } - - } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.dot b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.dot new file mode 100644 index 00000000000..28ed241d7d6 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.dot @@ -0,0 +1,174 @@ +digraph tryWithLambdaInside_kt { + graph [splines=ortho nodesep=3] + node [shape=box penwidth=2] + edge [penwidth=2] + + subgraph cluster_0 { + color=red + 0 [label="Enter function notInPlaceFilter" style="filled" fillcolor=red]; + 1 [label="Access variable this@R|/notInPlaceFilter|"]; + 2 [label="Jump: ^notInPlaceFilter this@R|/notInPlaceFilter|"]; + 3 [label="Stub" style="filled" fillcolor=gray]; + 4 [label="Exit function notInPlaceFilter" style="filled" fillcolor=red]; + } + + 0 -> {1}; + 1 -> {2}; + 2 -> {4}; + 2 -> {3} [style=dotted]; + 3 -> {4} [style=dotted]; + + subgraph cluster_1 { + color=red + 5 [label="Enter function foo" style="filled" fillcolor=red]; + 6 [label="Exit function foo" style="filled" fillcolor=red]; + } + + 5 -> {6}; + + subgraph cluster_2 { + color=red + 7 [label="Enter function testInPlace" style="filled" fillcolor=red]; + subgraph cluster_3 { + color=blue + 8 [label="Try expression enter"]; + subgraph cluster_4 { + color=blue + 9 [label="Try main block enter"]; + subgraph cluster_5 { + color=blue + 10 [label="Enter block"]; + 11 [label="Access variable R|/list|"]; + 12 [label="Postponed enter to lambda"]; + subgraph cluster_6 { + color=blue + 13 [label="Enter function anonymousFunction"]; + 14 [label="Access variable R|/it|"]; + 15 [label="Exit function anonymousFunction"]; + } + 16 [label="Postponed exit from lambda"]; + 17 [label="Function call: R|/list|.R|kotlin/collections/filter|( = filter@fun .(): { + R|/it| +} +)"]; + 18 [label="Exit block"]; + } + 19 [label="Try main block exit"]; + } + subgraph cluster_7 { + color=blue + 20 [label="Enter finally"]; + subgraph cluster_8 { + color=blue + 21 [label="Enter block"]; + 22 [label="Exit block"]; + } + 23 [label="Exit finally"]; + } + 24 [label="Try expression exit"]; + } + 25 [label="Jump: ^testInPlace try { + R|/list|.R|kotlin/collections/filter|( = filter@fun .(): { + R|/it| + } + ) +} +finally { +} +"]; + 26 [label="Stub" style="filled" fillcolor=gray]; + 27 [label="Exit function testInPlace" style="filled" fillcolor=red]; + } + + 7 -> {8}; + 8 -> {9}; + 9 -> {27 20 10}; + 10 -> {11}; + 11 -> {12}; + 12 -> {13}; + 12 -> {16} [color=red]; + 13 -> {15 14}; + 14 -> {15}; + 15 -> {13}; + 15 -> {16} [color=green]; + 16 -> {17}; + 17 -> {18}; + 18 -> {19}; + 19 -> {24}; + 20 -> {21}; + 21 -> {22}; + 22 -> {23}; + 23 -> {24}; + 24 -> {25}; + 25 -> {27}; + 25 -> {26} [style=dotted]; + 26 -> {27} [style=dotted]; + + subgraph cluster_9 { + color=red + 28 [label="Enter function testNotInPlace" style="filled" fillcolor=red]; + subgraph cluster_10 { + color=blue + 29 [label="Try expression enter"]; + subgraph cluster_11 { + color=blue + 30 [label="Try main block enter"]; + subgraph cluster_12 { + color=blue + 31 [label="Enter block"]; + 32 [label="Access variable R|/list|"]; + 33 [label="Postponed enter to lambda"]; + 34 [label="Postponed exit from lambda"]; + 35 [label="Function call: R|/list|.R|/notInPlaceFilter|( = notInPlaceFilter@fun .(): { + R|/it| +} +)"]; + 36 [label="Exit block"]; + } + 37 [label="Try main block exit"]; + } + subgraph cluster_13 { + color=blue + 38 [label="Enter finally"]; + subgraph cluster_14 { + color=blue + 39 [label="Enter block"]; + 40 [label="Exit block"]; + } + 41 [label="Exit finally"]; + } + 42 [label="Try expression exit"]; + } + 43 [label="Jump: ^testNotInPlace try { + R|/list|.R|/notInPlaceFilter|( = notInPlaceFilter@fun .(): { + R|/it| + } + ) +} +finally { +} +"]; + 44 [label="Stub" style="filled" fillcolor=gray]; + 45 [label="Exit function testNotInPlace" style="filled" fillcolor=red]; + } + + 28 -> {29}; + 29 -> {30}; + 30 -> {45 38 31}; + 31 -> {32}; + 32 -> {33}; + 33 -> {34 34} [color=green]; + 34 -> {35}; + 35 -> {36}; + 36 -> {37}; + 37 -> {42}; + 38 -> {39}; + 39 -> {40}; + 40 -> {41}; + 41 -> {42}; + 42 -> {43}; + 43 -> {45}; + 43 -> {44} [style=dotted]; + 44 -> {45} [style=dotted]; + +} diff --git a/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.kt b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.kt new file mode 100644 index 00000000000..8b9f460b4f4 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.kt @@ -0,0 +1,15 @@ +// FULL_JDK + +fun List.notInPlaceFilter(block: (T) -> Boolean): List = this + +fun foo() {} + +fun testInPlace(list: List) = + try { + list.filter { it } + } finally {} + +fun testNotInPlace(list: List) = + try { + list.notInPlaceFilter { it } + } finally {} diff --git a/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.txt b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.txt new file mode 100644 index 00000000000..e5c53e22b9d --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.txt @@ -0,0 +1,28 @@ +FILE: tryWithLambdaInside.kt + public final fun R|kotlin/collections/List|.notInPlaceFilter(block: R|(T) -> kotlin/Boolean|): R|kotlin/collections/List| { + ^notInPlaceFilter this@R|/notInPlaceFilter| + } + public final fun foo(): R|kotlin/Unit| { + } + public final fun testInPlace(list: R|kotlin/collections/List|): R|kotlin/collections/List| { + ^testInPlace try { + R|/list|.R|kotlin/collections/filter|( = filter@fun .(): { + R|/it| + } + ) + } + finally { + } + + } + public final fun testNotInPlace(list: R|kotlin/collections/List|): R|kotlin/collections/List| { + ^testNotInPlace try { + R|/list|.R|/notInPlaceFilter|( = notInPlaceFilter@fun .(): { + R|/it| + } + ) + } + finally { + } + + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsWithCfgTest.kt b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsWithCfgTest.kt index 90b7a07115a..7642cbf440b 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsWithCfgTest.kt +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsWithCfgTest.kt @@ -91,7 +91,7 @@ abstract class AbstractFirDiagnosticsWithCfgTest : AbstractFirDiagnosticsTest() val toKind = to.incomingEdges.getValue(from) TestCase.assertEquals(fromKind, toKind) if (from.isDead || to.isDead) { - TestCase.assertEquals(EdgeKind.Dead, fromKind) + KtUsefulTestCase.assertContainsElements(listOf(EdgeKind.Dead, EdgeKind.Cfg), toKind) } } } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgAndStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgAndStdlibTestGenerated.java index fff5535d98f..7c5e09a83ff 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgAndStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgAndStdlibTestGenerated.java @@ -16,25 +16,46 @@ import java.util.regex.Pattern; /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("compiler/fir/resolve/testData/resolve/stdlib/contracts") -@TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class FirDiagnosticsWithCfgAndStdlibTestGenerated extends AbstractFirDiagnosticsWithCfgAndStdlibTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + @TestMetadata("compiler/fir/resolve/testData/resolve/stdlib/contracts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contracts extends AbstractFirDiagnosticsWithCfgAndStdlibTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInContracts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/contracts"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("callsInPlace.kt") + public void testCallsInPlace() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.kt"); + } + + @TestMetadata("conditionalEffects.kt") + public void testConditionalEffects() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/stdlib/contracts/conditionalEffects.kt"); + } } - public void testAllFilesPresentInContracts() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/contracts"), Pattern.compile("^([^.]+)\\.kt$"), null, true); - } + @TestMetadata("compiler/fir/resolve/testData/resolve/stdlib/smartcasts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Smartcasts extends AbstractFirDiagnosticsWithCfgAndStdlibTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } - @TestMetadata("callsInPlace.kt") - public void testCallsInPlace() throws Exception { - runTest("compiler/fir/resolve/testData/resolve/stdlib/contracts/callsInPlace.kt"); - } + public void testAllFilesPresentInSmartcasts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/smartcasts"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } - @TestMetadata("conditionalEffects.kt") - public void testConditionalEffects() throws Exception { - runTest("compiler/fir/resolve/testData/resolve/stdlib/contracts/conditionalEffects.kt"); + @TestMetadata("tryWithLambdaInside.kt") + public void testTryWithLambdaInside() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/stdlib/smartcasts/tryWithLambdaInside.kt"); + } } } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgTestGenerated.java index 609082e7bcb..fc26b46c231 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithCfgTestGenerated.java @@ -75,6 +75,11 @@ public class FirDiagnosticsWithCfgTestGenerated extends AbstractFirDiagnosticsWi runTest("compiler/fir/resolve/testData/resolve/cfg/loops.kt"); } + @TestMetadata("postponedLambdas.kt") + public void testPostponedLambdas() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/cfg/postponedLambdas.kt"); + } + @TestMetadata("propertiesAndInitBlocks.kt") public void testPropertiesAndInitBlocks() throws Exception { runTest("compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.kt"); diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index f53e3f0d35e..0c7571b94fd 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -30,7 +30,7 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic } public void testAllFilesPresentInStdlib() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "contracts"); + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "contracts", "smartcasts"); } @TestMetadata("anonymousInDelegate.kt") @@ -622,11 +622,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/inapplicableRemoveAll.kt"); } - @TestMetadata("tryWithLambdaInside.kt") - public void testTryWithLambdaInside() throws Exception { - runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt"); - } - @TestMetadata("weakHashMap.kt") public void testWeakHashMap() throws Exception { runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/weakHashMap.kt"); diff --git a/compiler/testData/diagnostics/tests/inference/constraints/returnLambdaFromLambda.fir.kt b/compiler/testData/diagnostics/tests/inference/constraints/returnLambdaFromLambda.fir.kt index 0f100c7b735..76dc095659a 100644 --- a/compiler/testData/diagnostics/tests/inference/constraints/returnLambdaFromLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/constraints/returnLambdaFromLambda.fir.kt @@ -6,14 +6,14 @@ fun testLambda() { if (x is String) return@myRun { it -> x.length + it } if (x !is Int) return@myRun { it -> it } - { it -> x + it } + { it -> x + it } } val twoLambda: (Int) -> Int = myRun { val x: Int = 1 run { val y: Int = 2 - { x + y } + { x + y } } } diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt32358_1.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt32358_1.fir.kt index 1d8c2ac98ee..91387af8e94 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt32358_1.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt32358_1.fir.kt @@ -13,5 +13,5 @@ fun myFun() { val myParent = MyParent() myParent.child?.nullableString ?: run { return } - myParent.child.notNull // <- No smart cast in plugin + myParent.child.notNull // <- No smart cast in plugin } diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt index 17d3723f720..44560bdeb48 100644 --- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt +++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt @@ -544,11 +544,12 @@ fun main(args: Array) { } testClass { - model("resolve/stdlib", pattern = KT_WITHOUT_DOTS_IN_NAME, excludeDirs = listOf("contracts")) + model("resolve/stdlib", pattern = KT_WITHOUT_DOTS_IN_NAME, excludeDirs = listOf("contracts", "smartcasts")) } testClass { model("resolve/stdlib/contracts", pattern = KT_WITHOUT_DOTS_IN_NAME) + model("resolve/stdlib/smartcasts", pattern = KT_WITHOUT_DOTS_IN_NAME) } }