[FIR] Use Operator origin for ITERATOR and HAS_NEXT function calls instead of Regular

It automatically fixes KT-62356 since iterators now are operators

^KT-62356 Fixed
This commit is contained in:
Ivan Kochurkin
2024-02-18 19:15:14 +01:00
committed by Space Team
parent 313b230333
commit 55159694df
7 changed files with 40 additions and 22 deletions
@@ -260,9 +260,9 @@ FILE: forLoopChecker.kt
} }
{ {
lval <iterator>: R|ImproperIterator6| = R|<local>/notRange9|.R|/NotRange9.iterator|() lval <iterator>: R|ImproperIterator6| = R|<local>/notRange9|.R|/NotRange9.iterator<Inapplicable(CONVENTION_ERROR): /NotRange9.iterator>#|()
while(R|<local>/<iterator>|.R|/ImproperIterator6.hasNext|()) { while(R|<local>/<iterator>|.R|/ImproperIterator6.hasNext<Inapplicable(CONVENTION_ERROR): /ImproperIterator6.hasNext>#|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|/ImproperIterator6.next|() lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|/ImproperIterator6.next<Inapplicable(CONVENTION_ERROR): /ImproperIterator6.next>#|()
{ {
} }
@@ -105,7 +105,7 @@ fun test(
for (i in notRange6); for (i in notRange6);
for (i in <!CONDITION_TYPE_MISMATCH!>notRange7<!>); for (i in <!CONDITION_TYPE_MISMATCH!>notRange7<!>);
for (i in <!HAS_NEXT_MISSING!>notRange8<!>); for (i in <!HAS_NEXT_MISSING!>notRange8<!>);
for (i in <!OPERATOR_MODIFIER_REQUIRED, OPERATOR_MODIFIER_REQUIRED, OPERATOR_MODIFIER_REQUIRED!>notRange9<!>); for (i in <!OPERATOR_MODIFIER_REQUIRED!>notRange9<!>);
for (i in range0); for (i in range0);
for (i in range1); for (i in range1);
} }
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.isError import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.resolve.calls.OperatorCallOfNonOperatorFunction
import org.jetbrains.kotlin.fir.resolve.calls.UnsafeCall import org.jetbrains.kotlin.fir.resolve.calls.UnsafeCall
import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -106,10 +107,13 @@ object FirForLoopChecker : FirBlockChecker(MppCheckerKind.Common) {
when { when {
calleeReference.isError() -> { calleeReference.isError() -> {
when (val diagnostic = calleeReference.diagnostic) { when (val diagnostic = calleeReference.diagnostic) {
is ConeAmbiguityError -> if (diagnostic.applicability.isSuccess) { is ConeAmbiguityError -> {
reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates.map { it.symbol }, context) reporter.reportOn(
} else if (noneApplicableFactory != null) { reportSource,
reporter.reportOn(reportSource, noneApplicableFactory, diagnostic.candidates.map { it.symbol }, context) noneApplicableFactory ?: ambiguityFactory,
diagnostic.candidates.map { it.symbol },
context
)
} }
is ConeUnresolvedNameError -> { is ConeUnresolvedNameError -> {
reporter.reportOn(reportSource, missingFactory, context) reporter.reportOn(reportSource, missingFactory, context)
@@ -132,17 +136,25 @@ object FirForLoopChecker : FirBlockChecker(MppCheckerKind.Common) {
is ConeInapplicableCandidateError -> { is ConeInapplicableCandidateError -> {
if (unsafeCallFactory != null || noneApplicableFactory != null) { if (unsafeCallFactory != null || noneApplicableFactory != null) {
diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.forEach { diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.forEach {
if (it is UnsafeCall) { when (it) {
if (unsafeCallFactory != null) { is UnsafeCall -> {
if (unsafeCallFactory != null) {
reporter.reportOn(
reportSource, unsafeCallFactory, context
)
} else {
reporter.reportOn(
reportSource, noneApplicableFactory!!, listOf(diagnostic.candidate.symbol), context
)
}
return true
}
is OperatorCallOfNonOperatorFunction -> {
val symbol = it.function
reporter.reportOn( reporter.reportOn(
reportSource, unsafeCallFactory, context reportSource, OPERATOR_MODIFIER_REQUIRED, symbol, symbol.name.asString(), context
)
} else {
reporter.reportOn(
reportSource, noneApplicableFactory!!, listOf(diagnostic.candidate.symbol), context
) )
} }
return true
} }
} }
} }
@@ -1172,6 +1172,7 @@ class LightTreeRawFirExpressionBuilder(
name = OperatorNameConventions.ITERATOR name = OperatorNameConventions.ITERATOR
} }
explicitReceiver = calculatedRangeExpression explicitReceiver = calculatedRangeExpression
origin = FirFunctionCallOrigin.Operator
} }
) )
statements += iteratorVal statements += iteratorVal
@@ -1184,6 +1185,7 @@ class LightTreeRawFirExpressionBuilder(
name = OperatorNameConventions.HAS_NEXT name = OperatorNameConventions.HAS_NEXT
} }
explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal)
origin = FirFunctionCallOrigin.Operator
} }
// break/continue in the for loop condition will refer to an outer loop if any. // break/continue in the for loop condition will refer to an outer loop if any.
// So, prepare the loop target after building the condition. // So, prepare the loop target after building the condition.
@@ -1204,6 +1206,7 @@ class LightTreeRawFirExpressionBuilder(
name = OperatorNameConventions.NEXT name = OperatorNameConventions.NEXT
} }
explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal)
origin = FirFunctionCallOrigin.Operator
}, },
valueParameter.returnTypeRef, valueParameter.returnTypeRef,
extractedAnnotations = valueParameter.annotations extractedAnnotations = valueParameter.annotations
@@ -2743,6 +2743,7 @@ open class PsiRawFirBuilder(
name = OperatorNameConventions.ITERATOR name = OperatorNameConventions.ITERATOR
} }
explicitReceiver = rangeExpression explicitReceiver = rangeExpression
origin = FirFunctionCallOrigin.Operator
}, },
) )
statements += iteratorVal statements += iteratorVal
@@ -2755,6 +2756,7 @@ open class PsiRawFirBuilder(
name = OperatorNameConventions.HAS_NEXT name = OperatorNameConventions.HAS_NEXT
} }
explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal)
origin = FirFunctionCallOrigin.Operator
} }
// break/continue in the for loop condition will refer to an outer loop if any. // break/continue in the for loop condition will refer to an outer loop if any.
// So, prepare the loop target after building the condition. // So, prepare the loop target after building the condition.
@@ -2776,6 +2778,7 @@ open class PsiRawFirBuilder(
name = OperatorNameConventions.NEXT name = OperatorNameConventions.NEXT
} }
explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal) explicitReceiver = generateResolvedAccessExpression(rangeSource, iteratorVal)
origin = FirFunctionCallOrigin.Operator
}, },
typeRef = ktParameter.typeReference.toFirOrImplicitType(), typeRef = ktParameter.typeReference.toFirOrImplicitType(),
extractedAnnotations = ktParameter.modifierList?.annotationEntries?.map { it.convert<FirAnnotation>() }, extractedAnnotations = ktParameter.modifierList?.annotationEntries?.map { it.convert<FirAnnotation>() },
@@ -187,13 +187,13 @@ class B(var a: Int = 0) {
* TESTCASE NUMBER: 7 * TESTCASE NUMBER: 7
* NOTE: for-loop operators * NOTE: for-loop operators
* UNEXPECTED BEHAVIOUR * UNEXPECTED BEHAVIOUR
* ISSUES: KT-36898 * ISSUES: KT-36898, KT-62356
*/ */
package testPackCase7 package testPackCase7
fun case7 () { fun case7 () {
val iterable: Iterable = Iterable(Inv('s')) val iterable: Iterable = Iterable(Inv('s'))
for (i in iterable) { for (i in <!PROPERTY_AS_OPERATOR!>iterable<!>) {
println(i) println(i)
} }
} }
@@ -220,13 +220,13 @@ class Inv(val c: Char) {
* TESTCASE NUMBER: 8 * TESTCASE NUMBER: 8
* NOTE: for-loop operators * NOTE: for-loop operators
* UNEXPECTED BEHAVIOUR * UNEXPECTED BEHAVIOUR
* ISSUES: KT-36898 * ISSUES: KT-36898, KT-62356
*/ */
package testPackCase8 package testPackCase8
fun case8 () { fun case8 () {
val iterable: Iterable = Iterable() val iterable: Iterable = Iterable()
for (i in iterable) { for (i in <!PROPERTY_AS_OPERATOR!>iterable<!>) {
println(i) println(i)
} }
} }
@@ -187,7 +187,7 @@ class B(var a: Int = 0) {
* TESTCASE NUMBER: 7 * TESTCASE NUMBER: 7
* NOTE: for-loop operators * NOTE: for-loop operators
* UNEXPECTED BEHAVIOUR * UNEXPECTED BEHAVIOUR
* ISSUES: KT-36898 * ISSUES: KT-36898, KT-62356
*/ */
package testPackCase7 package testPackCase7
@@ -220,7 +220,7 @@ class Inv(val c: Char) {
* TESTCASE NUMBER: 8 * TESTCASE NUMBER: 8
* NOTE: for-loop operators * NOTE: for-loop operators
* UNEXPECTED BEHAVIOUR * UNEXPECTED BEHAVIOUR
* ISSUES: KT-36898 * ISSUES: KT-36898, KT-62356
*/ */
package testPackCase8 package testPackCase8