KT-8365 Bogus "Receiver never used" warning when receiver is used in invoke() convention call

#KT-8365 fixed
This commit is contained in:
Evgeny Gerashchenko
2015-12-17 13:31:43 +03:00
parent 2e6d82a72b
commit 9aa38d99fb
2 changed files with 47 additions and 3 deletions
@@ -28,7 +28,10 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isOverridable
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
public class UnusedReceiverParameterInspection : AbstractKotlinInspection() {
@@ -53,13 +56,25 @@ public class UnusedReceiverParameterInspection : AbstractKotlinInspection() {
val bindingContext = element.analyze()
val resolvedCall = element.getResolvedCall(bindingContext) ?: return
if (isUsageOfReceiver(resolvedCall, bindingContext)) {
used = true
} else if (resolvedCall is VariableAsFunctionResolvedCall
&& isUsageOfReceiver(resolvedCall.variableCall, bindingContext)) {
used = true
}
}
private fun isUsageOfReceiver(resolvedCall: ResolvedCall<*>, bindingContext: BindingContext): Boolean {
// As receiver of call
if (resolvedCall.dispatchReceiver.getThisReceiverOwner(bindingContext) == callable ||
(resolvedCall.extensionReceiver as ReceiverValue?).getThisReceiverOwner(bindingContext) == callable) {
used = true
return true
}
else if ((resolvedCall.candidateDescriptor as? ReceiverParameterDescriptor)?.containingDeclaration == callable) {
used = true
// As explicit "this"
if ((resolvedCall.candidateDescriptor as? ReceiverParameterDescriptor)?.containingDeclaration == callable) {
return true
}
return false
}
})
@@ -0,0 +1,29 @@
// KT-8365 Bogus "Receiver never used" warning
class FunctionLike {
fun invoke() {}
}
class OwnerClass {
val functionLike = FunctionLike()
val function = { }
}
val OwnerClass.extFunctionLike = FunctionLike()
val OwnerClass.extFunction = { }
fun OwnerClass.f1() {
functionLike()
}
fun OwnerClass.f2() {
function()
}
fun OwnerClass.f3() {
extFunctionLike()
}
fun OwnerClass.f4() {
extFunction()
}