"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() {
|
class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
||||||
override fun visitRangeToExpression(expression: KtExpression, holder: ProblemsHolder) {
|
override fun visitRangeToExpression(expression: KtExpression, holder: ProblemsHolder) {
|
||||||
if (expression.getArguments()?.second?.deparenthesize()?.isMinusOne() != true) return
|
if (!isApplicable(expression)) return
|
||||||
|
|
||||||
holder.registerProblem(
|
holder.registerProblem(
|
||||||
expression,
|
expression,
|
||||||
"'rangeTo' or the '..' call should be replaced with 'until'",
|
"'rangeTo' or the '..' call should be replaced with 'until'",
|
||||||
@@ -44,6 +43,20 @@ class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
|||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
val element = descriptor.psiElement as KtExpression
|
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
|
val args = element.getArguments() ?: return
|
||||||
element.replace(
|
element.replace(
|
||||||
KtPsiFactory(element).createExpressionByPattern(
|
KtPsiFactory(element).createExpressionByPattern(
|
||||||
@@ -53,15 +66,15 @@ class ReplaceRangeToWithUntilInspection : AbstractPrimitiveRangeToInspection() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun KtExpression.isMinusOne(): Boolean {
|
private fun KtExpression.isMinusOne(): Boolean {
|
||||||
if (this !is KtBinaryExpression) return false
|
if (this !is KtBinaryExpression) return false
|
||||||
if (operationToken != KtTokens.MINUS) return false
|
if (operationToken != KtTokens.MINUS) return false
|
||||||
|
|
||||||
val constantValue = right?.constantValueOrNull()
|
val constantValue = right?.constantValueOrNull()
|
||||||
val rightValue = (constantValue?.value as? Number)?.toInt() ?: return false
|
val rightValue = (constantValue?.value as? Number)?.toInt() ?: return false
|
||||||
return rightValue == 1
|
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.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
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.idea.intentions.branchedTransformations.evaluatesTo
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -49,13 +50,16 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen
|
|||||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||||
val rangeData = generateRangeExpressionData(element) ?: return
|
val rangeData = generateRangeExpressionData(element) ?: return
|
||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
element.replace(
|
val replaced = element.replace(
|
||||||
factory.createExpressionByPattern(
|
factory.createExpressionByPattern(
|
||||||
"$0 in $1..$2", rangeData.value,
|
"$0 in $1..$2", rangeData.value,
|
||||||
factory.createExpression(rangeData.min),
|
factory.createExpression(rangeData.min),
|
||||||
factory.createExpression(rangeData.max)
|
factory.createExpression(rangeData.max)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(replaced as? KtBinaryExpression)?.right?.let {
|
||||||
|
ReplaceRangeToWithUntilInspection.applyFixIfApplicable(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? {
|
private fun generateRangeExpressionData(condition: KtBinaryExpression): RangeExpressionData? {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
fun foo(bar: Int, min: Int, max: Int) {
|
fun foo(bar: Int, min: Int, max: Int) {
|
||||||
min < bar && bar < max<caret>
|
min < bar && bar < max<caret>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
fun foo(bar: Int, min: Int, max: Int) {
|
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 {
|
public void testNonConstants() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertTwoComparisonsToRangeCheck/nonConstants.kt");
|
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")
|
@TestMetadata("idea/testData/intentions/convertUnsafeCastCallToUnsafeCast")
|
||||||
|
|||||||
Reference in New Issue
Block a user