"Remove redundant let": fix destructuring declaration false positive
#KT-26042 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
7e8521d9dc
commit
2d2f1125a9
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
@@ -105,11 +106,20 @@ class ReplaceSingleLineLetIntention : SelfTargetingOffsetIndependentIntention<Kt
|
||||
val bodyExpression = lambdaExpression.bodyExpression?.children?.singleOrNull() ?: return false
|
||||
|
||||
return when (bodyExpression) {
|
||||
is KtBinaryExpression -> element.parent !is KtSafeQualifiedExpression && bodyExpression.isApplicable(parameterName)
|
||||
is KtDotQualifiedExpression -> bodyExpression.isApplicable(parameterName)
|
||||
is KtCallExpression -> element.parent !is KtSafeQualifiedExpression
|
||||
&& lambdaExpression.functionLiteral.valueParameterReferences(bodyExpression).count() <= 1
|
||||
else -> false
|
||||
is KtBinaryExpression ->
|
||||
element.parent !is KtSafeQualifiedExpression && bodyExpression.isApplicable(parameterName)
|
||||
is KtDotQualifiedExpression ->
|
||||
bodyExpression.isApplicable(parameterName)
|
||||
is KtCallExpression ->
|
||||
if (element.parent is KtSafeQualifiedExpression) {
|
||||
false
|
||||
} else {
|
||||
val count = lambdaExpression.functionLiteral.valueParameterReferences(bodyExpression).count()
|
||||
val destructuringDeclaration = lambdaExpression.functionLiteral.valueParameters.firstOrNull()?.destructuringDeclaration
|
||||
count == 0 || (count == 1 && destructuringDeclaration == null)
|
||||
}
|
||||
else ->
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,13 +173,17 @@ class ReplaceSingleLineLetIntention : SelfTargetingOffsetIndependentIntention<Kt
|
||||
private fun KtExpression.nameUsed(name: String, except: KtNameReferenceExpression? = null): Boolean =
|
||||
anyDescendantOfType<KtNameReferenceExpression> { it != except && it.getReferencedName() == name }
|
||||
|
||||
private fun KtFunctionLiteral.valueParameterReferences(callExpression: KtCallExpression): List<KtReferenceExpression> {
|
||||
private fun KtFunctionLiteral.valueParameterReferences(callExpression: KtCallExpression): List<KtNameReferenceExpression> {
|
||||
val context = analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = context[BindingContext.FUNCTION, this]?.valueParameters?.singleOrNull() ?: return emptyList()
|
||||
val name = descriptor.name.asString()
|
||||
val parameterDescriptor = context[BindingContext.FUNCTION, this]?.valueParameters?.singleOrNull() ?: return emptyList()
|
||||
val variableDescriptorByName = if (parameterDescriptor is ValueParameterDescriptorImpl.WithDestructuringDeclaration)
|
||||
parameterDescriptor.destructuringVariables.associate { it.name to it }
|
||||
else
|
||||
mapOf(parameterDescriptor.name to parameterDescriptor)
|
||||
return callExpression.valueArguments.flatMap { arg ->
|
||||
arg.collectDescendantsOfType<KtReferenceExpression>().filter {
|
||||
it.text == name && it.getResolvedCall(context)?.resultingDescriptor == descriptor
|
||||
arg.collectDescendantsOfType<KtNameReferenceExpression>().filter {
|
||||
val descriptor = variableDescriptorByName[it.getReferencedNameAsName()]
|
||||
descriptor != null && it.getResolvedCall(context)?.resultingDescriptor == descriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user