FIR checker: check if callable reference targets are allowed members

This commit is contained in:
Jinseong Jeon
2021-03-17 08:41:45 -07:00
committed by Mikhail Glukhikh
parent 6769ce0e2b
commit 8d8ed4cc18
29 changed files with 299 additions and 42 deletions
@@ -7,6 +7,6 @@ enum class D
fun main() {
<!UNRESOLVED_REFERENCE!>::A<!>
::B
::C // KT-3465
<!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>::C<!> // KT-3465
<!UNRESOLVED_REFERENCE!>::D<!>
}
}
@@ -1,5 +1,5 @@
annotation class Ann(val prop: String)
val annCtorRef = ::Ann
val annCtorRef = <!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>::Ann<!>
val annClassRef = Ann::class
val annPropRef = Ann::prop
@@ -4,11 +4,11 @@ class A {
fun A.extA(x: String) = x
fun main() {
Int::extInt
A::extA
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>Int::extInt<!>
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>A::extA<!>
eat(Int::extInt)
eat(A::extA)
eat(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>Int::extInt<!>)
eat(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>A::extA<!>)
}
}
@@ -14,10 +14,10 @@ class A {
}
fun test() {
String::ext
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>String::ext<!>
<!UNRESOLVED_REFERENCE!>Obj::ext<!>
String::ext2
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>String::ext2<!>
<!UNRESOLVED_REFERENCE!>A.Companion::ext2<!>
<!UNRESOLVED_REFERENCE!>A::ext2<!>
@@ -0,0 +1,7 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION
val i: Int = 10
get() {
<!UNSUPPORTED!>::field<!>
return field
}
@@ -0,0 +1,7 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION
val i: Int = 10
get() {
::<!UNSUPPORTED!>field<!>
return field
}
@@ -0,0 +1,3 @@
package
public val i: kotlin.Int = 10
@@ -2,7 +2,7 @@
fun a() {
val x = 10
foo(::x)
foo(<!UNSUPPORTED!>::x<!>)
}
fun foo(a: Any) {}
fun foo(a: Any) {}
@@ -5,4 +5,4 @@ fun a() {
foo(::<!UNSUPPORTED!>x<!>)
}
fun foo(a: Any) {}
fun foo(a: Any) {}
@@ -3,13 +3,13 @@
fun eat(value: Any) {}
fun test(param: String) {
val a = ::param
val a = <!UNSUPPORTED!>::param<!>
val local = "local"
val b = ::local
val b = <!UNSUPPORTED!>::local<!>
val lambda = { -> }
val g = ::lambda
val g = <!UNSUPPORTED!>::lambda<!>
eat(::param)
eat(<!UNSUPPORTED!>::param<!>)
}
@@ -9,6 +9,6 @@ class Foo {
fun main() {
val f = Foo()
val a: Int
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, ::a) // no exception after fix
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, <!UNSUPPORTED!>::a<!>) // no exception after fix
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
}
}
@@ -9,6 +9,6 @@ class Foo {
fun main(x: Int) {
val f = Foo()
val a: Int
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, ::x) // no exception after fix
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, <!UNSUPPORTED!>::x<!>) // no exception after fix
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
}
}
@@ -11,7 +11,7 @@ interface TypeConstructor
class Refiner {
val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails
val memoizedFunctionReference = createMemoizedFunction(TypeConstructor::foo) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine
val memoizedFunctionReference = createMemoizedFunction(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>TypeConstructor::foo<!>) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine
val memoizedFunctionTypes = createMemoizedFunction<TypeConstructor, Boolean> { it.foo() } // works fine
private fun TypeConstructor.foo(): Boolean = true