[FE] Add clear warning about future changes about nullability of safe call with non nullable receiver

^KT-46860
This commit is contained in:
Dmitriy Novozhilov
2021-10-26 17:35:31 +03:00
committed by teamcityserver
parent 937f4c1dab
commit f26059a7d3
122 changed files with 323 additions and 283 deletions
@@ -1,6 +1,6 @@
fun bar(doIt: Int.() -> Int) {
1.doIt()
1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()<!>
val i: Int? = 1
<!ARGUMENT_TYPE_MISMATCH!>i<!>.doIt()
i?.doIt()
+1 -1
View File
@@ -1,6 +1,6 @@
fun bar(doIt: Int.() -> Int) {
1.doIt()
1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()<!>
val i: Int? = 1
i<!UNSAFE_CALL!>.<!>doIt()
i?.doIt()
@@ -82,6 +82,6 @@ fun test() {
val i : Int? = null
i.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()<!>
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
}
@@ -82,6 +82,6 @@ fun test() {
val i : Int? = null
i<!UNSAFE_CALL!>.<!>(fun Int.() = 1)();
{}<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>()
1<!UNNECESSARY_SAFE_CALL!>?.<!>(fun Int.() = 1)()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>1<!UNNECESSARY_SAFE_CALL!>?.<!>(fun Int.() = 1)()<!>
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
}
+1 -1
View File
@@ -18,6 +18,6 @@ fun foo() {
// these both also ok (with smart cast / unnecessary safe call)
if (rule != null) {
rule.apply()
rule<!UNNECESSARY_SAFE_CALL!>?.<!>apply()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>rule<!UNNECESSARY_SAFE_CALL!>?.<!>apply()<!>
}
}
+2 -2
View File
@@ -18,6 +18,6 @@ fun foo() {
// these both also ok (with smart cast / unnecessary safe call)
if (rule != null) {
<!DEBUG_INFO_SMARTCAST!>rule<!>.apply()
rule<!UNNECESSARY_SAFE_CALL!>?.<!>apply()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>rule<!UNNECESSARY_SAFE_CALL!>?.<!>apply()<!>
}
}
}
@@ -4,5 +4,5 @@
fun ff() {
val i: Int = 1
val a: Int = i<!UNNECESSARY_SAFE_CALL!>?.<!>plus(2)
val a: Int = <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>i<!UNNECESSARY_SAFE_CALL!>?.<!>plus(2)<!>
}
@@ -3,5 +3,5 @@
fun ff() {
val i: Int = 1
val a: Int? = i<!UNNECESSARY_SAFE_CALL!>?.<!>plus(2)
val a: Int? = <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>i<!UNNECESSARY_SAFE_CALL!>?.<!>plus(2)<!>
}
@@ -2,5 +2,5 @@ fun Int.gg() = null
fun ff() {
val a: Int = 1
val b: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>a<!UNNECESSARY_SAFE_CALL!>?.<!>gg()<!>
val b: Int = <!INITIALIZER_TYPE_MISMATCH, SAFE_CALL_WILL_CHANGE_NULLABILITY, TYPE_MISMATCH!>a<!UNNECESSARY_SAFE_CALL!>?.<!>gg()<!>
}
@@ -2,5 +2,5 @@ fun Int.gg() = null
fun ff() {
val a: Int = 1
val b: Int = <!TYPE_MISMATCH!>a<!UNNECESSARY_SAFE_CALL!>?.<!>gg()<!>
val b: Int = <!SAFE_CALL_WILL_CHANGE_NULLABILITY, TYPE_MISMATCH!>a<!UNNECESSARY_SAFE_CALL!>?.<!>gg()<!>
}
@@ -5,7 +5,7 @@ fun test11() {
fun test12() {
fun Any.bar(i: Int) {}
todo()<!UNREACHABLE_CODE!><!UNNECESSARY_SAFE_CALL!>?.<!>bar(1)<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>todo()<!UNREACHABLE_CODE!><!UNNECESSARY_SAFE_CALL!>?.<!>bar(1)<!><!>
}
fun todo(): Nothing = throw Exception()
@@ -5,7 +5,7 @@ fun test11() {
fun test12() {
fun Any.bar(<!UNUSED_PARAMETER!>i<!>: Int) {}
todo()<!UNNECESSARY_SAFE_CALL!>?.<!><!UNREACHABLE_CODE!>bar(1)<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>todo()<!UNNECESSARY_SAFE_CALL!>?.<!><!UNREACHABLE_CODE!>bar(1)<!><!>
}
fun todo(): Nothing = throw Exception()
fun todo(): Nothing = throw Exception()
@@ -8,6 +8,6 @@ fun foo(): String {
}
fun bar(): String {
val x = fn() ?: return ""
val y = x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() } <!USELESS_ELVIS!>?: "unreachable"<!>
val y = <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() }<!> <!USELESS_ELVIS!>?: "unreachable"<!>
return y
}
@@ -8,6 +8,6 @@ fun foo(): String {
}
fun bar(): String {
val x = fn() ?: return ""
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>y<!> =<!> x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() } <!UNREACHABLE_CODE, USELESS_ELVIS!>?: "unreachable"<!>
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>y<!> =<!> <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() }<!> <!UNREACHABLE_CODE, USELESS_ELVIS!>?: "unreachable"<!>
<!UNREACHABLE_CODE!>return y<!>
}
}
@@ -9,7 +9,7 @@ fun <T: Any, E> T.foo(x : E, y : A) : T {
y plus 1
y + 1.0
this<!UNNECESSARY_SAFE_CALL!>?.<!>minus<T>(this)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>minus<T>(this)<!>
return this
}
@@ -69,7 +69,7 @@ import outer.*
command?.equals1(null)
val c = Command()
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)<!>
if (command == null) 1
}
@@ -9,7 +9,7 @@ fun <T: Any, E> T.foo(x : E, y : A) : T {
y plus 1
y + 1.0
this<!UNNECESSARY_SAFE_CALL!>?.<!>minus<T>(this)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>minus<T>(this)<!>
return this
}
@@ -69,7 +69,7 @@ import outer.*
command?.equals1(null)
val c = Command()
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)<!>
if (command == null) 1
}
+4 -4
View File
@@ -27,15 +27,15 @@ fun foo(l: A<String>?) {
foo(l?.bar()) checkType { _<String?>() }
foo(l?.gav()) checkType { _<String?>() }
if (l != null) {
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
}
}
fun fooNotNull(l: A<String>) {
// No errors should be here
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
}
fun bar() {
+4 -4
View File
@@ -27,15 +27,15 @@ fun foo(l: A<String>?) {
foo(l?.bar()) checkType { _<String?>() }
foo(l?.gav()) checkType { _<String?>() }
if (l != null) {
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { _<String>() }
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { _<String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()<!>) checkType { _<String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()<!>) checkType { _<String>() }
}
}
fun fooNotNull(l: A<String>) {
// No errors should be here
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()) checkType { _<String>() }
foo(l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()) checkType { _<String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>bar()<!>) checkType { _<String>() }
foo(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>l<!UNNECESSARY_SAFE_CALL!>?.<!>gav()<!>) checkType { _<String>() }
}
fun bar() {
@@ -12,7 +12,7 @@ fun <T : CharSequence?> foo(x: T) {
if (<!SENSELESS_COMPARISON!>x != null<!>) {}
x.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
x.bar1()
x.bar2()
@@ -20,14 +20,14 @@ fun <T : CharSequence?> foo(x: T) {
x.bar4()
x<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()<!>
}
x<!UNSAFE_CALL!>.<!>length
if (x is String) {
x.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
x.bar1()
x.bar2()
@@ -36,7 +36,7 @@ fun <T : CharSequence?> foo(x: T) {
if (x is CharSequence) {
x.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
x.bar1()
x.bar2()
@@ -12,7 +12,7 @@ fun <T : CharSequence?> foo(x: T) {
if (<!SENSELESS_COMPARISON!>x != null<!>) {}
<!DEBUG_INFO_SMARTCAST!>x<!>.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!DEBUG_INFO_SMARTCAST!>x<!>.bar1()
x.bar2()
@@ -20,14 +20,14 @@ fun <T : CharSequence?> foo(x: T) {
<!DEBUG_INFO_SMARTCAST!>x<!>.bar4()
x<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()<!>
}
x<!UNSAFE_CALL!>.<!>length
if (x is String) {
<!DEBUG_INFO_SMARTCAST!>x<!>.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!DEBUG_INFO_SMARTCAST!>x<!>.bar1()
x.bar2()
@@ -36,7 +36,7 @@ fun <T : CharSequence?> foo(x: T) {
if (x is CharSequence) {
<!DEBUG_INFO_SMARTCAST!>x<!>.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!DEBUG_INFO_SMARTCAST!>x<!>.bar1()
x.bar2()
@@ -11,7 +11,7 @@ fun <T : String?> T.foo() {
if (<!SENSELESS_COMPARISON!>this != null<!>) {}
length
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
bar1()
bar2()
@@ -19,14 +19,14 @@ fun <T : String?> T.foo() {
bar4()
this<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()<!>
}
<!UNSAFE_CALL!>length<!>
if (this is String) {
length
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
bar1()
bar2()
@@ -11,7 +11,7 @@ fun <T : String?> T.foo() {
if (<!SENSELESS_COMPARISON!>this != null<!>) {}
<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>length<!>
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>bar1<!>()
bar2()
@@ -19,14 +19,14 @@ fun <T : String?> T.foo() {
<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>bar4<!>()
this<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>bar1()<!>
}
<!UNSAFE_CALL!>length<!>
if (this is String) {
<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>length<!>
this<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>bar1<!>()
bar2()
@@ -57,13 +57,13 @@ fun test() {
if (get() === null) {}
if (x != null) {
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals(1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals(1)<!>
x.equals("")
x.hashCode()
x.toString()
x.test()
x<!UNNECESSARY_SAFE_CALL!>?.<!>test2()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>test2()<!>
x.test2()
}
@@ -25,36 +25,36 @@ fun <R1 : R2, R2> build4(x: R2, @BuilderInference block: TestInterface<R1>.() ->
fun test(a: String?) {
val ret1 = build {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
}
val ret2 = build2 {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
}
val ret3 = build3 {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
}
val ret4 = build4(1) {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
@@ -34,27 +34,27 @@ fun test(a: String?) {
}
val ret2 = build2 {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
}
val ret3 = build3 {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
}
val ret4 = build4(1) {
emit(1)
get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>get()<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
val x = get()
x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>x<!UNNECESSARY_SAFE_CALL!>?.<!>equals("")<!>
x <!USELESS_ELVIS!>?: 1<!>
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
""
@@ -54,5 +54,5 @@ fun test2(t: Test?) {
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val xSafeCallCast = t?.findViewById(0) as X
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
val xSafeCallCastExplicitType = <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0)<!> as X
}
@@ -54,5 +54,5 @@ fun test2(t: Test?) {
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val xSafeCallCast = t?.findViewById(0) as X
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
val xSafeCallCastExplicitType = <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0)<!> as X
}
@@ -12,7 +12,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<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>u<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!><!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
x?.b!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
// x?.b is not null
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
@@ -23,7 +23,7 @@ fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
// z?.nb is not null
z<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
w.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>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!>!!<!>
@@ -39,4 +39,4 @@ fun doInt(i: Int) = i
fun test(a: A?) {
doInt(a?.b.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
doInt(a?.b.baz()!!)
}
}
@@ -18,5 +18,5 @@ fun smartCastAfterIntersection(a: One, b: Two) = run {
}
fun test(one: One, two: Two) {
smartCastAfterIntersection(one, two)<!UNNECESSARY_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>base<!>()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>smartCastAfterIntersection(one, two)<!UNNECESSARY_SAFE_CALL!>?.<!><!UNRESOLVED_REFERENCE!>base<!>()<!>
}
@@ -10,7 +10,7 @@ public class Throwables() {
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) : Unit {
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
{
throw declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)!!
throw <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)<!>!!
}
}
public fun propagateIfPossible(throwable : Throwable?) : Unit {
+1 -1
View File
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -UNNECESSARY_NOT_NULL_ASSERTION -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -UNNECESSARY_NOT_NULL_ASSERTION -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
fun getFun(s: (p: Int) -> Unit): Function1<Int, Int> = {11}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNNECESSARY_SAFE_CALL -UNNECESSARY_NOT_NULL_ASSERTION -CONFLICTING_JVM_DECLARATIONS
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNNECESSARY_SAFE_CALL -UNNECESSARY_NOT_NULL_ASSERTION -CONFLICTING_JVM_DECLARATIONS -SAFE_CALL_WILL_CHANGE_NULLABILITY
inline fun String.submit(action: Function1<Int, Int>) {
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -30,6 +30,6 @@ import p.*
fun <Y, Z> test(b: B<Y, Z>?) {
if (b is C<Y, Z>) {
b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null)<!>
}
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -31,6 +31,6 @@ fun test(b: B?, c: C) {
b?.foo(1, 1)
c.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
if (b is C) {
b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)<!>
}
}
@@ -31,6 +31,6 @@ fun test(b: B?, c: C) {
b?.foo(1, 1)
c.foo(1, 1)
if (b is C) {
b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!><!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, 1)<!>
}
}
@@ -31,6 +31,6 @@ import p.*
fun test(b: B?) {
if (b is C) {
b?.getParent()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b?.getParent()<!>
}
}
@@ -31,6 +31,6 @@ import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_SMARTCAST!>b<!>?.getParent()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!><!DEBUG_INFO_SMARTCAST!>b<!>?.getParent()<!>
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m0
// FILE: a.kt
@@ -41,4 +41,4 @@ fun test(b: B?) {
if (b is C) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null, null)
}
}
}
@@ -29,6 +29,6 @@ import p.*
fun test(b: B?) {
if (b is C) {
b<!UNNECESSARY_SAFE_CALL!>?.<!>foo(1, "")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!>foo(1, "")<!>
}
}
@@ -29,6 +29,6 @@ import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_SMARTCAST!>b<!><!UNNECESSARY_SAFE_CALL!>?.<!>foo(1, "")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!><!DEBUG_INFO_SMARTCAST!>b<!><!UNNECESSARY_SAFE_CALL!>?.<!>foo(1, "")<!>
}
}
}
@@ -1,4 +1,4 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -33,4 +33,4 @@ fun test(b: B?) {
if (b is C) {
b?.getParent()
}
}
}
@@ -1,4 +1,4 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -33,4 +33,4 @@ fun test(b: B?) {
if (b is C) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>getParent<!>()
}
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -38,4 +38,4 @@ fun test(b: B?) {
// as opposed to diagnostics for a single unmatched candidate
b?.<!NONE_APPLICABLE!>foo<!>()
}
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -50,4 +50,4 @@ fun test3(b: B?) {
if (b != null) {
b?.foo("")
}
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -42,4 +42,4 @@ fun test(b: B?) {
fun test1(b: B?) {
if (b !is C) return
b?.foo<String>("")
}
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
package p
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m1
// FILE: a.kt
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL -SAFE_CALL_WILL_CHANGE_NULLABILITY
// MODULE: m0
// FILE: a.kt
@@ -34,6 +34,6 @@ import p.*
fun test(b: B?) {
if (b is C && b is D) {
b<!UNNECESSARY_SAFE_CALL!>?.<!>getParent()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!>getParent()<!>
}
}
@@ -30,6 +30,6 @@ import p.*
fun test(b: B?) {
if (b is C) {
b<!UNNECESSARY_SAFE_CALL!>?.<!>foo("")
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>b<!UNNECESSARY_SAFE_CALL!>?.<!>foo("")<!>
}
}
@@ -25,9 +25,9 @@ fun A.test2() {
this.bar()
this.buzz()
this<!UNNECESSARY_SAFE_CALL!>?.<!>foo() // warning
this<!UNNECESSARY_SAFE_CALL!>?.<!>bar() // warning
this<!UNNECESSARY_SAFE_CALL!>?.<!>buzz() // warning
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!> // warning
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>bar()<!> // warning
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>buzz()<!> // warning
}
fun A?.test3() {
@@ -9,10 +9,10 @@ fun <N : Number?> test(arg: N) {
makeDefinitelyNotNull(arg)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
makeDefinitelyNotNull(arg)<!UNNECESSARY_SAFE_CALL!>?.<!>toInt()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>makeDefinitelyNotNull(arg)<!UNNECESSARY_SAFE_CALL!>?.<!>toInt()<!>
val nullImposible = when (val dnn = makeDefinitelyNotNull(arg)) {
<!SENSELESS_NULL_IN_WHEN!>null<!> -> false
else -> true
}
}
}
@@ -1,13 +1,13 @@
fun <T> test(t: T): String? {
if (t != null) {
return t<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
return <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>t<!UNNECESSARY_SAFE_CALL!>?.<!>toString()<!>
}
return t?.toString()
}
fun <T> T.testThis(): String? {
if (this != null) {
return this<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
return <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>toString()<!>
}
return this?.toString()
}
@@ -1,13 +1,13 @@
fun <T> test(t: T): String? {
if (t != null) {
return t<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
return <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>t<!UNNECESSARY_SAFE_CALL!>?.<!>toString()<!>
}
return <!DEBUG_INFO_CONSTANT!>t<!>?.toString()
}
fun <T> T.testThis(): String? {
if (this != null) {
return this<!UNNECESSARY_SAFE_CALL!>?.<!>toString()
return <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>this<!UNNECESSARY_SAFE_CALL!>?.<!>toString()<!>
}
return this?.toString()
}
@@ -52,40 +52,40 @@ fun foo(a: A?) {
a?.w.inc()
if (a != null) {
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
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!> += 1
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0]
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0]++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0] = 1
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]++
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0] = 1
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>[0][0]
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>[0][0]++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>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<!UNNECESSARY_SAFE_CALL!>?.<!>q()
a<!UNNECESSARY_SAFE_CALL, UNNECESSARY_SAFE_CALL!>?.<!>w++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q()<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY, SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL, UNNECESSARY_SAFE_CALL!>?.<!>w<!>++
(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
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>) += 1
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0]
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0]++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0] = 1
(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)++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0]
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0]++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0] = 1
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q<!>)()
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY, SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL, UNNECESSARY_SAFE_CALL!>?.<!>w<!>)++
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)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.plusAssign(1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.get(0)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.get(0).inc()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.set(0, 1)
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()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).get(0)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).get(0).inc()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).set(0, 1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q<!>.invoke()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>w<!>.inc()
}
}
@@ -52,40 +52,40 @@ fun foo(a: A?) {
a?.w.inc()
if (a != null) {
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
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!> += 1
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0]
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0]++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>[0] = 1
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0]++
a<!UNNECESSARY_SAFE_CALL!>?.<!>ll[0][0] = 1
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>[0][0]
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>[0][0]++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>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<!UNNECESSARY_SAFE_CALL!>?.<!>q()
a<!UNNECESSARY_SAFE_CALL!>?.<!>w++
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q()<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>w<!>++
(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
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>) += 1
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0]
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0]++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>)[0] = 1
(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!>?.<!>w)++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0]
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0]++
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>)[0][0] = 1
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q<!>)()
(<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>w<!>)++
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)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.plusAssign(1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.get(0)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.get(0).inc()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>l<!>.set(0, 1)
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()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).get(0)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).get(0).inc()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>ll<!>.get(0).set(0, 1)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>q<!>.invoke()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>w<!>.inc()
}
}
@@ -19,6 +19,6 @@ public class A<T> {
// FILE: k.kt
fun test() {
A.create().bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length
A<String?>().bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>A.create().bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>A<String?>().bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
}
@@ -15,6 +15,6 @@ public class A<T> {
// FILE: k.kt
fun test(a: A<out CharSequence>) {
a.bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length
a.bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a.bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a.bar()<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
}
@@ -14,7 +14,7 @@ public class J {
fun list(j: J): Any {
val a = j.n()!!
a<!UNNECESSARY_SAFE_CALL!>?.<!>get(0)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>a<!UNNECESSARY_SAFE_CALL!>?.<!>get(0)<!>
if (<!SENSELESS_COMPARISON!>a == null<!>) {}
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
@@ -25,20 +25,20 @@ fun test() {
// platform type with no annotation
val platformJ = J.staticJ
platformNN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>platformNN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!>
platformN?.foo()
platformJ?.foo()
if (platformNN != null) {
platformNN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>platformNN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!>
}
if (platformN != null) {
platformN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>platformN<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!>
}
if (platformJ != null) {
platformJ<!UNNECESSARY_SAFE_CALL!>?.<!>foo()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>platformJ<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!>
}
}
@@ -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<!UNNECESSARY_SAFE_CALL!>?.<!>name)
System.out.println("You see " + <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>item<!UNNECESSARY_SAFE_CALL!>?.<!>name<!>)
}
}
}
+2 -2
View File
@@ -12,7 +12,7 @@ fun test(room : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>Object<!>) {
for(item: Item? in items) {
if (item?.room === room) {
// item?.room is not null
System.out.println("You see " + item<!UNNECESSARY_SAFE_CALL!>?.<!>name)
System.out.println("You see " + <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>item<!UNNECESSARY_SAFE_CALL!>?.<!>name<!>)
}
}
}
}
@@ -4,6 +4,6 @@ fun main() {
val command : Any = 1
command<!UNNECESSARY_SAFE_CALL!>?.<!>equals(null)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>command<!UNNECESSARY_SAFE_CALL!>?.<!>equals(null)<!>
command.equals(null)
}
@@ -4,6 +4,6 @@ fun main() {
val command : Any = 1
command<!UNNECESSARY_SAFE_CALL!>?.<!>equals(null)
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>command<!UNNECESSARY_SAFE_CALL!>?.<!>equals(null)<!>
command.equals(null)
}
@@ -6,7 +6,7 @@ public class Throwables() {
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) {
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
{
throw declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)!!
throw <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)<!>!!
}
}
public fun propagateIfPossible(throwable : Throwable?) {
+1 -1
View File
@@ -6,7 +6,7 @@ public class Throwables() {
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) {
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
{
throw declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)!!
throw <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)<!>!!
}
}
public fun propagateIfPossible(throwable : Throwable?) {
@@ -31,7 +31,7 @@ fun testNullableReceiver(nullable: Cls?) {
fun testNotNullableReceiver(notNullable: Cls) {
notNullable.<!UNSAFE_IMPLICIT_INVOKE_CALL!>nullableExtensionProperty<!>()
notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()<!>
}
fun testFlexibleReceiver() {
@@ -31,7 +31,7 @@ fun testNullableReceiver(nullable: Cls?) {
fun testNotNullableReceiver(notNullable: Cls) {
notNullable.<!UNSAFE_IMPLICIT_INVOKE_CALL!>nullableExtensionProperty<!>()
notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()<!>
}
fun testFlexibleReceiver() {
@@ -5,7 +5,7 @@ fun test(foo: Foo?) {
// Correct
foo.bar?.length
// Unnecessary
foo<!UNNECESSARY_SAFE_CALL!>?.<!>bar?.length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>foo<!UNNECESSARY_SAFE_CALL!>?.<!>bar<!>?.length
}
foo.bar<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>foo.bar<!UNNECESSARY_SAFE_CALL!>?.<!>length<!>
}
@@ -5,7 +5,7 @@ fun test(foo: Foo?) {
// Correct
<!DEBUG_INFO_SMARTCAST!>foo<!>.bar?.length
// Unnecessary
foo<!UNNECESSARY_SAFE_CALL!>?.<!>bar?.length
<!SAFE_CALL_WILL_CHANGE_NULLABILITY!>foo<!UNNECESSARY_SAFE_CALL!>?.<!>bar<!>?.length
}
<!DEBUG_INFO_SMARTCAST!>foo<!>.bar?.length
}
}
@@ -36,7 +36,7 @@ fun foo(x: Iterator<String>, y: Iterator<String?>) {
x.forEachRemaining(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.forEachRemaining { it -> it.length }
x.forEachRemaining { it -> it<!UNNECESSARY_SAFE_CALL!>?.<!>length }
x.forEachRemaining { it -> <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>it<!UNNECESSARY_SAFE_CALL!>?.<!>length<!> }
y.forEachRemaining { it -> it<!UNSAFE_CALL!>.<!>length }
y.forEachRemaining { it -> it?.length }
}