Introduce FirForLoopChecker

This commit is contained in:
Mikhail Glukhikh
2021-04-02 13:19:04 +03:00
parent 4ddc0ed3fe
commit 2e14b65644
35 changed files with 708 additions and 118 deletions
@@ -78,14 +78,14 @@ abstract class NotRange8() {
fun test(notRange1: NotRange1, notRange2: NotRange2, notRange3: NotRange3, notRange4: NotRange4, notRange5: NotRange5, notRange6: NotRange6, notRange7: NotRange7, notRange8: NotRange8, range0: Range0, range1: Range1) {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (i in notRange1)<!>;
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (i in notRange2)<!>;
<!UNRESOLVED_REFERENCE!>for (i in notRange3)<!>;
<!UNRESOLVED_REFERENCE!>for (i in notRange4)<!>;
for (i in <!ITERATOR_MISSING!>notRange1<!>);
for (i in <!HAS_NEXT_MISSING!>notRange2<!>);
for (i in <!NEXT_MISSING!>notRange3<!>);
for (i in <!HAS_NEXT_MISSING!>notRange4<!>);
for (i in notRange5);
for (i in notRange6);
for (i in notRange7);
<!UNRESOLVED_REFERENCE!>for (i in notRange8)<!>;
for (i in <!HAS_NEXT_MISSING!>notRange8<!>);
for (i in range0);
for (i in range1);
+2 -2
View File
@@ -22,11 +22,11 @@ fun testUnresolved() {
is String -> <!UNRESOLVED_REFERENCE!>a<!>
}
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (j in <!UNRESOLVED_REFERENCE!>collection<!>) {
for (j in <!ITERATOR_MISSING, UNRESOLVED_REFERENCE!>collection<!>) {
var i: Int = j
i += 1
foo1(j)
}<!>
}
}
fun foo1(i: Int) {}
@@ -1,22 +0,0 @@
// !WITH_NEW_INFERENCE
// See also KT-7428
class Container<K>(val k: K)
// iterator() must be an extension, otherwise code will not compile
operator fun <K> Container<K>.iterator(): Iterator<K> = null!!
fun test() {
val container: Container<String>? = null
// Error
container<!UNSAFE_CALL!>.<!>iterator()
// for extension iterator, this code compiles, but should not
<!UNSAFE_CALL!>for (s in container) {}<!>
}
class OtherContainer<K>(val k: K) {
operator fun iterator(): Iterator<K> = null!!
}
fun test2() {
val other: OtherContainer<String>? = null
// Error
<!UNSAFE_CALL!>for (s in other) {}<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !WITH_NEW_INFERENCE
// See also KT-7428
class Container<K>(val k: K)
@@ -1,7 +1,7 @@
fun foo1() = <!EXPRESSION_EXPECTED!>while (b()) {}<!>
fun foo2() = <!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (i in 10) {}<!>
fun foo2() = for (i in <!ITERATOR_MISSING!>10<!>) {}
fun foo3() = when (b()) {
true -> 1
@@ -8,7 +8,7 @@ class It {
}
fun test(c: Coll?) {
<!UNSAFE_CALL!>for (x in c) {}<!>
for (x in <!ITERATOR_ON_NULLABLE!>c<!>) {}
if (c != null) {
for(x in c) {}
@@ -8,5 +8,5 @@ class It {
}
fun test() {
<!UNSAFE_CALL, UNSAFE_CALL!>for (x in Coll()) {}<!>
for (x in <!HAS_NEXT_FUNCTION_NONE_APPLICABLE!>Coll()<!>) {}
}
@@ -1,15 +1,15 @@
// !WITH_NEW_INFERENCE
fun useDeclaredVariables() {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((a, b)<!SYNTAX!><!>) {
for ((a, b)<!SYNTAX!><!>) {
a
b
}<!>
}
}
fun checkersShouldRun() {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for ((@A a, _)<!SYNTAX!><!>) {
for ((@A a, _)<!SYNTAX!><!>) {
}<!>
}
}
annotation class A
@@ -11,6 +11,6 @@ fun test(nothing: Nothing?) {
}
fun sum(a : IntArray) : Int {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (n
<!SYNTAX!>return<!><!SYNTAX!><!> "?"<!>
for (n
<!SYNTAX!>return<!><!SYNTAX!><!> "?"
}
@@ -1,8 +1,8 @@
package b
fun foo() {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (i in <!UNRESOLVED_REFERENCE!>collection<!>) {
for (i in <!ITERATOR_MISSING, UNRESOLVED_REFERENCE!>collection<!>) {
{
break
}
}<!><!SYNTAX!><!>
}<!SYNTAX!><!>
@@ -4,6 +4,6 @@ class X
operator fun <T> X.iterator(): Iterable<T> = TODO()
fun test() {
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (i in X()) {
}<!>
for (i in <!HAS_NEXT_MISSING!>X()<!>) {
}
}
@@ -1,27 +0,0 @@
//KT-1821 Write test for ITERATOR_AMBIGUITY diagnostic
interface MyCollectionInterface {
}
interface MyAnotherCollectionInterface {
}
class MyCollection : MyCollectionInterface, MyAnotherCollectionInterface {
}
fun MyCollectionInterface.iterator() = MyIterator()
fun MyAnotherCollectionInterface.iterator() = MyIterator()
class MyIterator {
fun next() : MyElement = MyElement()
fun hasNext() = true
}
class MyElement
fun test1(collection: MyCollection) {
collection.<!OVERLOAD_RESOLUTION_AMBIGUITY!>iterator<!>()
<!OVERLOAD_RESOLUTION_AMBIGUITY, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (element in collection) {
}<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-1821 Write test for ITERATOR_AMBIGUITY diagnostic
interface MyCollectionInterface {
@@ -1,28 +0,0 @@
// FILE: J.java
import org.jetbrains.annotations.*;
import java.util.*;
public class J {
@NotNull
public static List<String> staticNN;
@Nullable
public static List<String> staticN;
public static List<String> staticJ;
}
// FILE: k.kt
fun test() {
// @NotNull platform type
val platformNN = J.staticNN
// @Nullable platform type
val platformN = J.staticN
// platform type with no annotation
val platformJ = J.staticJ
for (x in platformNN) {}
<!UNSAFE_CALL!>for (x in platformN) {}<!>
for (x in platformJ) {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: J.java
import org.jetbrains.annotations.*;
@@ -14,8 +14,8 @@ class MyClass {
var res = 0
m = create()
// See KT-7428
<!UNSAFE_CALL!>for ((k, v) in m)
res += (k.length + v.length)<!>
for ((k, v) in <!ITERATOR_ON_NULLABLE!>m<!>)
res += (k.length + v.length)
return res
}
}
@@ -25,7 +25,7 @@ fun whenInContract(x: Any?, boolean: Boolean) {
fun forInContract(x: Any?) {
contract {
<!ERROR_IN_CONTRACT_DESCRIPTION, UNRESOLVED_REFERENCE!>for (i in 0..1) {
<!ERROR_IN_CONTRACT_DESCRIPTION!>for (i in 0..1) {
returns() implies (x is String)
}<!>
}
@@ -23,5 +23,5 @@ typealias C2<T> = JHost.Consumer2<T, T>
val test1 = R { }
val test2 = C<String> { s -> println(s.length) }
val test3 = CStr { s -> <!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(s.<!UNRESOLVED_REFERENCE!>length<!>) }
val test4 = CStrList { ss -> <!OVERLOAD_RESOLUTION_AMBIGUITY, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>for (s in ss) { <!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(s.<!UNRESOLVED_REFERENCE!>length<!>) }<!> }
val test4 = CStrList { ss -> for (s in <!ITERATOR_AMBIGUITY!>ss<!>) { <!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(s.<!UNRESOLVED_REFERENCE!>length<!>) } }
val test5 = <!INAPPLICABLE_CANDIDATE!>C2<!><Int> { a, b -> val x: Int = a <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> b; println(x)}