[RAW FIR] Use range as source of desugared loop-related statements

This commit is contained in:
Kirill Rakhman
2023-08-24 16:37:41 +02:00
committed by Space Team
parent 61259ef34b
commit 411210b520
8 changed files with 32 additions and 30 deletions
@@ -101,9 +101,9 @@ fun test(
for (i in <!HAS_NEXT_MISSING, NEXT_MISSING!>notRange2<!>);
for (i in <!NEXT_MISSING!>notRange3<!>);
for (i in <!HAS_NEXT_MISSING!>notRange4<!>);
<!CONDITION_TYPE_MISMATCH!>for (i in notRange5)<!>;
for (i in <!CONDITION_TYPE_MISMATCH!>notRange5<!>);
for (i in notRange6);
<!CONDITION_TYPE_MISMATCH!>for (i in notRange7)<!>;
for (i in <!CONDITION_TYPE_MISMATCH!>notRange7<!>);
for (i in <!HAS_NEXT_MISSING!>notRange8<!>);
for (i in <!OPERATOR_MODIFIER_REQUIRED, OPERATOR_MODIFIER_REQUIRED, OPERATOR_MODIFIER_REQUIRED!>notRange9<!>);
for (i in range0);
@@ -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 ->
@@ -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
)
@@ -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(),
)
@@ -82,12 +82,12 @@ fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRa
for (i in <!HAS_NEXT_MISSING, NEXT_MISSING!>notRange2<!>);
for (i in <!NEXT_MISSING!>notRange3<!>);
for (i in <!HAS_NEXT_MISSING!>notRange4<!>);
<!CONDITION_TYPE_MISMATCH!>for (i in notRange5)<!>;
for (i in <!CONDITION_TYPE_MISMATCH!>notRange5<!>);
for (i in notRange6);
<!CONDITION_TYPE_MISMATCH!>for (i in notRange7)<!>;
for (i in <!CONDITION_TYPE_MISMATCH!>notRange7<!>);
for (i in <!HAS_NEXT_MISSING!>notRange8<!>);
for (i in range0);
for (i in range1);
for (i in (checkSubtype<List<Int>>(ArrayList<Int>())));
}
}
@@ -19,6 +19,6 @@ class Iter2 {
}
fun use() {
<!DEPRECATION!>for (x in Iter()) {}<!>
<!DEPRECATION, DEPRECATION!>for (x in Iter2()) {}<!>
for (x in <!DEPRECATION!>Iter<!>()) {}
for (x in <!DEPRECATION, DEPRECATION!>Iter2<!>()) {}
}
@@ -120,5 +120,5 @@ fun operatorContainerUsage(s: String, a: AnotherContainer) {
val res1 = s <!OPT_IN_USAGE_ERROR!>-<!> s
val res2 = <!OPT_IN_USAGE_ERROR!>s<!>()
val res3 = <!OPT_IN_USAGE_ERROR!>res1<!> <!OPT_IN_USAGE_ERROR!>><!> <!OPT_IN_USAGE_ERROR!>res2<!>
<!OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR!>for (c in a) {}<!>
for (c in <!OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR!>a<!>) {}
}
@@ -120,5 +120,5 @@ fun operatorContainerUsage(s: String, a: AnotherContainer) {
val res1 = s <!OPT_IN_USAGE_ERROR!>-<!> s
val res2 = <!OPT_IN_USAGE_ERROR!>s<!>()
val res3 = <!OPT_IN_USAGE_ERROR!>res1<!> <!OPT_IN_USAGE_ERROR!>><!> <!OPT_IN_USAGE_ERROR!>res2<!>
<!OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR!>for (c in a) {}<!>
for (c in <!OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR, OPT_IN_USAGE_ERROR!>a<!>) {}
}