From 24579c27a20ec388cd89b5a42a548ba176057c88 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Wed, 1 Aug 2018 16:10:15 +0300 Subject: [PATCH] Extract common part in inspections that checks usage of descriptor in some call --- .../inspections/RedundantWithInspection.kt | 25 ++------- .../UnusedReceiverParameterInspection.kt | 51 ++++++++++--------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt index 7b5b3012f4e..8b4bf8af8da 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt @@ -14,14 +14,11 @@ import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.moveCaret import org.jetbrains.kotlin.idea.core.replaced -import org.jetbrains.kotlin.idea.util.getThisReceiverOwner import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.startOffset 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.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -42,7 +39,7 @@ class RedundantWithInspection : AbstractKotlinInspection() { if (callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe != FqName("kotlin.with")) return val lambdaDescriptor = context[BindingContext.FUNCTION, lambda.functionLiteral] ?: return - val lambdaExtensionReceiver = lambdaDescriptor.extensionReceiverParameter + var used = false lambda.functionLiteral.acceptChildren(object : KtVisitorVoid() { override fun visitKtElement(element: KtElement) { @@ -55,27 +52,13 @@ class RedundantWithInspection : AbstractKotlinInspection() { } val resolvedCall = element.getResolvedCall(context) ?: return - if (isUsageOfReceiver(resolvedCall, context)) { - used = true - } else if (resolvedCall is VariableAsFunctionResolvedCall && isUsageOfReceiver(resolvedCall.variableCall, context)) { - used = true - } - } - private fun isUsageOfReceiver(resolvedCall: ResolvedCall<*>, bindingContext: BindingContext): Boolean { - // As receiver of call - if (resolvedCall.dispatchReceiver.getThisReceiverOwner(bindingContext) == lambdaDescriptor || - resolvedCall.extensionReceiver.getThisReceiverOwner(bindingContext) == lambdaDescriptor - ) { - return true + if (isUsageOfDescriptor(lambdaDescriptor, resolvedCall, context)) { + used = true } - // As explicit "this" - if (resolvedCall.candidateDescriptor == lambdaExtensionReceiver) { - return true - } - return false } }) + if (!used) { val quickfix = when (receiver) { is KtSimpleNameExpression, is KtStringTemplateExpression, is KtConstantExpression -> RemoveRedundantWithFix() diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt index be5a108b7bb..a55771fa673 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.MainFunctionDetector @@ -69,16 +70,16 @@ class UnusedReceiverParameterInspection : AbstractKotlinInspection() { callableDeclaration.isOverridable() ) return - val context = receiverTypeReference.analyze() + val context = callableDeclaration.analyze() val receiverType = context[BindingContext.TYPE, receiverTypeReference] ?: return val receiverTypeDeclaration = receiverType.constructor.declarationDescriptor if (DescriptorUtils.isCompanionObject(receiverTypeDeclaration)) return - val callable = callableDeclaration.descriptor + val callable = callableDeclaration.descriptor ?: return - if (callable != null && MainFunctionDetector.isMain(callable)) return + if (MainFunctionDetector.isMain(callable)) return - val containingDeclaration = callable?.containingDeclaration + val containingDeclaration = callable.containingDeclaration if (containingDeclaration != null && containingDeclaration == receiverTypeDeclaration) { val thisLabelName = containingDeclaration.getThisLabelName() if (!callableDeclaration.anyDescendantOfType { it.getLabelName() == thisLabelName }) { @@ -93,31 +94,12 @@ class UnusedReceiverParameterInspection : AbstractKotlinInspection() { if (used) return element.acceptChildren(this) - val bindingContext = element.analyze() - val resolvedCall = element.getResolvedCall(bindingContext) ?: return + val resolvedCall = element.getResolvedCall(context) ?: return - if (isUsageOfReceiver(resolvedCall, bindingContext)) { - used = true - } else if (resolvedCall is VariableAsFunctionResolvedCall - && isUsageOfReceiver(resolvedCall.variableCall, bindingContext) - ) { + if (isUsageOfDescriptor(callable, resolvedCall, context)) { used = true } } - - private fun isUsageOfReceiver(resolvedCall: ResolvedCall<*>, bindingContext: BindingContext): Boolean { - // As receiver of call - if (resolvedCall.dispatchReceiver.getThisReceiverOwner(bindingContext) == callable || - resolvedCall.extensionReceiver.getThisReceiverOwner(bindingContext) == callable - ) { - return true - } - // As explicit "this" - if ((resolvedCall.candidateDescriptor as? ReceiverParameterDescriptor)?.containingDeclaration == callable) { - return true - } - return false - } }) if (!used) registerProblem(receiverTypeReference) @@ -175,3 +157,22 @@ class UnusedReceiverParameterInspection : AbstractKotlinInspection() { override fun startInWriteAction() = false } } + +fun isUsageOfDescriptor(descriptor: DeclarationDescriptor, resolvedCall: ResolvedCall<*>, bindingContext: BindingContext): Boolean { + // As receiver of call + if (resolvedCall.dispatchReceiver.getThisReceiverOwner(bindingContext) == descriptor || + resolvedCall.extensionReceiver.getThisReceiverOwner(bindingContext) == descriptor + ) { + return true + } + // As explicit "this" + if ((resolvedCall.candidateDescriptor as? ReceiverParameterDescriptor)?.containingDeclaration == descriptor) { + return true + } + + if (resolvedCall is VariableAsFunctionResolvedCall) { + return isUsageOfDescriptor(descriptor, resolvedCall.variableCall, bindingContext) + } + + return false +} \ No newline at end of file