[NI] Report unsafe implicit invoke accordingly to OI

This reverts commit df046683cc.
KT-30695
This commit is contained in:
Pavel Kirpichenkov
2020-02-13 16:13:53 +03:00
parent 1a2d28d25b
commit b161839092
30 changed files with 286 additions and 62 deletions
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
class Rule(val apply:() -> Unit)
fun bar() {}
+1 -2
View File
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
class Rule(val apply:() -> Unit)
fun bar() {}
@@ -14,7 +13,7 @@ fun foo() {
rule?.apply?.invoke()
// this should be an error
rule?.<!OI;UNSAFE_IMPLICIT_INVOKE_CALL!>apply<!>()
rule?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>apply<!>()
// these both also ok (with smart cast / unnecessary safe call)
if (rule != null) {
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
//KT-1875 Safe call should be binded with receiver or this object (but not with both by default)
package kt1875
+2 -3
View File
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
//KT-1875 Safe call should be binded with receiver or this object (but not with both by default)
package kt1875
@@ -10,13 +9,13 @@ interface T {
}
fun test(t: T) {
t<!NI;UNSAFE_CALL!>.<!><!OI;UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1) //unsafe call error
t.<!UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1) //unsafe call error
t.f?.invoke(1)
}
fun test1(t: T?) {
t<!UNSAFE_CALL!>.<!><!FUNCTION_EXPECTED!>f<!>(1) // todo resolve f as value and report UNSAFE_CALL
t<!NI;UNSAFE_CALL!>?.<!><!OI;UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1)
t?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>f<!>(1)
t<!UNSAFE_CALL!>.<!>f?.invoke(1)
t?.f?.invoke(1)
}
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
fun <E : String?, T : ((CharSequence) -> Unit)?> foo(x: E, y: T) {
if (x != null) {
y(x)
@@ -1,7 +1,6 @@
// !WITH_NEW_INFERENCE
fun <E : String?, T : ((CharSequence) -> Unit)?> foo(x: E, y: T) {
if (x != null) {
<!NI;UNSAFE_CALL, OI;UNSAFE_IMPLICIT_INVOKE_CALL!>y<!>(<!DEBUG_INFO_SMARTCAST!>x<!>)
<!UNSAFE_IMPLICIT_INVOKE_CALL!>y<!>(<!DEBUG_INFO_SMARTCAST!>x<!>)
}
if (y != null) {
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// FILE: J.java
import org.jetbrains.annotations.*;
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// FILE: J.java
import org.jetbrains.annotations.*;
@@ -19,6 +18,6 @@ public class J {
fun test() {
J.staticNN()
J<!NI;UNSAFE_CALL!>.<!><!OI;UNSAFE_IMPLICIT_INVOKE_CALL!>staticN<!>()
J.<!UNSAFE_IMPLICIT_INVOKE_CALL!>staticN<!>()
J.staticJ()
}
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
class A(val x: (String.() -> Unit)?)
fun test(a: A) {
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
class A(val x: (String.() -> Unit)?)
fun test(a: A) {
@@ -0,0 +1,18 @@
class A {
val lambda: () -> Unit = TODO()
val memberInvoke: B = TODO()
val extensionInvoke: C = TODO()
}
class B {
operator fun invoke() {}
}
class C
operator fun C.invoke() {}
fun test(a: A?) {
a?.lambda()
a?.memberInvoke()
a?.extensionInvoke()
}
@@ -0,0 +1,18 @@
class A {
val lambda: () -> Unit = TODO()
val memberInvoke: B = TODO()
val extensionInvoke: C = TODO()
}
class B {
operator fun invoke() {}
}
class C
operator fun C.invoke() {}
fun test(a: A?) {
a?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>lambda<!>()
a?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>memberInvoke<!>()
a?.extensionInvoke()
}
@@ -0,0 +1,29 @@
package
public fun test(/*0*/ a: A?): kotlin.Unit
public operator fun C.invoke(): kotlin.Unit
public final class A {
public constructor A()
public final val extensionInvoke: C
public final val lambda: () -> kotlin.Unit
public final val memberInvoke: B
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class B {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class C {
public constructor C()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,25 @@
class MemberInvokeOwner {
operator fun invoke() {}
}
class Cls {
fun testImplicitReceiver() {
<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
}
}
val Cls.nullableExtensionProperty: MemberInvokeOwner?
get() = null
val Cls.extensionProperty: MemberInvokeOwner
get() = TODO()
fun testNullableReceiver(nullable: Cls?) {
nullable?.extensionProperty()
nullable.<!UNRESOLVED_REFERENCE!>extensionProperty<!>()
}
fun testNotNullableReceiver(notNullable: Cls) {
notNullable.<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
notNullable?.extensionProperty()
}
@@ -0,0 +1,25 @@
class MemberInvokeOwner {
operator fun invoke() {}
}
class Cls {
fun testImplicitReceiver() {
<!UNSAFE_IMPLICIT_INVOKE_CALL!>nullableExtensionProperty<!>()
}
}
val Cls.nullableExtensionProperty: MemberInvokeOwner?
get() = null
val Cls.extensionProperty: MemberInvokeOwner
get() = TODO()
fun testNullableReceiver(nullable: Cls?) {
nullable?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>extensionProperty<!>()
nullable<!UNSAFE_CALL!>.<!><!FUNCTION_EXPECTED!>extensionProperty<!>()
}
fun testNotNullableReceiver(notNullable: Cls) {
notNullable.<!UNSAFE_IMPLICIT_INVOKE_CALL!>nullableExtensionProperty<!>()
notNullable<!UNNECESSARY_SAFE_CALL!>?.<!>extensionProperty()
}
@@ -0,0 +1,22 @@
package
public val Cls.extensionProperty: MemberInvokeOwner
public val Cls.nullableExtensionProperty: MemberInvokeOwner?
public fun testNotNullableReceiver(/*0*/ notNullable: Cls): kotlin.Unit
public fun testNullableReceiver(/*0*/ nullable: Cls?): kotlin.Unit
public final class Cls {
public constructor Cls()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun testImplicitReceiver(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class MemberInvokeOwner {
public constructor MemberInvokeOwner()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// !LANGUAGE: -SafeCastCheckBoundSmartCasts -BooleanElvisBoundSmartCasts
// A set of examples for
// "If the result of a safe call is not null, understand that its receiver is not null"
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// !LANGUAGE: -SafeCastCheckBoundSmartCasts -BooleanElvisBoundSmartCasts
// A set of examples for
// "If the result of a safe call is not null, understand that its receiver is not null"
@@ -130,7 +129,7 @@ class Invokable(val x: String) {
class InvokableProperty(val i: Invokable)
fun checkInvokable(ip: InvokableProperty?) {
if (ip?.<!OI;UNSAFE_IMPLICIT_INVOKE_CALL!>i<!>() == "Hello") {
if (ip?.<!UNSAFE_IMPLICIT_INVOKE_CALL!>i<!>() == "Hello") {
<!DEBUG_INFO_SMARTCAST!>ip<!>.hashCode()
}
}