#ref is always inverted
boolean.variable.always.inverted.problem.descriptor=Boolean variable #ref 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 #ref
+unnecessary.explicit.numeric.cast.quickfix=Remove cast
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
index acaa5e6d3fdf..365d75710597 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
@@ -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#ref";
+ 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;
}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html
index 51a48d5d2687..0330989c2cff 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html
@@ -1,6 +1,7 @@
-
+This inspection reports any primitive numeric casts which would otherwise be inserted
+implicitly by the compiler.
New in 11, Powered by InspectionGadgets
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java
index d9894dd1674f..1d0374680be7 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java
@@ -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) {}
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml
index 5d779fbe7db2..adf186ebad97 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml
@@ -48,4 +48,49 @@