[RAW FIR] Use range as source of desugared loop-related statements
This commit is contained in:
committed by
Space Team
parent
61259ef34b
commit
411210b520
+2
-2
@@ -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 ->
|
||||
|
||||
+10
-9
@@ -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
|
||||
)
|
||||
|
||||
+10
-9
@@ -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<!>()) {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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<!>) {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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<!>) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user