ConstantConditionalExpressionInspection: add cast if necessary when type changes

Fixes IDEA-194648 Simpler expression auto-fix results in different code
This commit is contained in:
Tagir Valeev
2018-06-29 15:27:16 +07:00
parent 21ca5b6566
commit 04df6bad09
8 changed files with 85 additions and 11 deletions

View File

@@ -0,0 +1,7 @@
// "Simplify" "true"
class Test {
String test(String foo) {
/*always false?*/
return null;
}
}

View File

@@ -0,0 +1,6 @@
// "Simplify" "true"
class Test {
int test(int a, int b) {
return a;
}
}

View File

@@ -0,0 +1,7 @@
// "Simplify" "true"
class Test {
public static void main(String[] args) {
int i = 0;
System.out.println((int) 'x');
}
}

View File

@@ -0,0 +1,6 @@
// "Simplify" "true"
class Test {
String test(String foo) {
return (false/*always false?*/) ? foo<caret> : null;
}
}

View File

@@ -0,0 +1,6 @@
// "Simplify" "true"
class Test {
int test(int a, int b) {
return true<caret>?a:b;
}
}

View File

@@ -0,0 +1,7 @@
// "Simplify" "true"
class Test {
public static void main(String[] args) {
int i = 0;
System.out.println(false <caret>? i : 'x');
}
}

View File

@@ -19,11 +19,14 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiConditionalExpression;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeCastExpression;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.RedundantCastUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
@@ -46,20 +49,19 @@ public class ConstantConditionalExpressionInspection
@Override
@NotNull
public String buildErrorString(Object... infos) {
final PsiConditionalExpression expression =
(PsiConditionalExpression)infos[0];
return InspectionGadgetsBundle.message(
"constant.conditional.expression.problem.descriptor",
calculateReplacementExpression(expression, new CommentTracker()));
final PsiConditionalExpression expression = (PsiConditionalExpression)infos[0];
return InspectionGadgetsBundle.message("constant.conditional.expression.problem.descriptor",
calculateReplacementExpression(expression).getText());
}
static String calculateReplacementExpression(PsiConditionalExpression exp, CommentTracker commentTracker) {
@NotNull
static PsiExpression calculateReplacementExpression(@NotNull PsiConditionalExpression exp) {
final PsiExpression thenExpression = exp.getThenExpression();
final PsiExpression elseExpression = exp.getElseExpression();
final PsiExpression condition = exp.getCondition();
assert thenExpression != null;
assert elseExpression != null;
return BoolUtils.isTrue(condition) ? commentTracker.text(thenExpression) : commentTracker.text(elseExpression);
return BoolUtils.isTrue(condition) ? thenExpression : elseExpression;
}
@Override
@@ -79,9 +81,23 @@ public class ConstantConditionalExpressionInspection
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiConditionalExpression expression = (PsiConditionalExpression)descriptor.getPsiElement();
CommentTracker commentTracker = new CommentTracker();
final String newExpression = calculateReplacementExpression(expression, commentTracker);
PsiReplacementUtil.replaceExpression(expression, newExpression, commentTracker);
CommentTracker ct = new CommentTracker();
final PsiExpression replacement = calculateReplacementExpression(expression);
PsiType type = replacement.getType();
PsiType expressionType = expression.getType();
if (type != null &&
expressionType != null &&
!type.equals(expressionType) &&
PsiTypesUtil.isDenotableType(expressionType, expression)) {
PsiTypeCastExpression castExpression = (PsiTypeCastExpression)ct
.replaceAndRestoreComments(expression, "(" + expressionType.getCanonicalText() + ")" + ct.text(replacement));
if (RedundantCastUtil.isCastRedundant(castExpression)) {
RedundantCastUtil.removeCast(castExpression);
}
}
else {
ct.replaceAndRestoreComments(expression, replacement);
}
}
}

View File

@@ -0,0 +1,19 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.siyeh.ig.controlflow;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
public class ConstantConditionalExpressionInspectionFixTest extends LightQuickFixParameterizedTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
enableInspectionTool(new ConstantConditionalExpressionInspection());
}
public void test() { doAllTests(); }
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/constantConditional";
}
}