[Analysis API] Provide type mapping for callable references

Strictly speaking, callable references are not calls. However, type
arguments are still inferred for references, and 'KtCall' is the only
place in Analysis API that exposes call-substituted types.

^KT-66485 Fixed
This commit is contained in:
Yan Zhulanow
2024-02-22 02:17:14 +09:00
committed by Space Team
parent 6028595ce4
commit 0147d725fb
45 changed files with 940 additions and 6 deletions
@@ -0,0 +1,8 @@
annotation class Anno(val value: String)
fun test() {
// Annotation class cannot be instantiated
consume(<expr>::Anno</expr>)
}
fun consume(f: (String) -> Any) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = Anno
symbol = <constructor>(value: kotlin.String): Anno
valueParameters = [
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.String
symbol = value: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,15 @@
interface Foo {
fun Bar.foo(a: Int)
}
interface Bar
fun test(foo: Foo) {
with(foo) {
// 'foo' is a member and an extension at the same time.
// References to such elements are prohibited.
consume(<expr>Bar::foo</expr>)
}
}
fun consume(f: (Bar, Int) -> Unit) {}
@@ -0,0 +1,30 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: KtUsualClassType:
annotationsList: []
ownTypeArguments: []
type: Foo
type = Foo
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = Bar
returnType = kotlin.Unit
symbol = /Foo.foo(<extension receiver>: Bar, <dispatch receiver>: Foo, a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo {
fun foo(a: Int)
}
fun test(obj: Foo) {
consume(<expr>obj::foo</expr>)
}
fun consume(f: (Int) -> Unit) {}
@@ -0,0 +1,24 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = obj
isSafeNavigation = false
type = Foo
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /Foo.foo(<dispatch receiver>: Foo, a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,10 @@
class Foo {
val foo: String
get() = ""
}
fun test(obj: Foo) {
consume(<expr>obj::foo</expr>)
}
fun consume(f: () -> String) {}
@@ -0,0 +1,17 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = obj
isSafeNavigation = false
type = Foo
extensionReceiver = null
signature = KtVariableLikeSignature:
name = foo
receiverType = null
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /Foo.foo
simpleAccess = Read:
typeArgumentsMapping = {}
@@ -0,0 +1,9 @@
interface Foo
fun Foo.foo(a: Int) {}
fun test(obj: Foo) {
consume(<expr>obj::foo</expr>)
}
fun consume(f: (Int) -> Unit) {}
@@ -0,0 +1,24 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = obj
isSafeNavigation = false
type = Foo
signature = KtFunctionLikeSignature:
receiverType = Foo
returnType = kotlin.Unit
symbol = /foo(<extension receiver>: Foo, a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,10 @@
interface Foo
val Foo.foo: String
get() = ""
fun test(obj: Foo) {
consume(<expr>obj::foo</expr>)
}
fun consume(f: () -> String) {}
@@ -0,0 +1,17 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = obj
isSafeNavigation = false
type = Foo
signature = KtVariableLikeSignature:
name = foo
receiverType = Foo
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /foo
simpleAccess = Read:
typeArgumentsMapping = {}
@@ -0,0 +1,7 @@
class Foo(val value: String)
fun test() {
consume(<expr>::Foo</expr>)
}
fun consume(f: (String) -> Foo) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = Foo
symbol = <constructor>(value: kotlin.String): Foo
valueParameters = [
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.String
symbol = value: kotlin.String
callableIdIfNonLocal = null
]
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo<T> {
fun foo(value: T)
}
fun test() {
consume(<expr>Foo<Int>::foo</expr>)
}
fun consume(f: (Foo<Int>, Int) -> Unit) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /Foo.foo(<dispatch receiver>: Foo<T>, value: T): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Int
symbol = value: T
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo<T> {
fun foo(value: T)
}
fun test() {
consume(<expr>Foo<Int>::foo</expr>)
}
fun <T> consume(f: (Foo<T>, T) -> Unit) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /Foo.foo(<dispatch receiver>: Foo<T>, value: T): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Int
symbol = value: T
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo<T> {
fun foo(): T
}
fun test() {
consume(<expr>Foo<Int>::foo</expr>)
}
fun consume(f: (Foo<Int>) -> Int) {}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Int
symbol = /Foo.foo(<dispatch receiver>: Foo<T>): T
valueParameters = []
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo<T> {
fun foo(): T
}
fun test() {
consume(<expr>Foo<Int>::foo</expr>)
}
fun <T> consume(f: (Foo<T>) -> T) {}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Int
symbol = /Foo.foo(<dispatch receiver>: Foo<T>): T
valueParameters = []
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,16 @@
interface Foo {
val Bar.foo: String
get() = ""
}
interface Bar
fun test(foo: Foo) {
with(foo) {
// 'foo' is a member and an extension at the same time.
// References to such elements are prohibited.
consume(<expr>Bar::foo</expr>)
}
}
fun consume(f: (Bar) -> String) {}
@@ -0,0 +1,23 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: KtUsualClassType:
annotationsList: []
ownTypeArguments: []
type: Foo
type = Foo
extensionReceiver = null
signature = KtVariableLikeSignature:
name = foo
receiverType = Bar
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /Foo.foo
simpleAccess = Read:
typeArgumentsMapping = {}
@@ -0,0 +1,9 @@
interface Foo {
fun foo(a: Int)
}
fun test() {
consume(<expr>Foo::foo</expr>)
}
fun consume(f: (Foo, Int) -> Unit) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /Foo.foo(<dispatch receiver>: Foo, a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /Foo.foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,10 @@
class Foo {
val foo: String
get() = ""
}
fun test() {
consume(<expr>Foo::foo</expr>)
}
fun consume(f: (Foo) -> String) {}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtVariableLikeSignature:
name = foo
receiverType = null
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /Foo.foo
simpleAccess = Read:
typeArgumentsMapping = {}
@@ -0,0 +1,3 @@
fun foo() {
<expr>::foo</expr>
}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /foo(): kotlin.Unit
valueParameters = []
callableIdIfNonLocal = /foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,9 @@
interface Foo
fun Foo.foo(a: Int) {}
fun test(foo: Foo) {
consume(<expr>Foo::foo</expr>)
}
fun consume(f: (Foo, Int) -> Unit) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = Foo
returnType = kotlin.Unit
symbol = /foo(<extension receiver>: Foo, a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,10 @@
interface Foo
val Foo.foo: String
get() = ""
fun test() {
consume(<expr>Foo::foo</expr>)
}
fun consume(f: (Foo) -> String) {}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtVariableLikeSignature:
name = foo
receiverType = Foo
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /foo
simpleAccess = Read:
typeArgumentsMapping = {}
@@ -0,0 +1,7 @@
fun foo(a: Int) {}
fun test() {
consume(<expr>::foo</expr>)
}
fun consume(f: (Int) -> Unit) {}
@@ -0,0 +1,21 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /foo(a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /foo
typeArgumentsMapping = {}
argumentMapping = {}
@@ -0,0 +1,8 @@
val foo: String
get() = ""
fun test(foo: Foo) {
consume(<expr>::foo</expr>)
}
fun consume(f: () -> String) {}
@@ -0,0 +1,14 @@
KtSuccessCallInfo:
call = KtSimpleVariableAccessCall:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtVariableLikeSignature:
name = foo
receiverType = null
returnType = kotlin.String
symbol = val foo: kotlin.String
callableIdIfNonLocal = /foo
simpleAccess = Read:
typeArgumentsMapping = {}