diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 18132d2b26e..e32a1a5a693 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -183,11 +183,15 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformBlock(block: FirBlock, data: ResolutionMode): CompositeTransformResult { dataFlowAnalyzer.enterBlock(block) - @Suppress("NAME_SHADOWING") - val block = block.transformChildren(transformer, data) as FirBlock - val statement = block.statements.lastOrNull() + val numberOfStatements = block.statements.size - val resultExpression = when (statement) { + block.transformStatementsIndexed(transformer) { index -> + if (index == numberOfStatements - 1) data else ResolutionMode.ContextIndependent + } + block.transformAllStatementsExceptLast(integerLiteralTypeApproximator, builtinTypes.intType.type) + block.transformOtherChildren(transformer, data) + + val resultExpression = when (val statement = block.statements.lastOrNull()) { is FirReturnExpression -> statement.result is FirExpression -> statement else -> null diff --git a/compiler/fir/resolve/testData/resolve/cfg/loops.dot b/compiler/fir/resolve/testData/resolve/cfg/loops.dot index 30686d1b994..2046410a83f 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/loops.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/loops.dot @@ -183,7 +183,7 @@ digraph loops_kt { subgraph cluster_19 { color=blue 63 [label="Enter block"]; - 64 [label="Const: Int(1)"]; + 64 [label="Const: IntegerLiteral(1)"]; 65 [label="Exit block"]; } 66 [label="Exit loop block"]; @@ -301,7 +301,7 @@ digraph loops_kt { subgraph cluster_32 { color=blue 100 [label="Enter block" style="filled" fillcolor=gray]; - 101 [label="Const: Int(1)" style="filled" fillcolor=gray]; + 101 [label="Const: IntegerLiteral(1)" style="filled" fillcolor=gray]; 102 [label="Exit block" style="filled" fillcolor=gray]; } 103 [label="Exit loop block" style="filled" fillcolor=gray]; @@ -338,7 +338,7 @@ digraph loops_kt { subgraph cluster_36 { color=blue 110 [label="Enter block"]; - 111 [label="Const: Int(1)"]; + 111 [label="Const: IntegerLiteral(1)"]; 112 [label="Exit block"]; } 113 [label="Exit loop block"]; @@ -456,7 +456,7 @@ digraph loops_kt { subgraph cluster_49 { color=blue 147 [label="Enter block"]; - 148 [label="Const: Int(1)"]; + 148 [label="Const: IntegerLiteral(1)"]; 149 [label="Exit block"]; } 150 [label="Exit loop block"]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/loops.txt b/compiler/fir/resolve/testData/resolve/cfg/loops.txt index a72a595e925..e6fb75107ce 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/loops.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/loops.txt @@ -24,7 +24,7 @@ FILE: loops.kt } public final fun testWhileTrue(): R|kotlin/Unit| { while(Boolean(true)) { - Int(1) + IntegerLiteral(1) } Int(1) @@ -43,14 +43,14 @@ FILE: loops.kt } public final fun testWhileFalse(): R|kotlin/Unit| { while(Boolean(false)) { - Int(1) + IntegerLiteral(1) } Int(1) } public final fun testDoWhileTrue(): R|kotlin/Unit| { do { - Int(1) + IntegerLiteral(1) } while(Boolean(true)) Int(1) @@ -69,7 +69,7 @@ FILE: loops.kt } public final fun testDoWhileFalse(): R|kotlin/Unit| { do { - Int(1) + IntegerLiteral(1) } while(Boolean(false)) Int(1) diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.dot b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.dot index 85360b862b7..8159e51f055 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.dot +++ b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.dot @@ -16,10 +16,11 @@ digraph callsInPlace_kt { 6 [label="Exit function anonymousFunction"]; } 7 [label="Postponed exit from lambda"]; - 8 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Unit| )"]; - 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]; + 8 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Nothing| )"]; + 9 [label="Stub" style="filled" fillcolor=gray]; + 10 [label="Access variable R|/x|" style="filled" fillcolor=gray]; + 11 [label="Function call: R|/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=gray]; + 12 [label="Exit function test" style="filled" fillcolor=red]; } 0 -> {1}; @@ -31,256 +32,258 @@ digraph callsInPlace_kt { 5 -> {6}; 6 -> {7} [color=green]; 7 -> {8}; - 8 -> {9}; - 9 -> {10}; - 10 -> {11}; + 8 -> {12}; + 8 -> {9} [style=dotted]; + 9 -> {10} [style=dotted]; + 10 -> {11} [style=dotted]; + 11 -> {12} [style=dotted]; subgraph cluster_2 { color=red - 12 [label="Enter function test_2" style="filled" fillcolor=red]; - 13 [label="Const: Int(10)"]; - 14 [label="Postponed enter to lambda"]; + 13 [label="Enter function test_2" style="filled" fillcolor=red]; + 14 [label="Const: Int(10)"]; + 15 [label="Postponed enter to lambda"]; subgraph cluster_3 { color=blue - 15 [label="Enter function anonymousFunction"]; - 16 [label="Const: String(test_2)"]; - 17 [label="Exit function anonymousFunction"]; + 16 [label="Enter function anonymousFunction"]; + 17 [label="Const: String(test_2)"]; + 18 [label="Exit function anonymousFunction"]; } - 18 [label="Postponed exit from lambda"]; - 19 [label="Function call: R|kotlin/repeat|(Int(10), = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| )"]; - 20 [label="Exit function test_2" style="filled" fillcolor=red]; + 19 [label="Postponed exit from lambda"]; + 20 [label="Function call: R|kotlin/repeat|(Int(10), = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| )"]; + 21 [label="Exit function test_2" style="filled" fillcolor=red]; } - 12 -> {13}; 13 -> {14}; 14 -> {15}; - 14 -> {18} [color=red]; - 15 -> {17 16}; - 16 -> {17}; - 17 -> {15}; - 17 -> {18} [color=green]; - 18 -> {19}; + 15 -> {16}; + 15 -> {19} [color=red]; + 16 -> {18 17}; + 17 -> {18}; + 18 -> {16}; + 18 -> {19} [color=green]; 19 -> {20}; + 20 -> {21}; subgraph cluster_4 { color=red - 21 [label="Enter function test_3" style="filled" fillcolor=red]; - 22 [label="Postponed enter to lambda"]; + 22 [label="Enter function test_3" style="filled" fillcolor=red]; + 23 [label="Postponed enter to lambda"]; subgraph cluster_5 { color=blue - 23 [label="Enter function anonymousFunction"]; - 24 [label="Const: String(test_3)"]; - 25 [label="Exit function anonymousFunction"]; + 24 [label="Enter function anonymousFunction"]; + 25 [label="Const: String(test_3)"]; + 26 [label="Exit function anonymousFunction"]; } - 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| , times = Int(10))"]; - 29 [label="Exit function test_3" style="filled" fillcolor=red]; + 27 [label="Postponed exit from lambda"]; + 28 [label="Const: Int(10)"]; + 29 [label="Function call: R|kotlin/repeat|(action = repeat@fun (it: R|kotlin/Int|): R|kotlin/Unit| , times = Int(10))"]; + 30 [label="Exit function test_3" style="filled" fillcolor=red]; } - 21 -> {22}; 22 -> {23}; - 22 -> {26} [color=red]; - 23 -> {25 24}; - 24 -> {25}; - 25 -> {23}; - 25 -> {26} [color=green]; - 26 -> {27}; + 23 -> {24}; + 23 -> {27} [color=red]; + 24 -> {26 25}; + 25 -> {26}; + 26 -> {24}; + 26 -> {27} [color=green]; 27 -> {28}; 28 -> {29}; + 29 -> {30}; subgraph cluster_6 { color=red - 30 [label="Enter function test_4" style="filled" fillcolor=red]; - 31 [label="Const: Int(1)"]; - 32 [label="Postponed enter to lambda"]; + 31 [label="Enter function test_4" style="filled" fillcolor=red]; + 32 [label="Const: Int(1)"]; + 33 [label="Postponed enter to lambda"]; subgraph cluster_7 { color=blue - 33 [label="Enter function anonymousFunction"]; - 34 [label="Const: String(test_4)"]; - 35 [label="Access variable R|/it|"]; - 36 [label="Const: Int(0)"]; - 37 [label="Function call: R|/it|.R|kotlin/Int.compareTo|(Int(0))"]; - 38 [label="Comparison >"]; - 39 [label="Exit function anonymousFunction"]; + 34 [label="Enter function anonymousFunction"]; + 35 [label="Const: String(test_4)"]; + 36 [label="Access variable R|/it|"]; + 37 [label="Const: Int(0)"]; + 38 [label="Function call: R|/it|.R|kotlin/Int.compareTo|(Int(0))"]; + 39 [label="Comparison >"]; + 40 [label="Exit function anonymousFunction"]; } - 40 [label="Postponed exit from lambda"]; - 41 [label="Function call: Int(1).R|kotlin/takeUnless|( = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| )"]; - 42 [label="Exit function test_4" style="filled" fillcolor=red]; + 41 [label="Postponed exit from lambda"]; + 42 [label="Function call: Int(1).R|kotlin/takeUnless|( = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| )"]; + 43 [label="Exit function test_4" style="filled" fillcolor=red]; } - 30 -> {31}; 31 -> {32}; 32 -> {33}; - 32 -> {40} [color=red]; 33 -> {34}; + 33 -> {41} [color=red]; 34 -> {35}; 35 -> {36}; 36 -> {37}; 37 -> {38}; 38 -> {39}; - 39 -> {40} [color=green]; - 40 -> {41}; + 39 -> {40}; + 40 -> {41} [color=green]; 41 -> {42}; + 42 -> {43}; subgraph cluster_8 { color=red - 43 [label="Enter function test_5" style="filled" fillcolor=red]; - 44 [label="Const: Int(1)"]; - 45 [label="Postponed enter to lambda"]; + 44 [label="Enter function test_5" style="filled" fillcolor=red]; + 45 [label="Const: Int(1)"]; + 46 [label="Postponed enter to lambda"]; subgraph cluster_9 { color=blue - 46 [label="Enter function anonymousFunction"]; - 47 [label="Const: String(test_5)"]; - 48 [label="Access variable R|/it|"]; - 49 [label="Const: Int(0)"]; - 50 [label="Function call: R|/it|.R|kotlin/Int.compareTo|(Int(0))"]; - 51 [label="Comparison >"]; - 52 [label="Exit function anonymousFunction"]; + 47 [label="Enter function anonymousFunction"]; + 48 [label="Const: String(test_5)"]; + 49 [label="Access variable R|/it|"]; + 50 [label="Const: Int(0)"]; + 51 [label="Function call: R|/it|.R|kotlin/Int.compareTo|(Int(0))"]; + 52 [label="Comparison >"]; + 53 [label="Exit function anonymousFunction"]; } - 53 [label="Postponed exit from lambda"]; - 54 [label="Function call: Int(1).R|kotlin/takeUnless|(predicate = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| )"]; - 55 [label="Exit function test_5" style="filled" fillcolor=red]; + 54 [label="Postponed exit from lambda"]; + 55 [label="Function call: Int(1).R|kotlin/takeUnless|(predicate = takeUnless@fun (it: R|kotlin/Int|): R|kotlin/Boolean| )"]; + 56 [label="Exit function test_5" style="filled" fillcolor=red]; } - 43 -> {44}; 44 -> {45}; 45 -> {46}; - 45 -> {53} [color=red]; 46 -> {47}; + 46 -> {54} [color=red]; 47 -> {48}; 48 -> {49}; 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {53} [color=green]; - 53 -> {54}; + 52 -> {53}; + 53 -> {54} [color=green]; 54 -> {55}; + 55 -> {56}; subgraph cluster_10 { color=red - 56 [label="Enter function myRun" style="filled" fillcolor=red]; - 57 [label="Function call: R|/block1|.R|FakeOverride|()"]; - 58 [label="Function call: R|/block2|.R|FakeOverride|()"]; - 59 [label="Exit function myRun" style="filled" fillcolor=red]; + 57 [label="Enter function myRun" style="filled" fillcolor=red]; + 58 [label="Function call: R|/block1|.R|FakeOverride|()"]; + 59 [label="Function call: R|/block2|.R|FakeOverride|()"]; + 60 [label="Exit function myRun" style="filled" fillcolor=red]; } - 56 -> {57}; 57 -> {58}; 58 -> {59}; + 59 -> {60}; subgraph cluster_11 { color=red - 60 [label="Enter function test_6" style="filled" fillcolor=red]; - 61 [label="Postponed enter to lambda"]; + 61 [label="Enter function test_6" style="filled" fillcolor=red]; + 62 [label="Postponed enter to lambda"]; subgraph cluster_12 { color=blue - 62 [label="Enter function anonymousFunction"]; - 63 [label="Const: String(test_6_1)"]; - 64 [label="Exit function anonymousFunction"]; + 63 [label="Enter function anonymousFunction"]; + 64 [label="Const: String(test_6_1)"]; + 65 [label="Exit function anonymousFunction"]; } - 65 [label="Postponed exit from lambda"]; - 66 [label="Postponed enter to lambda"]; + 66 [label="Postponed exit from lambda"]; + 67 [label="Postponed enter to lambda"]; subgraph cluster_13 { color=blue - 67 [label="Enter function anonymousFunction"]; - 68 [label="Const: String(test_6_2)"]; - 69 [label="Exit function anonymousFunction"]; + 68 [label="Enter function anonymousFunction"]; + 69 [label="Const: String(test_6_2)"]; + 70 [label="Exit function anonymousFunction"]; } - 70 [label="Postponed exit from lambda"]; - 71 [label="Function call: R|/myRun|(myRun@fun (): R|kotlin/Unit| , = myRun@fun (): R|kotlin/Unit| )"]; - 72 [label="Exit function test_6" style="filled" fillcolor=red]; + 71 [label="Postponed exit from lambda"]; + 72 [label="Function call: R|/myRun|(myRun@fun (): R|kotlin/Unit| , = myRun@fun (): R|kotlin/Unit| )"]; + 73 [label="Exit function test_6" style="filled" fillcolor=red]; } - 60 -> {61}; 61 -> {62}; - 61 -> {65} [color=red]; - 62 -> {64 63}; - 63 -> {64}; - 64 -> {62}; - 64 -> {65} [color=green]; - 65 -> {66}; + 62 -> {63}; + 62 -> {66} [color=red]; + 63 -> {65 64}; + 64 -> {65}; + 65 -> {63}; + 65 -> {66} [color=green]; 66 -> {67}; - 66 -> {70} [color=red]; - 67 -> {69 68}; - 68 -> {69}; - 69 -> {67}; - 69 -> {70} [color=green]; - 70 -> {71}; + 67 -> {68}; + 67 -> {71} [color=red]; + 68 -> {70 69}; + 69 -> {70}; + 70 -> {68}; + 70 -> {71} [color=green]; 71 -> {72}; + 72 -> {73}; subgraph cluster_14 { color=red - 73 [label="Enter function test_7" style="filled" fillcolor=red]; - 74 [label="Postponed enter to lambda"]; + 74 [label="Enter function test_7" style="filled" fillcolor=red]; + 75 [label="Postponed enter to lambda"]; subgraph cluster_15 { color=blue - 75 [label="Enter function anonymousFunction"]; - 76 [label="Const: String(test_7_2)"]; - 77 [label="Exit function anonymousFunction"]; + 76 [label="Enter function anonymousFunction"]; + 77 [label="Const: String(test_7_2)"]; + 78 [label="Exit function anonymousFunction"]; } - 78 [label="Postponed exit from lambda"]; - 79 [label="Postponed enter to lambda"]; + 79 [label="Postponed exit from lambda"]; + 80 [label="Postponed enter to lambda"]; subgraph cluster_16 { color=blue - 80 [label="Enter function anonymousFunction"]; - 81 [label="Const: String(test_7_1)"]; - 82 [label="Exit function anonymousFunction"]; + 81 [label="Enter function anonymousFunction"]; + 82 [label="Const: String(test_7_1)"]; + 83 [label="Exit function anonymousFunction"]; } - 83 [label="Postponed exit from lambda"]; - 84 [label="Function call: R|/myRun|(block2 = myRun@fun (): R|kotlin/Unit| , block1 = myRun@fun (): R|kotlin/Unit| )"]; - 85 [label="Exit function test_7" style="filled" fillcolor=red]; + 84 [label="Postponed exit from lambda"]; + 85 [label="Function call: R|/myRun|(block2 = myRun@fun (): R|kotlin/Unit| , block1 = myRun@fun (): R|kotlin/Unit| )"]; + 86 [label="Exit function test_7" style="filled" fillcolor=red]; } - 73 -> {74}; 74 -> {75}; - 74 -> {78} [color=red]; - 75 -> {77 76}; - 76 -> {77}; - 77 -> {75}; - 77 -> {78} [color=green]; - 78 -> {79}; + 75 -> {76}; + 75 -> {79} [color=red]; + 76 -> {78 77}; + 77 -> {78}; + 78 -> {76}; + 78 -> {79} [color=green]; 79 -> {80}; - 79 -> {83} [color=red]; - 80 -> {82 81}; - 81 -> {82}; - 82 -> {80}; - 82 -> {83} [color=green]; - 83 -> {84}; + 80 -> {81}; + 80 -> {84} [color=red]; + 81 -> {83 82}; + 82 -> {83}; + 83 -> {81}; + 83 -> {84} [color=green]; 84 -> {85}; + 85 -> {86}; subgraph cluster_17 { color=red - 86 [label="Enter function myDummyRun" style="filled" fillcolor=red]; - 87 [label="Function call: R|/block|.R|FakeOverride|()"]; - 88 [label="Exit function myDummyRun" style="filled" fillcolor=red]; + 87 [label="Enter function myDummyRun" style="filled" fillcolor=red]; + 88 [label="Function call: R|/block|.R|FakeOverride|()"]; + 89 [label="Exit function myDummyRun" style="filled" fillcolor=red]; } - 86 -> {87}; 87 -> {88}; + 88 -> {89}; subgraph cluster_18 { color=red - 89 [label="Enter function test_8" style="filled" fillcolor=red]; - 90 [label="Postponed enter to lambda"]; - 91 [label="Postponed exit from lambda"]; - 92 [label="Function call: R|/myDummyRun|( = myDummyRun@fun (): R|kotlin/Unit|)"]; - 93 [label="Exit function test_8" style="filled" fillcolor=red]; + 90 [label="Enter function test_8" style="filled" fillcolor=red]; + 91 [label="Postponed enter to lambda"]; + 92 [label="Postponed exit from lambda"]; + 93 [label="Function call: R|/myDummyRun|( = myDummyRun@fun (): R|kotlin/Unit|)"]; + 94 [label="Exit function test_8" style="filled" fillcolor=red]; } - 89 -> {90}; - 90 -> {91 91} [color=green]; - 91 -> {92}; + 90 -> {91}; + 91 -> {92 92} [color=green]; 92 -> {93}; + 93 -> {94}; subgraph cluster_19 { color=red - 94 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - 95 [label="Const: String(test_8)"]; - 96 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 95 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 96 [label="Const: String(test_8)"]; + 97 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 94 -> {95}; 95 -> {96}; + 96 -> {97}; } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.txt b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.txt index 15ca59afa42..cdc7da0dd9a 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/callsInPlace.txt @@ -1,7 +1,7 @@ FILE: callsInPlace.kt public final fun test(): R|kotlin/Unit| { lval x: R|kotlin/Int| - R|kotlin/run|( = run@fun (): R|kotlin/Unit| { + R|kotlin/run|( = run@fun (): R|kotlin/Nothing| { R|/x| = Int(1) } ) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirBlock.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirBlock.kt index 382a0a6b0ab..0635b9ef869 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirBlock.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirBlock.kt @@ -23,4 +23,8 @@ abstract class FirBlock : FirExpression() { override fun accept(visitor: FirVisitor, data: D): R = visitor.visitBlock(this, data) abstract override fun replaceTypeRef(newTypeRef: FirTypeRef) + + abstract fun transformStatements(transformer: FirTransformer, data: D): FirBlock + + abstract fun transformOtherChildren(transformer: FirTransformer, data: D): FirBlock } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirBlockImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirBlockImpl.kt index c01bcbc537d..8939d35d1a9 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirBlockImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirBlockImpl.kt @@ -32,8 +32,18 @@ internal class FirBlockImpl( } override fun transformChildren(transformer: FirTransformer, data: D): FirBlockImpl { - annotations.transformInplace(transformer, data) + transformStatements(transformer, data) + transformOtherChildren(transformer, data) + return this + } + + override fun transformStatements(transformer: FirTransformer, data: D): FirBlockImpl { statements.transformInplace(transformer, data) + return this + } + + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirBlockImpl { + annotations.transformInplace(transformer, data) typeRef = typeRef.transformSingle(transformer, data) return this } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEmptyExpressionBlock.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEmptyExpressionBlock.kt index cb43c6d5445..9d8b9c7bbdb 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEmptyExpressionBlock.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEmptyExpressionBlock.kt @@ -30,6 +30,15 @@ class FirEmptyExpressionBlock : FirBlock() { } override fun transformChildren(transformer: FirTransformer, data: D): FirEmptyExpressionBlock { + transformOtherChildren(transformer, data) + return this + } + + override fun transformStatements(transformer: FirTransformer, data: D): FirEmptyExpressionBlock { + return this + } + + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirEmptyExpressionBlock { typeRef = typeRef.transformSingle(transformer, data) return this } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt index 8c3d1d36718..f17e6faa593 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt @@ -48,6 +48,7 @@ class BuiltinTypes { val enumType: FirImplicitBuiltinTypeRef = FirImplicitEnumTypeRef(null) val annotationType: FirImplicitBuiltinTypeRef = FirImplicitAnnotationTypeRef(null) val booleanType: FirImplicitBuiltinTypeRef = FirImplicitBooleanTypeRef(null) + val intType: FirImplicitBuiltinTypeRef = FirImplicitIntTypeRef(null) val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null) val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null) val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index a1355314518..95833d9b7d8 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -10,13 +10,14 @@ import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression import org.jetbrains.kotlin.fir.expressions.builder.buildErrorLoop -import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl -import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl -import org.jetbrains.kotlin.fir.expressions.impl.FirErrorLoopImpl +import org.jetbrains.kotlin.fir.expressions.impl.* +import org.jetbrains.kotlin.fir.expressions.impl.FirBlockImpl import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.transformInplace import org.jetbrains.kotlin.name.ClassId inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType? @@ -55,4 +56,21 @@ fun buildErrorExpression(source: FirSourceElement?, diagnostic: FirDiagnostic): this.source = source this.diagnostic = diagnostic } +} + +fun FirBlock.transformStatementsIndexed(transformer: FirTransformer, dataProducer: (Int) -> D?): FirBlock { + when (this) { + is FirBlockImpl -> statements.transformInplace(transformer, dataProducer) + is FirSingleExpressionBlock -> { + dataProducer(0)?.let { transformStatements(transformer, it) } + } + } + return this +} + +fun FirBlock.transformAllStatementsExceptLast(transformer: FirTransformer, data: D): FirBlock { + val threshold = statements.size - 1 + return transformStatementsIndexed(transformer) { index -> + data.takeIf { index < threshold } + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirSingleExpressionBlock.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirSingleExpressionBlock.kt index 76a6dcca08b..c8fab318a20 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirSingleExpressionBlock.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirSingleExpressionBlock.kt @@ -32,15 +32,25 @@ class FirSingleExpressionBlock( } override fun transformChildren(transformer: FirTransformer, data: D): FirSingleExpressionBlock { - annotations.transformInplace(transformer, data) - statement = statement.transformSingle(transformer, data) - typeRef = typeRef.transformSingle(transformer, data) + transformStatements(transformer, data) + transformOtherChildren(transformer, data) return this } override fun replaceTypeRef(newTypeRef: FirTypeRef) { typeRef = newTypeRef } + + override fun transformStatements(transformer: FirTransformer, data: D): FirBlock { + statement = statement.transformSingle(transformer, data) + return this + } + + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirBlock { + annotations.transformInplace(transformer, data) + typeRef = typeRef.transformSingle(transformer, data) + return this + } } @Suppress("NOTHING_TO_INLINE") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt index 40e32330e3c..48ee61985fe 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt @@ -63,6 +63,10 @@ class FirImplicitBooleanTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Boolean) +class FirImplicitIntTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Int) + class FirImplicitNothingTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/visitors/FirTransformerUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/visitors/FirTransformerUtil.kt index 08bc12d8cb3..a6050a742d6 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/visitors/FirTransformerUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/visitors/FirTransformerUtil.kt @@ -34,3 +34,13 @@ fun MutableList.transformInplace(transformer: FirTransfor } } +inline fun MutableList.transformInplace(transformer: FirTransformer, dataProducer: (Int) -> D?) { + val iterator = this.listIterator() + var index = 0 + while (iterator.hasNext()) { + val next = iterator.next() as FirPureAbstractElement + val data = dataProducer(index++) ?: continue + val result = next.transform(transformer, data).single + iterator.set(result) + } +} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index b21e70d05ce..2f822d2c0a7 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -110,8 +110,9 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } block.configure { - +fieldList(statement) + +fieldList(statement).withTransform() +typeRefField + needTransformOtherChildren() } binaryLogicExpression.configure { diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt index 5faf6875838..216a92b0ea1 100644 --- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt +++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME fun box(): String { diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt index 0f62af3ed4d..eeecafca219 100644 --- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt +++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME fun box(): String { diff --git a/compiler/testData/codegen/box/fullJdk/regressions/kt15112.kt b/compiler/testData/codegen/box/fullJdk/regressions/kt15112.kt index 28c4120fff7..581222b1b24 100644 --- a/compiler/testData/codegen/box/fullJdk/regressions/kt15112.kt +++ b/compiler/testData/codegen/box/fullJdk/regressions/kt15112.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FULL_JDK // WITH_RUNTIME // TARGET_BACKEND: JVM diff --git a/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt b/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt index 619cd6d90de..b30d2416246 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { lateinit var ok: String run { diff --git a/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt b/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt index 23d1104aeba..c2cb9fb01f5 100644 --- a/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt +++ b/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR lateinit var ok: String fun box(): String { diff --git a/compiler/testData/codegen/box/synchronized/changeMonitor.kt b/compiler/testData/codegen/box/synchronized/changeMonitor.kt index 5c2bab2c36b..6b3600f3c94 100644 --- a/compiler/testData/codegen/box/synchronized/changeMonitor.kt +++ b/compiler/testData/codegen/box/synchronized/changeMonitor.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/diagnostics/tests/callableReference/generic/nestedCallWithOverload.fir.kt b/compiler/testData/diagnostics/tests/callableReference/generic/nestedCallWithOverload.fir.kt index 20c94cb3ae6..de5c7647851 100644 --- a/compiler/testData/diagnostics/tests/callableReference/generic/nestedCallWithOverload.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/generic/nestedCallWithOverload.fir.kt @@ -14,9 +14,9 @@ fun test() { val x5: (Double) -> Unit = baz(id(::foo), id(id(::foo))) - id<(Int) -> Unit>(id(id(::foo))) + id<(Int) -> Unit>(id(id(::foo))) id(id<(Int) -> Unit>(::foo)) - baz<(Int) -> Unit>(id(::foo), id(id(::foo))) - baz(id(::foo), id(id<(Int) -> Unit>(::foo))) + baz<(Int) -> Unit>(id(::foo), id(id(::foo))) + baz(id(::foo), id(id<(Int) -> Unit>(::foo))) baz(id(::foo), id<(Int) -> Unit>(id(::foo))) } \ No newline at end of file diff --git a/compiler/testData/ir/irText/declarations/parameters/useNextParamInLambda.fir.txt b/compiler/testData/ir/irText/declarations/parameters/useNextParamInLambda.fir.txt index 54ac1b7c137..d36a65d3362 100644 --- a/compiler/testData/ir/irText/declarations/parameters/useNextParamInLambda.fir.txt +++ b/compiler/testData/ir/irText/declarations/parameters/useNextParamInLambda.fir.txt @@ -22,7 +22,7 @@ FILE fqName: fileName:/useNextParamInLambda.kt BLOCK_BODY VAR name:result type:kotlin.String [var] CONST String type=kotlin.String value="fail" - TRY type=kotlin.String + TRY type=kotlin.Any try: CALL 'public final fun f (f1: kotlin.Function0, f2: kotlin.Function0): kotlin.String declared in ' type=kotlin.String origin=null CATCH parameter=val e: java.lang.Exception [val] declared in .box VAR name:e type:java.lang.Exception [val] diff --git a/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt b/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt index 2a23a4c0f5b..5b26dae24d2 100644 --- a/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt +++ b/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt @@ -24,7 +24,7 @@ FILE fqName: fileName:/ifElseIf.kt FUN name:testEmptyBranches1 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean BLOCK_BODY - WHEN type=kotlin.Unit origin=IF + WHEN type=kotlin.Any origin=IF BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in .testEmptyBranches1' type=kotlin.Boolean origin=null then: BLOCK type=kotlin.Unit origin=null @@ -38,7 +38,7 @@ FILE fqName: fileName:/ifElseIf.kt FUN name:testEmptyBranches2 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean BLOCK_BODY - WHEN type=kotlin.Unit origin=IF + WHEN type=kotlin.Any origin=IF BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in .testEmptyBranches2' type=kotlin.Boolean origin=null then: BLOCK type=kotlin.Unit origin=null