Analysis API: Fix issues related to implicit invoke calls:

- Correctly set explicit receiver value.
- Restore original function call from FirImplicitFunctionCall (i.e.,
calls implicitly resolved to `invoke`) to get the correct name for
getting all candidates.
- Collect candidates at all tower levels.

Also make order of candidate calls in tests deterministic.
This commit is contained in:
Mark Punzalan
2022-01-31 17:58:32 +00:00
committed by Ilya Kirillov
parent ace826c570
commit 9b9da94a09
30 changed files with 763 additions and 109 deletions
@@ -0,0 +1,44 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: kotlin.String
]
argumentMapping = {},
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {}
]
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions can be called with the arguments supplied:
local final operator fun Int.invoke(b: Boolean): Unit defined in call
local final operator fun Int.invoke(a: String): Unit defined in call>
@@ -0,0 +1,7 @@
fun x(c: Char) {}
fun call(x: kotlin.Int) {
operator fun Int.invoke(a: String) {}
operator fun Int.invoke(b: Boolean) {}
<expr>x()</expr>
}
@@ -0,0 +1,42 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: kotlin.String
]
argumentMapping = {},
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {}
]
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions are applicable: [<local>/invoke, <local>/invoke]>
@@ -1,22 +1,5 @@
KtErrorCallInfo:
candidateCalls = [
KtDelegatedConstructorCall:
kind = THIS_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = Sub
symbol = <constructor>(p: kotlin.Int): Sub
valueParameters = [
KtVariableLikeSignature:
name = p
receiverType = null
returnType = kotlin.Int
symbol = p: kotlin.Int
]
argumentMapping = {},
KtDelegatedConstructorCall:
kind = THIS_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
@@ -38,6 +21,23 @@ KtErrorCallInfo:
returnType = kotlin.Int
symbol = j: kotlin.Int
]
argumentMapping = {},
KtDelegatedConstructorCall:
kind = THIS_CALL
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = Sub
symbol = <constructor>(p: kotlin.Int): Sub
valueParameters = [
KtVariableLikeSignature:
name = p
receiverType = null
returnType = kotlin.Int
symbol = p: kotlin.Int
]
argumentMapping = {}
]
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions are applicable: [/Sub.Sub, /Sub.Sub]>
@@ -11,12 +11,14 @@ KtErrorCallInfo:
symbol = /function(a: kotlin.Char): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Char
symbol = a: kotlin.Char
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Char
symbol = a: kotlin.Char)
@@ -37,12 +39,14 @@ KtErrorCallInfo:
symbol = /function(b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean)
@@ -63,12 +67,14 @@ KtErrorCallInfo:
symbol = /function(c: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: kotlin.String)
@@ -0,0 +1,7 @@
fun x(c: Char) {}
fun call(x: kotlin.Int) {
operator fun Int.invoke(a: String) {}
operator fun Int.invoke(b: Boolean) {}
<expr>x()</expr>
}
@@ -0,0 +1,69 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: kotlin.String
]
argumentMapping = {}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'a'>
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'b'>
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /x(c: kotlin.Char): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.Char
symbol = c: kotlin.Char
]
argumentMapping = {}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'c'>
@@ -11,16 +11,19 @@ KtErrorCallInfo:
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = t
receiverType = null
returnType = kotlin.Int
symbol = t: T,
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Char
symbol = a: kotlin.Char
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = t
receiverType = null
returnType = kotlin.Int
symbol = t: T)
@@ -41,16 +44,19 @@ KtErrorCallInfo:
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = u
receiverType = null
returnType = kotlin.Int
symbol = u: U,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = u
receiverType = null
returnType = kotlin.Int
symbol = u: U)
@@ -71,16 +77,19 @@ KtErrorCallInfo:
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = v
receiverType = null
returnType = kotlin.Int
symbol = v: V,
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = v
receiverType = null
returnType = kotlin.Int
symbol = v: V)
@@ -11,16 +11,19 @@ KtErrorCallInfo:
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = t
receiverType = null
returnType = T
symbol = t: T,
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Char
symbol = a: kotlin.Char
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = t
receiverType = null
returnType = T
symbol = t: T)
@@ -41,16 +44,19 @@ KtErrorCallInfo:
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = u
receiverType = null
returnType = U
symbol = u: U,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = u
receiverType = null
returnType = U
symbol = u: U)
@@ -71,16 +77,19 @@ KtErrorCallInfo:
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = v
receiverType = null
returnType = V
symbol = v: V,
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = v
receiverType = null
returnType = V
symbol = v: V)
@@ -0,0 +1,8 @@
operator fun Int.invoke(i: Int) {}
fun x(c: Char) {}
fun call(x: kotlin.Int) {
fun x(b: Boolean) {}
<expr>x(true)</expr>
}
@@ -0,0 +1,82 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = x(b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {
true -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean)
}
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /x(c: kotlin.Char): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.Char
symbol = c: kotlin.Char
]
argumentMapping = {
true -> (KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.Char
symbol = c: kotlin.Char)
}
]
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Boolean but kotlin/Char was expected>
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = /invoke(<extension receiver>: kotlin.Int, i: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = i
receiverType = null
returnType = kotlin.Int
symbol = i: kotlin.Int
]
argumentMapping = {
true -> (KtVariableLikeSignature:
name = i
receiverType = null
returnType = kotlin.Int
symbol = i: kotlin.Int)
}
]
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Boolean but kotlin/Int was expected>
@@ -0,0 +1,9 @@
operator fun Int.invoke(i: Int) {}
class A(val x: Int) {
fun x(b: Boolean) {}
}
fun call(a: A) {
<expr>a.x(1)</expr>
}
@@ -0,0 +1,56 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = a
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /A.x(<dispatch receiver>: A, b: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.Boolean
symbol = b: kotlin.Boolean)
}
]
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Int but kotlin/Boolean was expected>
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Unit
symbol = /invoke(<extension receiver>: kotlin.Int, i: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = i
receiverType = null
returnType = kotlin.Int
symbol = i: kotlin.Int
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = i
receiverType = null
returnType = kotlin.Int
symbol = i: kotlin.Int)
}
@@ -0,0 +1,6 @@
operator fun Int.invoke() : Long = 1L
operator fun Long.invoke() : Double = 1.0
operator fun Double.invoke() {}
fun test(i: Int) {
<expr>i()</expr>()()
}
@@ -0,0 +1,50 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Long
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
valueParameters = []
argumentMapping = {}
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Long
returnType = kotlin.Double
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Double
returnType = kotlin.Unit
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
@@ -0,0 +1,6 @@
operator fun Int.invoke() : Long = 1L
operator fun Long.invoke() : Double = 1.0
operator fun Double.invoke() {}
fun test(i: Int) {
<expr>i()()</expr>()
}
@@ -0,0 +1,50 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Long
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Long
returnType = kotlin.Double
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
valueParameters = []
argumentMapping = {}
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Double
returnType = kotlin.Unit
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
@@ -0,0 +1,6 @@
operator fun Int.invoke() : Long = 1L
operator fun Long.invoke() : Double = 1.0
operator fun Double.invoke() {}
fun test(i: Int) {
<expr>i()()()</expr>
}
@@ -0,0 +1,50 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.Long
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Long
returnType = kotlin.Double
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
valueParameters = []
argumentMapping = {}
]
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = i()()
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Double
returnType = kotlin.Unit
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
valueParameters = []
argumentMapping = {}
@@ -2,7 +2,9 @@ KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
dispatchReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
@@ -3,7 +3,9 @@ KtSuccessCallInfo:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
extensionReceiver = KtExplicitReceiverValue:
expression = x
isSafeNavigation = false
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.String