diff --git a/java/java-analysis-impl/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-analysis-impl/src/com/intellij/psi/util/RedundantCastUtil.java
index e08fb39d876b..915716a1930f 100644
--- a/java/java-analysis-impl/src/com/intellij/psi/util/RedundantCastUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/psi/util/RedundantCastUtil.java
@@ -650,6 +650,59 @@ public class RedundantCastUtil {
}
}
}
+
+ @Override
+ public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
+ PsiExpression lockExpression = deparenthesizeExpression(statement.getLockExpression());
+ if (lockExpression instanceof PsiTypeCastExpression) {
+ PsiExpression operand = deparenthesizeExpression(((PsiTypeCastExpression)lockExpression).getOperand());
+ if (operand != null) {
+ PsiType opType = operand.getType();
+ if (operand instanceof PsiFunctionalExpression || opType instanceof PsiPrimitiveType || opType == null) {
+ return;
+ }
+ addIfNarrowing((PsiTypeCastExpression)lockExpression, opType);
+ }
+ }
+ super.visitSynchronizedStatement(statement);
+ }
+
+ private void addIfNarrowing(PsiTypeCastExpression lockExpression, PsiType opType) {
+ PsiTypeElement castElement = lockExpression.getCastType();
+ if (castElement != null && TypeConversionUtil.isAssignable(castElement.getType(), opType, false)) {
+ addToResults(lockExpression);
+ }
+ }
+
+ @Override
+ public void visitSwitchStatement(PsiSwitchStatement statement) {
+ visitSwitchBlock(statement);
+ super.visitSwitchStatement(statement);
+ }
+
+ @Override
+ public void visitSwitchExpression(PsiSwitchExpression expression) {
+ visitSwitchBlock(expression);
+ super.visitSwitchExpression(expression);
+ }
+
+ private void visitSwitchBlock(PsiSwitchBlock expression) {
+ PsiExpression switchVariable = deparenthesizeExpression(expression.getExpression());
+ if (switchVariable instanceof PsiTypeCastExpression) {
+ PsiExpression operand = ((PsiTypeCastExpression)switchVariable).getOperand();
+ if (operand != null) {
+ PsiType opType = operand.getType();
+ if (opType instanceof PsiClassType && PsiPrimitiveType.getUnboxedType(opType) == null && !opType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+ PsiClass aClass = ((PsiClassType)opType).resolve();
+ if (aClass != null && !aClass.isEnum()) {
+ return;
+ }
+ }
+ addIfNarrowing((PsiTypeCastExpression)switchVariable, opType);
+ }
+ }
+ }
+
private void processAlreadyHasTypeCast(PsiTypeCastExpression typeCast){
PsiElement parent = PsiUtil.skipParenthesizedExprUp(typeCast.getParent());
@@ -660,8 +713,10 @@ public class RedundantCastUtil {
if (parent instanceof PsiForeachStatement) return;
if (parent instanceof PsiInstanceOfExpression) return;
if (parent instanceof PsiThrowStatement) return;
-
+ if (parent instanceof PsiSynchronizedStatement) return;
if (parent instanceof PsiLambdaExpression) return;
+ if (parent instanceof PsiSwitchBlock) return;
+ if (parent instanceof PsiArrayAccessExpression) return;
if (isTypeCastSemantic(typeCast)) return;
@@ -674,11 +729,6 @@ public class RedundantCastUtil {
PsiType opType = operand.getType();
final PsiType expectedTypeByParent = PsiTypesUtil.getExpectedTypeByParent(typeCast);
- if (parent instanceof PsiSynchronizedStatement &&
- (opType instanceof PsiPrimitiveType || operand instanceof PsiFunctionalExpression)) {
- return;
- }
-
if (expectedTypeByParent != null) {
try {
final Project project = operand.getProject();
@@ -768,22 +818,6 @@ public class RedundantCastUtil {
}
}
}
-
- if (parent instanceof PsiSwitchBlock &&
- opType instanceof PsiClassType && PsiPrimitiveType.getUnboxedType(opType) == null && !opType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
- PsiClass aClass = ((PsiClassType)opType).resolve();
- if (aClass != null && !aClass.isEnum()) {
- return;
- }
- }
-
- if (arrayAccessAtTheLeftSideOfAssignment(parent, typeCast)) {
- if (TypeConversionUtil.isAssignable(opType, castTo, false) && opType.getArrayDimensions() == castTo.getArrayDimensions()) {
- addToResults(typeCast);
- }
- return;
- }
-
if (TypeConversionUtil.isAssignable(castTo, opType, false) &&
(expectedTypeByParent == null || TypeConversionUtil.isAssignable(expectedTypeByParent, opType, false))) {
@@ -801,24 +835,34 @@ public class RedundantCastUtil {
return true;
}
- private static boolean arrayAccessAtTheLeftSideOfAssignment(PsiElement parent, PsiElement element) {
- PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(parent, PsiAssignmentExpression.class, false, PsiMember.class);
- if (assignment == null) return false;
- PsiExpression lExpression = assignment.getLExpression();
- return lExpression instanceof PsiArrayAccessExpression &&
- PsiTreeUtil.isAncestor(lExpression, parent, false) &&
- !isIndexExpression(element, (PsiArrayAccessExpression)lExpression);
- }
-
- private static boolean isIndexExpression(PsiElement element, PsiArrayAccessExpression arrayAccessExpression) {
- if (PsiTreeUtil.isAncestor(arrayAccessExpression.getIndexExpression(), element, false)) {
- return true;
+ @Override
+ public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
+ PsiExpression arrayExpression = deparenthesizeExpression(expression.getArrayExpression());
+ if (arrayExpression instanceof PsiTypeCastExpression) {
+ PsiTypeElement castTypeElement = ((PsiTypeCastExpression)arrayExpression).getCastType();
+ PsiExpression operand = ((PsiTypeCastExpression)arrayExpression).getOperand();
+ if (castTypeElement != null && operand != null) {
+ if (PsiUtil.isAccessedForWriting(expression)) {
+ PsiType castTo = castTypeElement.getType();
+ PsiType opType = operand.getType();
+ if (opType != null && TypeConversionUtil.isAssignable(opType, castTo, false) && opType.getArrayDimensions() == castTo.getArrayDimensions()) {
+ addToResults((PsiTypeCastExpression)arrayExpression);
+ }
+ }
+ }
}
- PsiExpression arrayExpression = arrayAccessExpression.getArrayExpression();
- if (arrayExpression instanceof PsiArrayAccessExpression) {
- return isIndexExpression(element, (PsiArrayAccessExpression)arrayExpression);
+
+ PsiExpression indexExpression = deparenthesizeExpression(expression.getIndexExpression());
+ if (indexExpression instanceof PsiTypeCastExpression) {
+ PsiExpression operand = ((PsiTypeCastExpression)indexExpression).getOperand();
+ if (operand != null) {
+ PsiType opType = operand.getType();
+ if (opType != null) {
+ addIfNarrowing((PsiTypeCastExpression) indexExpression, opType);
+ }
+ }
}
- return false;
+ super.visitArrayAccessExpression(expression);
}
}
@@ -856,7 +900,8 @@ public class RedundantCastUtil {
if (opType instanceof PsiPrimitiveType) {
PsiElement parent = PsiUtil.skipParenthesizedExprUp(typeCast.getParent());
if ((parent instanceof PsiReturnStatement || parent instanceof PsiExpressionList || parent instanceof PsiVariable ||
- parent instanceof PsiAssignmentExpression) &&
+ parent instanceof PsiAssignmentExpression ||
+ parent instanceof PsiArrayAccessExpression && PsiTreeUtil.isAncestor(((PsiArrayAccessExpression)parent).getIndexExpression(), typeCast, false)) &&
castType.equals(ExpectedTypeUtils.findExpectedType(typeCast, false))) {
return !TypeConversionUtil.isSafeConversion(castType, opType); // let's suppose that casts losing precision are important
} else {
diff --git a/java/java-tests/testData/inspection/redundantCast/IDEADEV25675.java b/java/java-tests/testData/inspection/redundantCast/IDEADEV25675.java
index 8a80fbf953d0..9551968a4e73 100644
--- a/java/java-tests/testData/inspection/redundantCast/IDEADEV25675.java
+++ b/java/java-tests/testData/inspection/redundantCast/IDEADEV25675.java
@@ -18,5 +18,8 @@ class Test {
Object foo = 1;
ints[(Integer) foo] = 0;
ints[(Integer) 1] = 0;
+
+ short sh = 1;
+ ints[(int)sh] = 0;
}
}
\ No newline at end of file