From 411210b520aec416b87233c533833cd605c1d0e0 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Thu, 24 Aug 2023 16:37:41 +0200 Subject: [PATCH] [RAW FIR] Use range as source of desugared loop-related statements --- .../diagnostics/forLoopChecker.kt | 4 ++-- .../kotlin/fir/backend/ConversionUtils.kt | 6 +++--- .../LightTreeRawFirExpressionBuilder.kt | 19 ++++++++++--------- .../kotlin/fir/builder/PsiRawFirBuilder.kt | 19 ++++++++++--------- .../tests/ForRangeConventions.fir.kt | 6 +++--- .../tests/deprecated/iteratorUsage.fir.kt | 4 ++-- .../experimental/implicitUsages.fir.kt | 2 +- .../experimental/implicitUsagesFuture.fir.kt | 2 +- 8 files changed, 32 insertions(+), 30 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt index 17e882268ef..195b332a6a0 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt @@ -101,9 +101,9 @@ fun test( for (i in notRange2); for (i in notRange3); for (i in notRange4); - for (i in notRange5); + for (i in notRange5); for (i in notRange6); - for (i in notRange7); + for (i in notRange7); for (i in notRange8); for (i in notRange9); for (i in range0); diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index a252e0c010a..11d9ad165d1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -477,13 +477,13 @@ internal fun FirReference.statementOrigin(): IrStatementOrigin? = when (this) { symbol.callableId.isInvoke() -> IrStatementOrigin.INVOKE - source?.elementType == KtNodeTypes.FOR && symbol.callableId.isIteratorNext() -> + source?.kind == KtFakeSourceElementKind.DesugaredForLoop && symbol.callableId.isIteratorNext() -> IrStatementOrigin.FOR_LOOP_NEXT - source?.elementType == KtNodeTypes.FOR && symbol.callableId.isIteratorHasNext() -> + source?.kind == KtFakeSourceElementKind.DesugaredForLoop && symbol.callableId.isIteratorHasNext() -> IrStatementOrigin.FOR_LOOP_HAS_NEXT - source?.elementType == KtNodeTypes.FOR && symbol.callableId.isIterator() -> + source?.kind == KtFakeSourceElementKind.DesugaredForLoop && symbol.callableId.isIterator() -> IrStatementOrigin.FOR_LOOP_ITERATOR source?.elementType == KtNodeTypes.OPERATION_REFERENCE -> diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt index 34027dbfcc9..ab7617b5e21 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt @@ -1123,18 +1123,19 @@ class LightTreeRawFirExpressionBuilder( val calculatedRangeExpression = rangeExpression ?: buildErrorExpression(null, ConeSyntaxDiagnostic("No range in for loop")) val fakeSource = forLoop.toFirSourceElement(KtFakeSourceElementKind.DesugaredForLoop) + val rangeSource = calculatedRangeExpression.source?.fakeElement(KtFakeSourceElementKind.DesugaredForLoop) val target: FirLoopTarget // NB: FirForLoopChecker relies on this block existence and structure return buildBlock { source = fakeSource val iteratorVal = generateTemporaryVariable( baseModuleData, - calculatedRangeExpression.source?.fakeElement(KtFakeSourceElementKind.DesugaredForLoop), + rangeSource, SpecialNames.ITERATOR, buildFunctionCall { - source = fakeSource + source = rangeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource ?: fakeSource name = OperatorNameConventions.ITERATOR } explicitReceiver = calculatedRangeExpression @@ -1144,12 +1145,12 @@ class LightTreeRawFirExpressionBuilder( statements += FirWhileLoopBuilder().apply { source = fakeSource condition = buildFunctionCall { - source = fakeSource + source = rangeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource ?: fakeSource name = OperatorNameConventions.HAS_NEXT } - explicitReceiver = generateResolvedAccessExpression(fakeSource, iteratorVal) + explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) } // break/continue in the for loop condition will refer to an outer loop if any. // So, prepare the loop target after building the condition. @@ -1164,12 +1165,12 @@ class LightTreeRawFirExpressionBuilder( valueParameter.source, if (multiDeclaration != null) SpecialNames.DESTRUCT else valueParameter.name, buildFunctionCall { - source = fakeSource + source = rangeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource ?: fakeSource name = OperatorNameConventions.NEXT } - explicitReceiver = generateResolvedAccessExpression(fakeSource, iteratorVal) + explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) }, valueParameter.returnTypeRef ) diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt index fe1eeb933f8..a7324dffbfd 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt @@ -2563,17 +2563,18 @@ open class PsiRawFirBuilder( val rangeExpression = expression.loopRange.toFirExpression("No range in for loop") val ktParameter = expression.loopParameter val fakeSource = expression.toKtPsiSourceElement(KtFakeSourceElementKind.DesugaredForLoop) + val rangeSource = expression.loopRange?.toFirSourceElement(KtFakeSourceElementKind.DesugaredForLoop) + val target: FirLoopTarget // NB: FirForLoopChecker relies on this block existence and structure return buildBlock { source = fakeSource - val rangeSource = expression.loopRange?.toFirSourceElement(KtFakeSourceElementKind.DesugaredForLoop) val iteratorVal = generateTemporaryVariable( baseModuleData, rangeSource, SpecialNames.ITERATOR, buildFunctionCall { - source = fakeSource + source = rangeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource ?: fakeSource name = OperatorNameConventions.ITERATOR } explicitReceiver = rangeExpression @@ -2583,12 +2584,12 @@ open class PsiRawFirBuilder( statements += FirWhileLoopBuilder().apply { source = expression.toFirSourceElement() condition = buildFunctionCall { - source = fakeSource + source = rangeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource ?: fakeSource name = OperatorNameConventions.HAS_NEXT } - explicitReceiver = generateResolvedAccessExpression(fakeSource, iteratorVal) + explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) } // break/continue in the for loop condition will refer to an outer loop if any. // So, prepare the loop target after building the condition. @@ -2604,12 +2605,12 @@ open class PsiRawFirBuilder( source = expression.loopParameter?.toFirSourceElement(), name = if (multiDeclaration != null) SpecialNames.DESTRUCT else ktParameter.nameAsSafeName, initializer = buildFunctionCall { - source = fakeSource + source = rangeSource ?: fakeSource calleeReference = buildSimpleNamedReference { - source = fakeSource + source = rangeSource name = OperatorNameConventions.NEXT } - explicitReceiver = generateResolvedAccessExpression(fakeSource, iteratorVal) + explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) }, typeRef = ktParameter.typeReference.toFirOrImplicitType(), ) diff --git a/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt b/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt index f7fb90cfb46..33c0cc8dd47 100644 --- a/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt +++ b/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt @@ -82,12 +82,12 @@ fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRa for (i in notRange2); for (i in notRange3); for (i in notRange4); - for (i in notRange5); + for (i in notRange5); for (i in notRange6); - for (i in notRange7); + for (i in notRange7); for (i in notRange8); for (i in range0); for (i in range1); for (i in (checkSubtype>(ArrayList()))); -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/deprecated/iteratorUsage.fir.kt b/compiler/testData/diagnostics/tests/deprecated/iteratorUsage.fir.kt index 24905aeb0e0..3e33a33ef25 100644 --- a/compiler/testData/diagnostics/tests/deprecated/iteratorUsage.fir.kt +++ b/compiler/testData/diagnostics/tests/deprecated/iteratorUsage.fir.kt @@ -19,6 +19,6 @@ class Iter2 { } fun use() { - for (x in Iter()) {} - for (x in Iter2()) {} + for (x in Iter()) {} + for (x in Iter2()) {} } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt index c0de435a593..a03e5531e2d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt @@ -120,5 +120,5 @@ fun operatorContainerUsage(s: String, a: AnotherContainer) { val res1 = s - s val res2 = s() val res3 = res1 > res2 - for (c in a) {} + for (c in a) {} } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.fir.kt index aaa29f6813b..48a391acec2 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.fir.kt @@ -120,5 +120,5 @@ fun operatorContainerUsage(s: String, a: AnotherContainer) { val res1 = s - s val res2 = s() val res3 = res1 > res2 - for (c in a) {} + for (c in a) {} }