Reformat: ConvertLambdaToReferenceIntention

This commit is contained in:
Toshiaki Kameyama
2018-05-25 06:46:49 +03:00
committed by Mikhail Glukhikh
parent b87dd07dd1
commit 271cbc1dd3
@@ -46,10 +46,10 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
class ConvertLambdaToReferenceInspection : IntentionBasedInspection<KtLambdaExpression>(ConvertLambdaToReferenceIntention::class) class ConvertLambdaToReferenceInspection : IntentionBasedInspection<KtLambdaExpression>(ConvertLambdaToReferenceIntention::class)
open class ConvertLambdaToReferenceIntention(text: String) : open class ConvertLambdaToReferenceIntention(text: String) :
SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(KtLambdaExpression::class.java, text) { SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(KtLambdaExpression::class.java, text) {
@Suppress("unused") @Suppress("unused")
constructor(): this("Convert lambda to reference") constructor() : this("Convert lambda to reference")
open fun buildReferenceText(element: KtLambdaExpression) = buildReferenceText(lambdaExpression = element, shortTypes = false) open fun buildReferenceText(element: KtLambdaExpression) = buildReferenceText(lambdaExpression = element, shortTypes = false)
@@ -59,10 +59,10 @@ open class ConvertLambdaToReferenceIntention(text: String) :
} }
private fun isConvertibleCallInLambda( private fun isConvertibleCallInLambda(
callableExpression: KtExpression, callableExpression: KtExpression,
explicitReceiver: KtExpression? = null, explicitReceiver: KtExpression? = null,
lambdaExpression: KtLambdaExpression, lambdaExpression: KtLambdaExpression,
lambdaMustReturnUnit: Boolean lambdaMustReturnUnit: Boolean
): Boolean { ): Boolean {
val context = callableExpression.analyze() val context = callableExpression.analyze()
val calleeReferenceExpression = when (callableExpression) { val calleeReferenceExpression = when (callableExpression) {
@@ -97,10 +97,9 @@ open class ConvertLambdaToReferenceIntention(text: String) :
} }
} }
val explicitReceiverDescriptor = val explicitReceiverDescriptor = (explicitReceiver as? KtNameReferenceExpression)?.let {
(explicitReceiver as? KtNameReferenceExpression)?.let { context[REFERENCE_TARGET, it]
context[REFERENCE_TARGET, it] } as? ValueDescriptor
} as? ValueDescriptor
val lambdaValueParameterDescriptors = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return false val lambdaValueParameterDescriptors = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return false
val lambdaParameterAsExplicitReceiver = when (noBoundReferences) { val lambdaParameterAsExplicitReceiver = when (noBoundReferences) {
true -> explicitReceiver != null true -> explicitReceiver != null
@@ -115,7 +114,8 @@ open class ConvertLambdaToReferenceIntention(text: String) :
val receiverType = explicitReceiverDescriptor.type val receiverType = explicitReceiverDescriptor.type
// No exotic receiver types // No exotic receiver types
if (receiverType.isTypeParameter() || receiverType.isError || receiverType.isDynamic() || if (receiverType.isTypeParameter() || receiverType.isError || receiverType.isDynamic() ||
!receiverType.constructor.isDenotable || receiverType.isFunctionType) return false !receiverType.constructor.isDenotable || receiverType.isFunctionType
) return false
} }
// Same lambda / references function parameter order // Same lambda / references function parameter order
@@ -124,8 +124,7 @@ open class ConvertLambdaToReferenceIntention(text: String) :
val resolvedCall = callableExpression.getResolvedCall(context) ?: return false val resolvedCall = callableExpression.getResolvedCall(context) ?: return false
resolvedCall.valueArguments.entries.forEach { (valueParameter, resolvedArgument) -> resolvedCall.valueArguments.entries.forEach { (valueParameter, resolvedArgument) ->
val argumentExpression = val argumentExpression =
resolvedArgument.arguments.singleOrNull()?.getArgumentExpression() as? KtNameReferenceExpression resolvedArgument.arguments.singleOrNull()?.getArgumentExpression() as? KtNameReferenceExpression ?: return false
?: return false
val argumentTarget = context[REFERENCE_TARGET, argumentExpression] as? ValueParameterDescriptor ?: return false val argumentTarget = context[REFERENCE_TARGET, argumentExpression] as? ValueParameterDescriptor ?: return false
if (argumentTarget != lambdaValueParameterDescriptors[valueParameter.index + explicitReceiverShift]) return false if (argumentTarget != lambdaValueParameterDescriptors[valueParameter.index + explicitReceiverShift]) return false
} }
@@ -150,14 +149,21 @@ open class ConvertLambdaToReferenceIntention(text: String) :
return when (singleStatement) { return when (singleStatement) {
is KtCallExpression -> { is KtCallExpression -> {
isConvertibleCallInLambda(callableExpression = singleStatement, lambdaExpression = element, isConvertibleCallInLambda(
lambdaMustReturnUnit = lambdaMustReturnUnit) callableExpression = singleStatement,
lambdaExpression = element,
lambdaMustReturnUnit = lambdaMustReturnUnit
)
} }
is KtNameReferenceExpression -> false // Global property reference is not possible (?!) is KtNameReferenceExpression -> false // Global property reference is not possible (?!)
is KtDotQualifiedExpression -> { is KtDotQualifiedExpression -> {
val selector = singleStatement.selectorExpression ?: return false val selector = singleStatement.selectorExpression ?: return false
isConvertibleCallInLambda(callableExpression = selector, explicitReceiver = singleStatement.receiverExpression, isConvertibleCallInLambda(
lambdaExpression = element, lambdaMustReturnUnit = lambdaMustReturnUnit) callableExpression = selector,
explicitReceiver = singleStatement.receiverExpression,
lambdaExpression = element,
lambdaMustReturnUnit = lambdaMustReturnUnit
)
} }
else -> false else -> false
} }
@@ -171,8 +177,7 @@ open class ConvertLambdaToReferenceIntention(text: String) :
// Without lambda argument syntax, just replace lambda with reference // Without lambda argument syntax, just replace lambda with reference
val callableReferenceExpr = factory.createCallableReferenceExpression(referenceName) ?: return val callableReferenceExpr = factory.createCallableReferenceExpression(referenceName) ?: return
(element.replace(callableReferenceExpr) as? KtElement)?.let { ShortenReferences.RETAIN_COMPANION.process(it) } (element.replace(callableReferenceExpr) as? KtElement)?.let { ShortenReferences.RETAIN_COMPANION.process(it) }
} } else {
else {
// Otherwise, replace the whole argument list for lambda argument-using call // Otherwise, replace the whole argument list for lambda argument-using call
val outerCallExpression = lambdaArgument.parent as? KtCallExpression ?: return val outerCallExpression = lambdaArgument.parent as? KtCallExpression ?: return
val outerCalleeDescriptor = lambdaArgument.outerCalleeDescriptor() ?: return val outerCalleeDescriptor = lambdaArgument.outerCalleeDescriptor() ?: return
@@ -181,7 +186,7 @@ open class ConvertLambdaToReferenceIntention(text: String) :
val arguments = outerCallExpression.valueArguments.filter { it !is KtLambdaArgument } val arguments = outerCallExpression.valueArguments.filter { it !is KtLambdaArgument }
val hadDefaultValues = valueParameters.size - 1 > arguments.size val hadDefaultValues = valueParameters.size - 1 > arguments.size
val useNamedArguments = valueParameters.any { it.hasDefaultValue() } && hadDefaultValues val useNamedArguments = valueParameters.any { it.hasDefaultValue() } && hadDefaultValues
|| arguments.any { it.getArgumentName() != null } || arguments.any { it.getArgumentName() != null }
val newArgumentList = factory.buildValueArgumentList { val newArgumentList = factory.buildValueArgumentList {
appendFixedText("(") appendFixedText("(")
@@ -204,8 +209,7 @@ open class ConvertLambdaToReferenceIntention(text: String) :
val argumentList = outerCallExpression.valueArgumentList val argumentList = outerCallExpression.valueArgumentList
if (argumentList == null) { if (argumentList == null) {
(lambdaArgument.replace(newArgumentList) as? KtElement)?.let { ShortenReferences.RETAIN_COMPANION.process(it) } (lambdaArgument.replace(newArgumentList) as? KtElement)?.let { ShortenReferences.RETAIN_COMPANION.process(it) }
} } else {
else {
(argumentList.replace(newArgumentList) as? KtValueArgumentList)?.let { (argumentList.replace(newArgumentList) as? KtValueArgumentList)?.let {
ShortenReferences.RETAIN_COMPANION.process(it.arguments.last()) ShortenReferences.RETAIN_COMPANION.process(it.arguments.last())
} }
@@ -248,12 +252,10 @@ open class ConvertLambdaToReferenceIntention(text: String) :
val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true) val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true)
if (shortTypes) { if (shortTypes) {
"${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(receiverType)}::$selectorReferenceName" "${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(receiverType)}::$selectorReferenceName"
} } else {
else {
"${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName" "${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName"
} }
} } else {
else {
val receiverName = receiverDescriptor.importableFqName ?: receiverDescriptor.name val receiverName = receiverDescriptor.importableFqName ?: receiverDescriptor.name
"$receiverName::$selectorReferenceName" "$receiverName::$selectorReferenceName"
} }