From 1b1949d242a3df996100456c4fb6be2e536ca8b7 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 7 Apr 2021 09:50:15 +0200 Subject: [PATCH] FIR: generate destructurings for more than one parameter --- ...TouchedTilContractsPhaseTestGenerated.java | 5 ++ .../resolve/arguments/destructuring.fir.txt | 69 +++++++++++++++++++ .../resolve/arguments/destructuring.kt | 13 ++++ .../runners/FirDiagnosticTestGenerated.java | 6 ++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++ .../fir/lightTree/converter/ConverterUtil.kt | 3 +- .../converter/ExpressionsConverter.kt | 18 ++--- .../kotlin/fir/builder/PsiConversionUtils.kt | 2 +- .../kotlin/fir/builder/RawFirBuilder.kt | 18 ++--- .../complexInference.fir.kt | 14 ++-- .../redeclaration.fir.kt | 2 +- .../destructuringInLambdas/simple.fir.kt | 4 +- .../unusedParameters.fir.kt | 4 +- 13 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 5cc7afca015..55dba6b18d2 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -521,6 +521,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/arguments/definetelyNotNullForTypeParameter.kt"); } + @TestMetadata("destructuring.kt") + public void testDestructuring() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt"); + } + @TestMetadata("extensionLambdaInDefaultArgument.kt") public void testExtensionLambdaInDefaultArgument() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/arguments/extensionLambdaInDefaultArgument.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.fir.txt new file mode 100644 index 00000000000..9e6cf075d09 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.fir.txt @@ -0,0 +1,69 @@ +FILE: destructuring.kt + public final data class C : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|, y: R|kotlin/String|): R|C| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public final val y: R|kotlin/String| = R|/y| + public get(): R|kotlin/String| + + public final operator fun component1(): R|kotlin/Int| + + public final operator fun component2(): R|kotlin/String| + + public final fun copy(x: R|kotlin/Int| = this@R|/C|.R|/C.x|, y: R|kotlin/String| = this@R|/C|.R|/C.y|): R|C| + + } + public final fun foo1(block: R|(C) -> kotlin/Unit|): R|kotlin/Unit| { + ^foo1 R|/block|.R|SubstitutionOverride|(R|/C.C|(Int(0), String())) + } + public final fun foo2(block: R|(C, C) -> kotlin/Unit|): R|kotlin/Unit| { + ^foo2 R|/block|.R|SubstitutionOverride|(R|/C.C|(Int(0), String()), R|/C.C|(Int(0), String())) + } + public final fun test(): R|kotlin/Unit| { + R|/foo1|( = foo1@fun (: R|C|): R|kotlin/Unit| { + lval x: R|kotlin/Int| = R|/|.R|/C.component1|() + lval y: R|kotlin/String| = R|/|.R|/C.component2|() + R|/C.C|(R|/x|, R|/y|) + } + ) + R|/foo1|( = foo1@fun (: R|C|): R|kotlin/Unit| { + lval x: R|kotlin/Int| = R|/|.R|/C.component1|() + lval y: R|kotlin/String| = R|/|.R|/C.component2|() + R|/C.C|(R|/x|, R|/y|) + } + ) + R|/foo1|( = foo1@fun (: R|C|): R|kotlin/Unit| { + lval x: R|kotlin/String| = R|/|.R|/C.component1|() + lval y: R|kotlin/Int| = R|/|.R|/C.component2|() + #(R|/x|, R|/y|) + } + ) + R|/foo2|( = foo2@fun (: R|C|, : R|C|): R|kotlin/Unit| { + lval x: R|kotlin/Int| = R|/|.R|/C.component1|() + lval y: R|kotlin/String| = R|/|.R|/C.component2|() + lval z: R|kotlin/Int| = R|/|.R|/C.component1|() + lval w: R|kotlin/String| = R|/|.R|/C.component2|() + R|/C.C|(R|/x|.R|kotlin/Int.plus|(R|/z|), R|/y|.R|kotlin/String.plus|(R|/w|)) + } + ) + R|/foo2|( = foo2@fun (: R|C|, : R|C|): R|kotlin/Unit| { + lval x: R|kotlin/Int| = R|/|.R|/C.component1|() + lval y: R|kotlin/String| = R|/|.R|/C.component2|() + lval z: R|kotlin/Int| = R|/|.R|/C.component1|() + lval w: R|kotlin/String| = R|/|.R|/C.component2|() + R|/C.C|(R|/x|.R|kotlin/Int.plus|(R|/z|), R|/y|.R|kotlin/String.plus|(R|/w|)) + } + ) + R|/foo2|( = foo2@fun (: R|C|, : R|C|): R|kotlin/Unit| { + lval x: R|kotlin/String| = R|/|.R|/C.component1|() + lval y: R|kotlin/Int| = R|/|.R|/C.component2|() + lval z: R|kotlin/String| = R|/|.R|/C.component1|() + lval w: R|kotlin/Int| = R|/|.R|/C.component2|() + #(R|/x|.R|kotlin/String.plus|(R|/z|), R|/y|.R|kotlin/Int.plus|(R|/w|)) + } + ) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt b/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt new file mode 100644 index 00000000000..fdf3028d656 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt @@ -0,0 +1,13 @@ +data class C(val x: Int, val y: String) + +fun foo1(block: (C) -> Unit) = block(C(0, "")) +fun foo2(block: (C, C) -> Unit) = block(C(0, ""), C(0, "")) + +fun test() { + foo1 { (x, y) -> C(x, y) } + foo1 { (x: Int, y: String) -> C(x, y) } + foo1 { (x: String, y: Int) -> C(x, y) } + foo2 { (x, y), (z, w) -> C(x + z, y + w) } + foo2 { (x: Int, y: String), (z: Int, w: String) -> C(x + z, y + w) } + foo2 { (x: String, y: Int), (z: String, w: Int) -> C(x + z, y + w) } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 87183b4460f..ebb2ea80093 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -611,6 +611,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/arguments/definetelyNotNullForTypeParameter.kt"); } + @Test + @TestMetadata("destructuring.kt") + public void testDestructuring() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt"); + } + @Test @TestMetadata("extensionLambdaInDefaultArgument.kt") public void testExtensionLambdaInDefaultArgument() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 9f40c1aacd1..b11de9cac1e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -615,6 +615,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/arguments/definetelyNotNullForTypeParameter.kt"); } + @Test + @TestMetadata("destructuring.kt") + public void testDestructuring() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/arguments/destructuring.kt"); + } + @Test @TestMetadata("extensionLambdaInDefaultArgument.kt") public void testExtensionLambdaInDefaultArgument() throws Exception { diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ConverterUtil.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ConverterUtil.kt index 284b1b65e5a..ec0826b237b 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ConverterUtil.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ConverterUtil.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.lightTree.fir.DestructuringDeclaration @@ -106,7 +107,7 @@ fun generateDestructuringBlock( multiDeclaration: DestructuringDeclaration, container: FirVariable<*>, tmpVariable: Boolean -): FirExpression { +): FirBlock { return buildBlock { if (tmpVariable) { statements += container diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 8e03deba790..dd0e65f123f 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -147,7 +147,7 @@ class ExpressionsConverter( } target = FirFunctionTarget(labelName = label?.name, isLambda = true) context.firFunctionTargets += target - var destructuringBlock: FirExpression? = null + val destructuringStatements = mutableListOf() for (valueParameter in valueParameterList) { val multiDeclaration = valueParameter.destructuringDeclaration valueParameters += if (multiDeclaration != null) { @@ -163,12 +163,12 @@ class ExpressionsConverter( isNoinline = false isVararg = false } - destructuringBlock = generateDestructuringBlock( + destructuringStatements += generateDestructuringBlock( this@ExpressionsConverter.baseSession, multiDeclaration, multiParameter, tmpVariable = false - ) + ).statements multiParameter } else { valueParameter.firValueParameter @@ -187,11 +187,7 @@ class ExpressionsConverter( } ) } - if (destructuringBlock is FirBlock) { - for ((index, statement) in destructuringBlock.statements.withIndex()) { - statements.add(index, statement) - } - } + statements.addAll(0, destructuringStatements) }.build() } } else { @@ -989,11 +985,7 @@ class ExpressionsConverter( firLoopParameter, tmpVariable = true ) - if (destructuringBlock is FirBlock) { - for ((index, statement) in destructuringBlock.statements.withIndex()) { - statements.add(index, statement) - } - } + statements.addAll(0, destructuringBlock.statements) } else { statements.add(0, firLoopParameter) } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt index c10e211ea07..02f543794d3 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt @@ -88,7 +88,7 @@ internal fun generateDestructuringBlock( tmpVariable: Boolean, extractAnnotationsTo: KtAnnotated.(FirAnnotationContainerBuilder) -> Unit, toFirOrImplicitTypeRef: KtTypeReference?.() -> FirTypeRef, -): FirExpression { +): FirBlock { return buildBlock { source = multiDeclaration.toFirPsiSourceElement() if (tmpVariable) { diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 74024128715..c6eb37c17d2 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1069,7 +1069,7 @@ open class RawFirBuilder( symbol = FirAnonymousFunctionSymbol() isLambda = true - var destructuringBlock: FirExpression? = null + val destructuringStatements = mutableListOf() for (valueParameter in literal.valueParameters) { val multiDeclaration = valueParameter.destructuringDeclaration valueParameters += if (multiDeclaration != null) { @@ -1087,13 +1087,13 @@ open class RawFirBuilder( isNoinline = false isVararg = false } - destructuringBlock = generateDestructuringBlock( + destructuringStatements += generateDestructuringBlock( baseSession, multiDeclaration, multiParameter, tmpVariable = false, extractAnnotationsTo = { extractAnnotationsTo(it) }, - ) { toFirOrImplicitType() } + ) { toFirOrImplicitType() }.statements multiParameter } else { val typeRef = valueParameter.typeReference?.convertSafe() ?: buildImplicitTypeRef { @@ -1129,11 +1129,7 @@ open class RawFirBuilder( } ) } - if (destructuringBlock is FirBlock) { - for ((index, statement) in destructuringBlock.statements.withIndex()) { - statements.add(index, statement) - } - } + statements.addAll(0, destructuringStatements) }.build() } context.firFunctionTargets.removeLast() @@ -1742,11 +1738,7 @@ open class RawFirBuilder( tmpVariable = true, extractAnnotationsTo = { extractAnnotationsTo(it) }, ) { toFirOrImplicitType() } - if (destructuringBlock is FirBlock) { - for ((index, statement) in destructuringBlock.statements.withIndex()) { - blockBuilder.statements.add(index, statement) - } - } + blockBuilder.statements.addAll(0, destructuringBlock.statements) } else { blockBuilder.statements.add(0, firLoopParameter) } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/complexInference.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/complexInference.fir.kt index 7222a9323b9..36f55311414 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/complexInference.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/complexInference.fir.kt @@ -24,24 +24,24 @@ fun bar(aInstance: A, bInstance: B) { foo(bInstance) { (a, b): A, (c, d) -> - a checkType { _() } - b checkType { _() } + a checkType { _() } + b checkType { _() } c checkType { _() } d checkType { _() } } foo(bInstance) { - (a, b), (c, d) -> - a checkType { _() } - b checkType { _() } + (a, b), (c, d) -> + a checkType { _() } + b checkType { _() } c checkType { _() } d checkType { _() } } foo(bInstance) { (a, b), (c, d) -> - a checkType { _() } - b checkType { _() } + a checkType { _() } + b checkType { _() } c checkType { _() } d checkType { _() } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt index 77e16b4ffbe..eacbe222183 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt @@ -23,7 +23,7 @@ fun bar() { } foo { (a, b), (c, b) -> - a checkType { _() } + a checkType { _() } b checkType { _() } c checkType { _() } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/simple.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/simple.fir.kt index 81d6adabe56..18a810c9305 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/simple.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/simple.fir.kt @@ -36,8 +36,8 @@ fun bar() { } foobar { (a, b), (c, d) -> - a checkType { _() } - b checkType { _() } + a checkType { _() } + b checkType { _() } c checkType { _() } d checkType { _() } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/unusedParameters.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/unusedParameters.fir.kt index 34f2df67940..ab5ceb23965 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/unusedParameters.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/unusedParameters.fir.kt @@ -32,12 +32,12 @@ fun bar() { } foobar { (a, b), (c, d) -> - a checkType { _() } + a checkType { _() } d checkType { _() } } foobar { (a, b), (c, d) -> - b checkType { _() } + b checkType { _() } c checkType { _() } } }