mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
"Unnecessary explicit numeric cast" inspection improvements
This commit is contained in:
@@ -1894,3 +1894,6 @@ boolean.variable.always.inverted.display.name=Boolean variable is always inverte
|
||||
boolean.field.always.inverted.problem.descriptor=Boolean field <code>#ref</code> is always inverted
|
||||
boolean.variable.always.inverted.problem.descriptor=Boolean variable <code>#ref</code> is always inverted
|
||||
boolean.variable.always.inverted.quickfix=Invert ''{0}''
|
||||
unnecessary.explicit.numeric.cast.display.name=Unnecessary explicit numeric cast
|
||||
unnecessary.explicit.numeric.cast.problem.descriptor=''{0}'' unnecessarily cast to <code>#ref</code>
|
||||
unnecessary.explicit.numeric.cast.quickfix=Remove cast
|
||||
|
||||
+116
-53
@@ -18,28 +18,57 @@ package com.siyeh.ig.numeric;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
import com.siyeh.ig.psiutils.ExpectedTypeUtils;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
|
||||
private static final Set<IElementType> binaryPromotionOperators = new HashSet();
|
||||
static {
|
||||
binaryPromotionOperators.add(JavaTokenType.ASTERISK);
|
||||
binaryPromotionOperators.add(JavaTokenType.DIV);
|
||||
binaryPromotionOperators.add(JavaTokenType.PERC);
|
||||
binaryPromotionOperators.add(JavaTokenType.PLUS);
|
||||
binaryPromotionOperators.add(JavaTokenType.MINUS);
|
||||
binaryPromotionOperators.add(JavaTokenType.LT);
|
||||
binaryPromotionOperators.add(JavaTokenType.LE);
|
||||
binaryPromotionOperators.add(JavaTokenType.GT);
|
||||
binaryPromotionOperators.add(JavaTokenType.GE);
|
||||
binaryPromotionOperators.add(JavaTokenType.EQEQ);
|
||||
binaryPromotionOperators.add(JavaTokenType.NE);
|
||||
binaryPromotionOperators.add(JavaTokenType.AND);
|
||||
binaryPromotionOperators.add(JavaTokenType.XOR);
|
||||
binaryPromotionOperators.add(JavaTokenType.OR);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Unnecessary explicit numeric cast";
|
||||
return InspectionGadgetsBundle.message(
|
||||
"unnecessary.explicit.numeric.cast.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String buildErrorString(Object... infos) {
|
||||
final PsiExpression expression = (PsiExpression) infos[0];
|
||||
return " '" + expression.getText() + "' unnecessarily cast to <code>#ref</code>";
|
||||
return InspectionGadgetsBundle.message(
|
||||
"unnecessary.explicit.numeric.cast.problem.descriptor",
|
||||
expression.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,10 +78,12 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
|
||||
private static class UnnecessaryExplicitNumericCastFix
|
||||
extends InspectionGadgetsFix {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Remove cast";
|
||||
return InspectionGadgetsBundle.message(
|
||||
"unnecessary.explicit.numeric.cast.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +142,8 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
|
||||
static boolean isPrimitiveNumericCastNecessary(
|
||||
PsiTypeCastExpression expression) {
|
||||
final PsiType type = expression.getType();
|
||||
if (type == null) {
|
||||
final PsiType castType = expression.getType();
|
||||
if (castType == null) {
|
||||
return true;
|
||||
}
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
@@ -120,97 +151,129 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
return true;
|
||||
}
|
||||
final PsiType operandType = operand.getType();
|
||||
final PsiElement parent = expression.getParent();
|
||||
PsiElement parent = expression.getParent();
|
||||
while (parent instanceof PsiParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if (parent instanceof PsiBinaryExpression) {
|
||||
if (PsiType.INT.equals(type)) {
|
||||
return PsiType.LONG.equals(operandType) ||
|
||||
PsiType.FLOAT.equals(operandType) ||
|
||||
PsiType.DOUBLE.equals(operandType);
|
||||
}
|
||||
if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) ||
|
||||
PsiType.DOUBLE.equals(type)) {
|
||||
final PsiBinaryExpression binaryExpression =
|
||||
(PsiBinaryExpression) parent;
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
final PsiBinaryExpression binaryExpression =
|
||||
(PsiBinaryExpression) parent;
|
||||
final IElementType tokenType =
|
||||
binaryExpression.getOperationTokenType();
|
||||
if (binaryPromotionOperators.contains(tokenType)) {
|
||||
if (PsiType.INT.equals(castType)) {
|
||||
return PsiType.LONG.equals(operandType) ||
|
||||
PsiType.FLOAT.equals(operandType) ||
|
||||
PsiType.DOUBLE.equals(operandType);
|
||||
}
|
||||
|
||||
if (PsiType.LONG.equals(castType) ||
|
||||
PsiType.FLOAT.equals(castType) ||
|
||||
PsiType.DOUBLE.equals(castType)) {
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
final PsiExpression rhs = binaryExpression.getROperand();
|
||||
if (rhs == null) {
|
||||
return true;
|
||||
}
|
||||
if (expression == lhs) {
|
||||
final PsiType rhsType = rhs.getType();
|
||||
if (castType.equals(rhsType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (expression == rhs) {
|
||||
final PsiType lhsType = lhs.getType();
|
||||
if (castType.equals(lhsType)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
} else if (JavaTokenType.GTGT.equals(tokenType) ||
|
||||
JavaTokenType.GTGTGT.equals(tokenType) ||
|
||||
JavaTokenType.LTLT.equals(tokenType)) {
|
||||
final PsiExpression rhs = binaryExpression.getROperand();
|
||||
if (rhs == null) {
|
||||
if (PsiTreeUtil.isAncestor(rhs, expression, false)) {
|
||||
return false;
|
||||
}
|
||||
if (PsiType.LONG.equals(castType)) {
|
||||
return true;
|
||||
}
|
||||
if (expression == lhs) {
|
||||
final PsiType rhsType = rhs.getType();
|
||||
if (type.equals(rhsType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (expression == rhs) {
|
||||
final PsiType lhsType = lhs.getType();
|
||||
if (type.equals(lhsType)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
assert false;
|
||||
}
|
||||
return !isLegalWideningConversion(operand, PsiType.INT);
|
||||
}
|
||||
return true;
|
||||
} else if (parent instanceof PsiAssignmentExpression) {
|
||||
final PsiAssignmentExpression assignmentExpression =
|
||||
(PsiAssignmentExpression) parent;
|
||||
final PsiType lhsType = assignmentExpression.getType();
|
||||
if (!type.equals(lhsType)) {
|
||||
if (!castType.equals(lhsType)) {
|
||||
return true;
|
||||
}
|
||||
return !isHandledByAssignmentConversion(lhsType, operand);
|
||||
return !isLegalAssignmentConversion(operand, lhsType);
|
||||
} else if (parent instanceof PsiVariable) {
|
||||
final PsiVariable variable = (PsiVariable) parent;
|
||||
final PsiType lhsType = variable.getType();
|
||||
if (!type.equals(lhsType)) {
|
||||
if (!castType.equals(lhsType)) {
|
||||
return true;
|
||||
}
|
||||
return !isHandledByAssignmentConversion(lhsType, operand);
|
||||
return !isLegalAssignmentConversion(operand, lhsType);
|
||||
} else {
|
||||
final PsiType expectedType =
|
||||
ExpectedTypeUtils.findExpectedType(expression, false);
|
||||
if (!castType.equals(expectedType)) {
|
||||
return true;
|
||||
}
|
||||
return !isLegalWideningConversion(operand, castType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean isHandledByAssignmentConversion(PsiType lhsType,
|
||||
PsiExpression operand) {
|
||||
// JLS 5.2 Assignment Conversion
|
||||
final PsiType operandType = operand.getType();
|
||||
if (PsiType.DOUBLE.equals(lhsType)) {
|
||||
public static boolean isLegalWideningConversion(
|
||||
PsiExpression expression, PsiType requiredType) {
|
||||
final PsiType operandType = expression.getType();
|
||||
if (PsiType.DOUBLE.equals(requiredType)) {
|
||||
if (PsiType.FLOAT.equals(operandType) ||
|
||||
PsiType.LONG.equals(operandType) ||
|
||||
PsiType.INT.equals(operandType) ||
|
||||
PsiType.CHAR.equals(operandType) ||
|
||||
PsiType.SHORT.equals(operandType) ||
|
||||
PsiType.BYTE.equals(operandType)) {
|
||||
// widening
|
||||
return true;
|
||||
}
|
||||
} else if (PsiType.FLOAT.equals(lhsType)) {
|
||||
} else if (PsiType.FLOAT.equals(requiredType)) {
|
||||
if (PsiType.LONG.equals(operandType) ||
|
||||
PsiType.INT.equals(operandType) ||
|
||||
PsiType.CHAR.equals(operandType) ||
|
||||
PsiType.SHORT.equals(operandType) ||
|
||||
PsiType.BYTE.equals(operandType)) {
|
||||
// widening
|
||||
return true;
|
||||
}
|
||||
} else if (PsiType.LONG.equals(lhsType)) {
|
||||
} else if (PsiType.LONG.equals(requiredType)) {
|
||||
if (PsiType.INT.equals(operandType) ||
|
||||
PsiType.CHAR.equals(operandType) ||
|
||||
PsiType.SHORT.equals(operandType) ||
|
||||
PsiType.BYTE.equals(operandType)) {
|
||||
// widening
|
||||
return true;
|
||||
}
|
||||
} else if (PsiType.INT.equals(lhsType)) {
|
||||
} else if (PsiType.INT.equals(requiredType)) {
|
||||
if (PsiType.CHAR.equals(operandType) ||
|
||||
PsiType.SHORT.equals(operandType) ||
|
||||
PsiType.BYTE.equals(operandType)) {
|
||||
// widening
|
||||
return true;
|
||||
}
|
||||
} else if (PsiType.SHORT.equals(lhsType)) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isLegalAssignmentConversion(
|
||||
PsiExpression expression, PsiType assignmentType) {
|
||||
// JLS 5.2 Assignment Conversion
|
||||
final PsiType operandType = expression.getType();
|
||||
if (isLegalWideningConversion(expression, assignmentType)) {
|
||||
return true;
|
||||
} else if (PsiType.SHORT.equals(assignmentType)) {
|
||||
if (PsiType.INT.equals(operandType)) {
|
||||
final Object constant =
|
||||
ExpressionUtils.computeConstantExpression(operand);
|
||||
ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(constant instanceof Integer)) {
|
||||
return false;
|
||||
}
|
||||
@@ -220,10 +283,10 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (PsiType.CHAR.equals(lhsType)) {
|
||||
} else if (PsiType.CHAR.equals(assignmentType)) {
|
||||
if (PsiType.INT.equals(operandType)) {
|
||||
final Object constant =
|
||||
ExpressionUtils.computeConstantExpression(operand);
|
||||
ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(constant instanceof Integer)) {
|
||||
return false;
|
||||
}
|
||||
@@ -233,10 +296,10 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (PsiType.BYTE.equals(lhsType)) {
|
||||
} else if (PsiType.BYTE.equals(assignmentType)) {
|
||||
if (PsiType.INT.equals(operandType)) {
|
||||
final Object constant =
|
||||
ExpressionUtils.computeConstantExpression(operand);
|
||||
ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(constant instanceof Integer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
|
||||
This inspection reports any primitive numeric casts which would otherwise be inserted
|
||||
implicitly by the compiler.
|
||||
<p>
|
||||
<small>New in 11, Powered by InspectionGadgets</small>
|
||||
</body>
|
||||
|
||||
+14
@@ -22,4 +22,18 @@ public class UnnecessaryExplicitNumericCast {
|
||||
|
||||
double d = 123.0 / (456.0 * (double) i);
|
||||
}
|
||||
|
||||
void unary() {
|
||||
byte b = 2;
|
||||
int a[] = new int[(int)b];
|
||||
final int c = a[((int) b)];
|
||||
int[] a2 = new int[]{(int)b};
|
||||
int[] a3 = {(int)b};
|
||||
final int result = (int) b << 1;
|
||||
c((int)b);
|
||||
new UnnecessaryExplicitNumericCast((long)b);
|
||||
}
|
||||
|
||||
void c(int i) {}
|
||||
UnnecessaryExplicitNumericCast(long i) {}
|
||||
}
|
||||
|
||||
+45
@@ -48,4 +48,49 @@
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'i' unnecessarily cast to <code>double</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>28</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>29</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>30</line> <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>31</line> <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>32</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>33</line> <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>int</code></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>UnnecessaryExplicitNumericCast.java</file>
|
||||
<line>34</line> <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary explicit numeric cast</problem_class>
|
||||
<description>'b' unnecessarily cast to <code>long</code></description>
|
||||
</problem>
|
||||
</problems>
|
||||
Reference in New Issue
Block a user