"Replace 'if' with elvis operator": don't suggest if val initializer is a complex expression
#KT-35165 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
653e20dcba
commit
86ac44c23e
+17
-6
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.core.setType
|
import org.jetbrains.kotlin.idea.core.setType
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.isMultiLine
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.elvisPattern
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.elvisPattern
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.expressionComparedToNull
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.expressionComparedToNull
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.fromIfKeywordToRightParenthesisTextRangeInThis
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.fromIfKeywordToRightParenthesisTextRangeInThis
|
||||||
@@ -63,6 +64,11 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
|||||||
private fun applicabilityRange(element: KtIfExpression): TextRange? {
|
private fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||||
val data = calcData(element) ?: return null
|
val data = calcData(element) ?: return null
|
||||||
|
|
||||||
|
if (data.initializer !is KtParenthesizedExpression
|
||||||
|
&& data.initializer.isMultiLine()
|
||||||
|
&& createElvisExpression(element, data, KtPsiFactory(element)).left is KtParenthesizedExpression
|
||||||
|
) return null
|
||||||
|
|
||||||
val type = data.ifNullExpression.analyze().getType(data.ifNullExpression) ?: return null
|
val type = data.ifNullExpression.analyze().getType(data.ifNullExpression) ?: return null
|
||||||
if (!type.isNothing()) return null
|
if (!type.isNothing()) return null
|
||||||
|
|
||||||
@@ -72,7 +78,8 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
|||||||
fun isApplicable(element: KtIfExpression): Boolean = applicabilityRange(element) != null
|
fun isApplicable(element: KtIfExpression): Boolean = applicabilityRange(element) != null
|
||||||
|
|
||||||
fun applyTo(element: KtIfExpression): KtBinaryExpression {
|
fun applyTo(element: KtIfExpression): KtBinaryExpression {
|
||||||
val (initializer, declaration, ifNullExpr, typeReference) = calcData(element)!!
|
val data = calcData(element)!!
|
||||||
|
val (initializer, declaration, _, typeReference) = data
|
||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
|
|
||||||
val explicitTypeToSet = when {
|
val explicitTypeToSet = when {
|
||||||
@@ -90,11 +97,7 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
|||||||
val commentSaver = CommentSaver(childRangeBefore)
|
val commentSaver = CommentSaver(childRangeBefore)
|
||||||
val childRangeAfter = childRangeBefore.withoutLastStatement()
|
val childRangeAfter = childRangeBefore.withoutLastStatement()
|
||||||
|
|
||||||
val margin = CodeStyle.getSettings(element.containingKtFile).defaultRightMargin
|
val elvis = createElvisExpression(element, data, factory)
|
||||||
val declarationTextLength = declaration.text.split("\n").lastOrNull()?.trim()?.length ?: 0
|
|
||||||
val pattern = elvisPattern(declarationTextLength + ifNullExpr.textLength + 5 >= margin || element.then?.hasComments() == true)
|
|
||||||
|
|
||||||
val elvis = factory.createExpressionByPattern(pattern, initializer, ifNullExpr) as KtBinaryExpression
|
|
||||||
|
|
||||||
return runWriteAction {
|
return runWriteAction {
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
@@ -112,6 +115,14 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createElvisExpression(element: KtIfExpression, data: Data, factory: KtPsiFactory): KtBinaryExpression {
|
||||||
|
val (initializer, declaration, ifNullExpr, _) = data
|
||||||
|
val margin = CodeStyle.getSettings(element.containingKtFile).defaultRightMargin
|
||||||
|
val declarationTextLength = declaration.text.split("\n").lastOrNull()?.trim()?.length ?: 0
|
||||||
|
val pattern = elvisPattern(declarationTextLength + ifNullExpr.textLength + 5 >= margin || element.then?.hasComments() == true)
|
||||||
|
return factory.createExpressionByPattern(pattern, initializer, ifNullExpr) as KtBinaryExpression
|
||||||
|
}
|
||||||
|
|
||||||
private fun calcData(ifExpression: KtIfExpression): Data? {
|
private fun calcData(ifExpression: KtIfExpression): Data? {
|
||||||
if (ifExpression.`else` != null) return null
|
if (ifExpression.`else` != null) return null
|
||||||
|
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
private fun foo(arg: Any): Int {
|
||||||
|
val x =
|
||||||
|
if (arg is String)
|
||||||
|
(arg.length + 1)
|
||||||
|
else
|
||||||
|
arg.hashCode()
|
||||||
|
|
||||||
|
if (<caret>x == null) return 0
|
||||||
|
|
||||||
|
return x
|
||||||
|
}
|
||||||
+5
@@ -4814,6 +4814,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/Comments2.kt");
|
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/Comments2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ComplexExpression.kt")
|
||||||
|
public void testComplexExpression() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/ComplexExpression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Continue.kt")
|
@TestMetadata("Continue.kt")
|
||||||
public void testContinue() throws Exception {
|
public void testContinue() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/Continue.kt");
|
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/Continue.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user