From 488e5e9f603792cfef47b3f06dca1d2aa2df02ad Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Sat, 24 Mar 2018 12:30:23 +0300 Subject: [PATCH] Do not suggest "redundant toInt() call" for comparison receiver So #KT-23133 Fixed --- ...undantCallsOfConversionMethodsIntention.kt | 45 ++++++++++++------- .../booleanToInt.kt | 7 +++ .../intentions/IntentionTestGenerated.java | 6 +++ 3 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 idea/testData/intentions/removeRedundantCallsOfConversionMethods/booleanToInt.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt index 3b9e6a7ee1f..f66e6433dbe 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt @@ -26,24 +26,30 @@ import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.callUtil.getType +import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.isFlexible class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspection( - RemoveRedundantCallsOfConversionMethodsIntention::class + RemoveRedundantCallsOfConversionMethodsIntention::class ) { override fun problemHighlightType(element: KtQualifiedExpression) = ProblemHighlightType.LIKE_UNUSED_SYMBOL } -class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeIntention(KtQualifiedExpression::class.java, "Remove redundant calls of the conversion method") { +class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeIntention( + KtQualifiedExpression::class.java, + "Remove redundant calls of the conversion method" +) { - private val targetClassMap = mapOf("toString()" to String::class.qualifiedName, - "toDouble()" to Double::class.qualifiedName, - "toFloat()" to Float::class.qualifiedName, - "toLong()" to Long::class.qualifiedName, - "toInt()" to Int::class.qualifiedName, - "toChar()" to Char::class.qualifiedName, - "toShort()" to Short::class.qualifiedName, - "toByte()" to Byte::class.qualifiedName) + private val targetClassMap = mapOf( + "toString()" to String::class.qualifiedName, + "toDouble()" to Double::class.qualifiedName, + "toFloat()" to Float::class.qualifiedName, + "toLong()" to Long::class.qualifiedName, + "toInt()" to Int::class.qualifiedName, + "toChar()" to Char::class.qualifiedName, + "toShort()" to Short::class.qualifiedName, + "toByte()" to Byte::class.qualifiedName + ) override fun applyTo(element: KtQualifiedExpression, editor: Editor?) { @@ -54,10 +60,9 @@ class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeInten val selectorExpression = element.selectorExpression ?: return null val selectorExpressionText = selectorExpression.text val qualifiedName = targetClassMap[selectorExpressionText] ?: return null - return if(element.receiverExpression.isApplicableReceiverExpression(qualifiedName)) { + return if (element.receiverExpression.isApplicableReceiverExpression(qualifiedName)) { selectorExpression.textRange - } - else { + } else { null } } @@ -67,10 +72,16 @@ class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeInten is KtStringTemplateExpression -> String::class.qualifiedName is KtConstantExpression -> getType(analyze())?.getJetTypeFqName(false) else -> { - resolveToCall()?.candidateDescriptor?.returnType?.let { - if (it.isFlexible()) null - else if (it.isMarkedNullable && parent !is KtSafeQualifiedExpression) null - else it.getJetTypeFqName(false) + val resolvedCall = resolveToCall() + if ((resolvedCall?.call?.callElement as? KtBinaryExpression)?.operationToken in OperatorConventions.COMPARISON_OPERATIONS) { + // Special case here because compareTo returns Int + Boolean::class.qualifiedName + } else { + resolvedCall?.candidateDescriptor?.returnType?.let { + if (it.isFlexible()) null + else if (it.isMarkedNullable && parent !is KtSafeQualifiedExpression) null + else it.getJetTypeFqName(false) + } } } } == qualifiedName diff --git a/idea/testData/intentions/removeRedundantCallsOfConversionMethods/booleanToInt.kt b/idea/testData/intentions/removeRedundantCallsOfConversionMethods/booleanToInt.kt new file mode 100644 index 00000000000..dc54cfd21b0 --- /dev/null +++ b/idea/testData/intentions/removeRedundantCallsOfConversionMethods/booleanToInt.kt @@ -0,0 +1,7 @@ +// IS_APPLICABLE: false + +fun Boolean.toInt() = if (this) 1 else 0 + +fun test(x: Int, y: Int): Int { + return (x > y).toInt() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index fb1a82c3229..8328343bac0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -14010,6 +14010,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeRedundantCallsOfConversionMethods"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("booleanToInt.kt") + public void testBooleanToInt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeRedundantCallsOfConversionMethods/booleanToInt.kt"); + doTest(fileName); + } + @TestMetadata("byte.kt") public void testByte() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeRedundantCallsOfConversionMethods/byte.kt");