FIR checker: warn unnecessary safe calls
This commit is contained in:
committed by
Mikhail Glukhikh
parent
2ecb6733ed
commit
5a0b75bd89
@@ -1,6 +1,6 @@
|
||||
fun bar(doIt: Int.() -> Int) {
|
||||
1.doIt()
|
||||
1?.doIt()
|
||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()
|
||||
val i: Int? = 1
|
||||
i.<!INAPPLICABLE_CANDIDATE!>doIt<!>()
|
||||
i?.doIt()
|
||||
|
||||
@@ -82,6 +82,6 @@ fun test() {
|
||||
val i : Int? = null
|
||||
i.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
|
||||
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
||||
1?.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
|
||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
|
||||
1.<!UNRESOLVED_REFERENCE!>{}<!>()
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@ fun foo() {
|
||||
// these both also ok (with smart cast / unnecessary safe call)
|
||||
if (rule != null) {
|
||||
rule.apply()
|
||||
rule?.apply()
|
||||
rule<!UNNECESSARY_SAFE_CALL!>?.<!>apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// http://youtrack.jetbrains.net/issue/KT-418
|
||||
|
||||
fun ff() {
|
||||
val i: Int = 1
|
||||
val a: Int = i?.plus(2)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// http://youtrack.jetbrains.net/issue/KT-418
|
||||
|
||||
fun ff() {
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ fun Int.gg() = null
|
||||
|
||||
fun ff() {
|
||||
val a: Int = 1
|
||||
val b: Int = a?.gg()
|
||||
val b: Int = a<!UNNECESSARY_SAFE_CALL!>?.<!>gg()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ val s: String = "test"
|
||||
|
||||
// FILE: test.kt
|
||||
fun ff() {
|
||||
val a = Test?.<!UNRESOLVED_REFERENCE!>FOO<!>
|
||||
val b = foo?.<!UNRESOLVED_REFERENCE!>s<!>
|
||||
System?.<!UNRESOLVED_REFERENCE!>out<!>.<!UNRESOLVED_REFERENCE!>println<!>(a + b)
|
||||
val a = Test<!UNEXPECTED_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>FOO<!>
|
||||
val b = foo<!UNEXPECTED_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>s<!>
|
||||
System<!UNEXPECTED_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>out<!>.<!UNRESOLVED_REFERENCE!>println<!>(a + b)
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ fun test11() {
|
||||
|
||||
fun test12() {
|
||||
fun Any.bar(i: Int) {}
|
||||
todo()?.bar(1)
|
||||
todo()<!UNNECESSARY_SAFE_CALL!>?.<!>bar(1)
|
||||
}
|
||||
|
||||
fun todo(): Nothing = throw Exception()
|
||||
fun todo(): Nothing = throw Exception()
|
||||
|
||||
+2
-2
@@ -7,6 +7,6 @@ fun foo(): String {
|
||||
}
|
||||
fun bar(): String {
|
||||
val x = fn() ?: return ""
|
||||
val y = x?.let { throw Exception() } ?: "unreachable"
|
||||
val y = x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() } ?: "unreachable"
|
||||
return y
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ fun <T: Any, E> T.foo(x : E, y : A) : T {
|
||||
y plus 1
|
||||
y + 1.0
|
||||
|
||||
this?.minus<T>(this)
|
||||
this<!UNNECESSARY_SAFE_CALL!>?.<!>minus<T>(this)
|
||||
|
||||
return this
|
||||
}
|
||||
@@ -70,7 +70,7 @@ import outer.*
|
||||
command?.equals1(null)
|
||||
|
||||
val c = Command()
|
||||
c?.equals2(null)
|
||||
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
|
||||
|
||||
if (command == null) 1
|
||||
}
|
||||
|
||||
@@ -27,15 +27,15 @@ fun foo(l: A<String>?) {
|
||||
foo(l?.bar()) checkType { _<String?>() }
|
||||
foo(l?.gav()) checkType { _<String?>() }
|
||||
if (l != null) {
|
||||
foo(l?.bar()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l?.gav()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
}
|
||||
}
|
||||
|
||||
fun fooNotNull(l: A<String>) {
|
||||
// No errors should be here
|
||||
foo(l?.bar()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l?.gav()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
|
||||
@@ -13,7 +13,7 @@ fun <T : CharSequence?> foo(x: T) {
|
||||
if (x != null) {}
|
||||
|
||||
x.length
|
||||
x?.length
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
x.bar1()
|
||||
x.bar2()
|
||||
@@ -21,14 +21,14 @@ fun <T : CharSequence?> foo(x: T) {
|
||||
x.bar4()
|
||||
|
||||
|
||||
x?.bar1()
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
|
||||
}
|
||||
|
||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
|
||||
if (x is String) {
|
||||
x.length
|
||||
x?.length
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
x.bar1()
|
||||
x.bar2()
|
||||
@@ -37,7 +37,7 @@ fun <T : CharSequence?> foo(x: T) {
|
||||
|
||||
if (x is CharSequence) {
|
||||
x.length
|
||||
x?.length
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
x.bar1()
|
||||
x.bar2()
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ fun <T : String?> T.foo() {
|
||||
if (this != null) {}
|
||||
|
||||
length
|
||||
this?.length
|
||||
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
bar1()
|
||||
bar2()
|
||||
@@ -20,14 +20,14 @@ fun <T : String?> T.foo() {
|
||||
bar4()
|
||||
|
||||
|
||||
this?.bar1()
|
||||
this<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
|
||||
}
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
|
||||
if (this is String) {
|
||||
length
|
||||
this?.length
|
||||
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
bar1()
|
||||
bar2()
|
||||
|
||||
@@ -55,5 +55,5 @@ fun test2(t: Test?) {
|
||||
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) as? X
|
||||
|
||||
val xSafeCallCast = t?.findViewById(0) as X
|
||||
val xSafeCallCastExplicitType = t?.findViewById<X>(0) as X
|
||||
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ interface B {
|
||||
|
||||
fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
|
||||
u?.b?.foo()!! // was UNNECESSARY_SAFE_CALL everywhere, because result type (of 'foo()') wasn't made nullable
|
||||
u!!.b?.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
u!!.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
x?.b!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
// x?.b is not null
|
||||
x!!.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
@@ -22,7 +22,7 @@ fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
|
||||
// z?.nb is not null
|
||||
z!!.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
|
||||
w.b?.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
w.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
w.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
w.nb?.foo()!!
|
||||
w.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
|
||||
+1
-1
@@ -18,5 +18,5 @@ fun smartCastAfterIntersection(a: One, b: Two) = run {
|
||||
}
|
||||
|
||||
fun test(one: One, two: Two) {
|
||||
smartCastAfterIntersection(one, two)?.<!UNRESOLVED_REFERENCE!>base<!>()
|
||||
smartCastAfterIntersection(one, two)<!UNNECESSARY_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>base<!>()
|
||||
}
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
public interface B<T, Z> {
|
||||
public fun foo(a: T?)
|
||||
}
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface C<X, Z> : B<X, Z> {
|
||||
override fun foo(a: X?)
|
||||
|
||||
}
|
||||
|
||||
// MODULE: m3
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface B<Z, T> {
|
||||
public fun foo(a: T?)
|
||||
}
|
||||
|
||||
// MODULE: m4(m3, m2)
|
||||
// FILE: c.kt
|
||||
import p.*
|
||||
|
||||
fun <Y, Z> test(b: B<Y, Z>?) {
|
||||
if (b is C<Y, Z>) {
|
||||
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null)
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
+1
-1
@@ -32,6 +32,6 @@ fun test(b: B?, c: C) {
|
||||
b?.foo(1, 1)
|
||||
c.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
|
||||
if (b is C) {
|
||||
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
|
||||
b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -29,6 +29,6 @@ import p.*
|
||||
|
||||
fun test(b: B?) {
|
||||
if (b is C) {
|
||||
b?.foo(1, "")
|
||||
b<!UNNECESSARY_SAFE_CALL!>?.<!>foo(1, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-38
@@ -1,38 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
public interface B {
|
||||
public fun getParent(): B?
|
||||
}
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface C : B {
|
||||
override fun getParent(): B?
|
||||
|
||||
}
|
||||
|
||||
// MODULE: m3
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface B {
|
||||
public fun getParent(): B?
|
||||
}
|
||||
|
||||
public interface D : B {
|
||||
override fun getParent(): B?
|
||||
}
|
||||
|
||||
// MODULE: m4(m3, m2)
|
||||
// FILE: c.kt
|
||||
import p.*
|
||||
|
||||
fun test(b: B?) {
|
||||
if (b is C && b is D) {
|
||||
b?.getParent()
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
Vendored
-34
@@ -1,34 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
public interface B<T> {
|
||||
public fun foo(a: T)
|
||||
}
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface C : B<String> {
|
||||
override fun foo(a: String)
|
||||
|
||||
}
|
||||
|
||||
// MODULE: m3
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
public interface B {
|
||||
public fun foo(a: String)
|
||||
}
|
||||
|
||||
// MODULE: m4(m3, m2)
|
||||
// FILE: c.kt
|
||||
import p.*
|
||||
|
||||
fun test(b: B?) {
|
||||
if (b is C) {
|
||||
b?.foo("")
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
class A {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun A.bar() {}
|
||||
fun A?.buzz() {}
|
||||
|
||||
fun test(a : A?) {
|
||||
a<!UNSAFE_CALL!>.<!>foo() // error
|
||||
a<!UNSAFE_CALL!>.<!>bar() // error
|
||||
a.buzz()
|
||||
|
||||
a?.foo()
|
||||
a?.bar()
|
||||
a?.buzz()
|
||||
}
|
||||
|
||||
fun A.test2() {
|
||||
foo()
|
||||
bar()
|
||||
buzz()
|
||||
|
||||
this.foo()
|
||||
this.bar()
|
||||
this.buzz()
|
||||
|
||||
this?.foo() // warning
|
||||
this?.bar() // warning
|
||||
this?.buzz() // warning
|
||||
}
|
||||
|
||||
fun A?.test3() {
|
||||
<!UNSAFE_CALL!>foo<!>() // error
|
||||
<!UNSAFE_CALL!>bar<!>() // error
|
||||
buzz()
|
||||
|
||||
this<!UNSAFE_CALL!>.<!>foo() // error
|
||||
this<!UNSAFE_CALL!>.<!>bar() // error
|
||||
this.buzz()
|
||||
|
||||
this?.foo()
|
||||
this?.bar()
|
||||
this?.buzz()
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class A {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -8,7 +8,7 @@ fun <N : Number?> test(arg: N) {
|
||||
|
||||
makeDefinitelyNotNull(arg)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
|
||||
makeDefinitelyNotNull(arg)?.toInt()
|
||||
makeDefinitelyNotNull(arg)<!UNNECESSARY_SAFE_CALL!>?.<!>toInt()
|
||||
|
||||
val nullImposible = when (val dnn = makeDefinitelyNotNull(arg)) {
|
||||
null -> false
|
||||
|
||||
Vendored
+2
-2
@@ -1,14 +1,14 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun <T> test(t: T): String? {
|
||||
if (t != null) {
|
||||
return t?.toString()
|
||||
return t<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
|
||||
}
|
||||
return t?.toString()
|
||||
}
|
||||
|
||||
fun <T> T.testThis(): String? {
|
||||
if (this != null) {
|
||||
return this?.toString()
|
||||
return this<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
|
||||
}
|
||||
return this?.toString()
|
||||
}
|
||||
|
||||
+27
-27
@@ -52,40 +52,40 @@ fun foo(a: A?) {
|
||||
a?.w.inc()
|
||||
|
||||
if (a != null) {
|
||||
a?.l += 1
|
||||
a?.l[0]
|
||||
a?.l[0]++
|
||||
a?.l[0] = 1
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l += 1
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l[0]
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l[0]++
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l[0] = 1
|
||||
|
||||
a?.ll[0][0]
|
||||
a?.ll[0][0]++
|
||||
a?.ll[0][0] = 1
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]++
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0] = 1
|
||||
// No warning is reported because
|
||||
// 1. All kinds of green code with safe+call + invoke we identified fails with CCE if `a != null`, anyway
|
||||
// 2. In case of null value, the behavior is intended (no call performed)
|
||||
a?.q()
|
||||
a?.w++
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>q()
|
||||
a<!UNNECESSARY_SAFE_CALL, UNNECESSARY_SAFE_CALL!>?.<!>w++
|
||||
|
||||
(a?.l) += 1
|
||||
(a?.l)[0]
|
||||
(a?.l)[0]++
|
||||
(a?.l)[0] = 1
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>l) += 1
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>l)[0]
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>l)[0]++
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>l)[0] = 1
|
||||
|
||||
(a?.ll)[0][0]
|
||||
(a?.ll)[0][0]++
|
||||
(a?.ll)[0][0] = 1
|
||||
(a?.q)()
|
||||
(a?.w)++
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>ll)[0][0]
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>ll)[0][0]++
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>ll)[0][0] = 1
|
||||
(a<!UNNECESSARY_SAFE_CALL!>?.<!>q)()
|
||||
(a<!UNNECESSARY_SAFE_CALL, UNNECESSARY_SAFE_CALL!>?.<!>w)++
|
||||
|
||||
a?.l.plusAssign(1)
|
||||
a?.l.get(0)
|
||||
a?.l.get(0).inc()
|
||||
a?.l.set(0, 1)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l.plusAssign(1)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l.get(0)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l.get(0).inc()
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>l.set(0, 1)
|
||||
|
||||
a?.ll.get(0).get(0)
|
||||
a?.ll.get(0).get(0).inc()
|
||||
a?.ll.get(0).set(0, 1)
|
||||
a?.q.invoke()
|
||||
a?.w.inc()
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll.get(0).get(0)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll.get(0).get(0).inc()
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll.get(0).set(0, 1)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>q.invoke()
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>w.inc()
|
||||
}
|
||||
}
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// FILE: A.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class A<T> {
|
||||
public static A<String> create() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public T bar() {
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: k.kt
|
||||
|
||||
fun test() {
|
||||
A.create().bar()?.length
|
||||
A<String?>().bar()?.length
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: A.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
Vendored
-19
@@ -1,19 +0,0 @@
|
||||
// FILE: A.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class A<T> {
|
||||
@NotNull
|
||||
public T bar() {
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: k.kt
|
||||
|
||||
fun test(a: A<out CharSequence>) {
|
||||
a.bar()?.length
|
||||
a.bar()?.length
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: A.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ public class J {
|
||||
fun list(j: J): Any {
|
||||
val a = j.n()!!
|
||||
|
||||
a?.get(0)
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>get(0)
|
||||
if (a == null) {}
|
||||
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
// !DIAGNOSTICS: -SENSELESS_COMPARISON
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class J {
|
||||
@NotNull
|
||||
public static J staticNN;
|
||||
@Nullable
|
||||
public static J staticN;
|
||||
public static J staticJ;
|
||||
|
||||
public void foo() {}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
platformNN?.foo()
|
||||
platformN?.foo()
|
||||
platformJ?.foo()
|
||||
|
||||
if (platformNN != null) {
|
||||
platformNN?.foo()
|
||||
}
|
||||
|
||||
if (platformN != null) {
|
||||
platformN?.foo()
|
||||
}
|
||||
|
||||
if (platformJ != null) {
|
||||
platformJ?.foo()
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -SENSELESS_COMPARISON
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
@@ -12,7 +12,7 @@ fun test(room : Object) {
|
||||
for(item: Item? in items) {
|
||||
if (item?.room === room) {
|
||||
// item?.room is not null
|
||||
System.out.println("You see " + item?.name)
|
||||
System.out.println("You see " + item<!UNNECESSARY_SAFE_CALL!>?.<!>name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ fun main() {
|
||||
|
||||
val command : Any = 1
|
||||
|
||||
command?.equals(null)
|
||||
command<!UNNECESSARY_SAFE_CALL!>?.<!>equals(null)
|
||||
command.equals(null)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ fun testNullableReceiver(nullable: Cls?) {
|
||||
|
||||
fun testNotNullableReceiver(notNullable: Cls) {
|
||||
notNullable.<!UNSAFE_IMPLICIT_INVOKE_CALL!>nullableExtensionProperty<!>()
|
||||
notNullable?.extensionProperty()
|
||||
notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()
|
||||
}
|
||||
|
||||
fun testFlexibleReceiver() {
|
||||
|
||||
Vendored
+3
-3
@@ -5,7 +5,7 @@ fun test(foo: Foo?) {
|
||||
// Correct
|
||||
foo.bar?.length
|
||||
// Unnecessary
|
||||
foo?.bar?.length
|
||||
foo<!UNNECESSARY_SAFE_CALL!>?.<!>bar?.length
|
||||
}
|
||||
foo.bar?.length
|
||||
}
|
||||
foo.bar<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@ fun test1(a: A) {
|
||||
fun test2() {
|
||||
val a: A? = null;
|
||||
assert((a as B).bool())
|
||||
a?.bool()
|
||||
a<!UNNECESSARY_SAFE_CALL!>?.<!>bool()
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
fun test1(s: String?) {
|
||||
assert(s!!.isEmpty())
|
||||
s?.length
|
||||
s<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
}
|
||||
|
||||
fun test2(s: String?) {
|
||||
@@ -21,7 +21,7 @@ fun test3(s: String?) {
|
||||
fun test4() {
|
||||
val s: String? = null;
|
||||
assert(s!!.isEmpty())
|
||||
s?.length
|
||||
s<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
}
|
||||
|
||||
fun test5() {
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ public class Test {
|
||||
// FILE: test.kt
|
||||
fun ff() {
|
||||
val a = Test.FOO
|
||||
val b = Test?.<!UNRESOLVED_REFERENCE!>FOO<!>
|
||||
val b = Test<!UNEXPECTED_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>FOO<!>
|
||||
System.out.println(a + b)
|
||||
System?.<!UNRESOLVED_REFERENCE!>out<!>.<!UNRESOLVED_REFERENCE!>println<!>(a + b)
|
||||
System<!UNEXPECTED_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>out<!>.<!UNRESOLVED_REFERENCE!>println<!>(a + b)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user