java: redundant cast: strict check that cast in conditional branches doesn't influence top level inference

GitOrigin-RevId: e39ec399657f0f794628ef04e4fc8a308328002b
This commit is contained in:
Anna Kozlova
2020-05-15 08:33:44 +00:00
committed by intellij-monorepo-bot
parent 69fd0eb52d
commit a9c09d9c09
3 changed files with 26 additions and 9 deletions
@@ -343,11 +343,11 @@ public class RedundantCastUtil {
if (newThenExpression instanceof PsiTypeCastExpression &&
!castForBoxing(getInnerMostOperand(thenExpression), elseExpression != null ? elseExpression.getType() : null, conditionalType)) {
checkConditionalBranch(expression, newCall, oldMethod, thenExpression, newThenExpression);
checkConditionalBranch(expression, newCall, thenExpression, newThenExpression);
}
if (newElseExpression instanceof PsiTypeCastExpression &&
!castForBoxing(getInnerMostOperand(elseExpression), thenExpression != null ? thenExpression.getType() : null, conditionalType)) {
checkConditionalBranch(expression, newCall, oldMethod, elseExpression, newElseExpression);
checkConditionalBranch(expression, newCall, elseExpression, newElseExpression);
}
}
}
@@ -355,15 +355,15 @@ public class RedundantCastUtil {
private void checkConditionalBranch(PsiCall oldCall,
PsiCall newCall,
PsiMethod oldMethod,
PsiExpression oldBranchExpression,
PsiExpression newBranchExpression) {
PsiExpression operand = ((PsiTypeCastExpression)newBranchExpression).getOperand();
if (operand != null) {
newBranchExpression = (PsiExpression)newBranchExpression.replace(operand);
JavaResolveResult oldResult = oldCall.resolveMethodGenerics();
JavaResolveResult newResult = resolveNewResult(oldCall, newCall);
if (newResult.getElement() == oldMethod &&
newResult.isValidResult()) {
if (isSameResolveResult(oldResult, newResult)) {
addToResults((PsiTypeCastExpression)oldBranchExpression);
}
else {
@@ -372,6 +372,15 @@ public class RedundantCastUtil {
}
}
private static boolean isSameResolveResult(JavaResolveResult oldResult, JavaResolveResult newResult) {
PsiMethod oldMethod = (PsiMethod)oldResult.getElement();
LOG.assertTrue(oldMethod != null);
return oldMethod.equals(newResult.getElement()) &&
newResult.isValidResult() &&
!(newResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)newResult).getInferenceErrorMessage() != null) &&
recapture(newResult.getSubstitutor()).equals(oldResult.getSubstitutor());
}
private static boolean castForBoxing(PsiExpression operand, PsiType oppositeType, PsiType conditionalType) {
return operand != null &&
TypeConversionUtil.isPrimitiveAndNotNull(operand.getType()) &&
@@ -476,10 +485,7 @@ public class RedundantCastUtil {
return;
}
if (oldMethod.equals(newResult.getElement()) &&
newResult.isValidResult() &&
!(newResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)newResult).getInferenceErrorMessage() != null) &&
recapture(newResult.getSubstitutor()).equals(oldResult.getSubstitutor())) {
if (isSameResolveResult(oldResult, newResult)) {
PsiExpression newArg = PsiUtil.deparenthesizeExpression(newArgs[i]);
if (newArg instanceof PsiFunctionalExpression) {
PsiType newArgType = calculateNewArgType(i, newResult, parameters);
@@ -0,0 +1,10 @@
class Cond<T, K> {
static <A, B> Cond<A, B> create(A a, B b) {
return null;
}
void m(boolean a, Object o){
Cond<String, String> c = Cond.create(a ? (String)o : null, "");
Cond<String, String> c1 = Cond.create(a ? (String)o : "null", a ? (String)o : "null");
}
}
@@ -53,4 +53,5 @@ public class RedundantCast18Test extends LightDaemonAnalyzerTestCase {
public void testMiscStatements() { doTest();}
public void testSameSubstitutor() { doTest();}
public void testSameUpperBounds() { doTest();}
public void testSameResolveWithConditionalBranches() { doTest();}
}