"Convert to range check" inspection: apply ReplaceRangeToWithUntilInspection after convertion
#KT-33880 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
54df0aad16
commit
82f75c707e
+22
-9
@@ -27,8 +27,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
|
||||
class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
||||
override fun visitRangeToExpression(expression: KtExpression, holder: ProblemsHolder) {
|
||||
if (expression.getArguments()?.second?.deparenthesize()?.isMinusOne() != true) return
|
||||
|
||||
if (!isApplicable(expression)) return
|
||||
holder.registerProblem(
|
||||
expression,
|
||||
"'rangeTo' or the '..' call should be replaced with 'until'",
|
||||
@@ -44,6 +43,20 @@ class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement as KtExpression
|
||||
applyFix(element)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun applyFixIfApplicable(expression: KtExpression) {
|
||||
if (isApplicable(expression)) applyFix(expression)
|
||||
}
|
||||
|
||||
private fun isApplicable(expression: KtExpression): Boolean {
|
||||
return expression.getArguments()?.second?.deparenthesize()?.isMinusOne() == true
|
||||
}
|
||||
|
||||
private fun applyFix(element: KtExpression) {
|
||||
val args = element.getArguments() ?: return
|
||||
element.replace(
|
||||
KtPsiFactory(element).createExpressionByPattern(
|
||||
@@ -53,15 +66,15 @@ class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtExpression.isMinusOne(): Boolean {
|
||||
if (this !is KtBinaryExpression) return false
|
||||
if (operationToken != KtTokens.MINUS) return false
|
||||
private fun KtExpression.isMinusOne(): Boolean {
|
||||
if (this !is KtBinaryExpression) return false
|
||||
if (operationToken != KtTokens.MINUS) return false
|
||||
|
||||
val constantValue = right?.constantValueOrNull()
|
||||
val rightValue = (constantValue?.value as? Number)?.toInt() ?: return false
|
||||
return rightValue == 1
|
||||
val constantValue = right?.constantValueOrNull()
|
||||
val rightValue = (constantValue?.value as? Number)?.toInt() ?: return false
|
||||
return rightValue == 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -21,6 +21,7 @@ import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
import org.jetbrains.kotlin.idea.inspections.ReplaceRangeToWithUntilInspection
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -49,13 +50,16 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||
val rangeData = generateRangeExpressionData(element) ?: return
|
||||
val factory = KtPsiFactory(element)
|
||||
element.replace(
|
||||
val replaced = element.replace(
|
||||
factory.createExpressionByPattern(
|
||||
"$0 in $1..$2", rangeData.value,
|
||||
factory.createExpression(rangeData.min),
|
||||
factory.createExpression(rangeData.max)
|
||||
)
|
||||
)
|
||||
(replaced as? KtBinaryExpression)?.right?.let {
|
||||
ReplaceRangeToWithUntilInspection.applyFixIfApplicable(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(bar: Int, min: Int, max: Int) {
|
||||
min < bar && bar < max<caret>
|
||||
}
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(bar: Int, min: Int, max: Int) {
|
||||
bar in (min + 1)..(max - 1)
|
||||
bar in (min + 1) until max
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
val N = 42
|
||||
fun test(a: Int) = a >= 0 && a < N<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
val N = 42
|
||||
fun test(a: Int) = a in 0 until N
|
||||
@@ -7809,6 +7809,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
public void testNonConstants() throws Exception {
|
||||
runTest("idea/testData/intentions/convertTwoComparisonsToRangeCheck/nonConstants.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("until.kt")
|
||||
public void testUntil() throws Exception {
|
||||
runTest("idea/testData/intentions/convertTwoComparisonsToRangeCheck/until.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/convertUnsafeCastCallToUnsafeCast")
|
||||
|
||||
Reference in New Issue
Block a user