mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java redundant cast: cleanup: avoid dbl cast registration for expressions with expected type
GitOrigin-RevId: a31b1d892b2e19bfaf556e85724eb244189111b4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c3bda2dac0
commit
efc6106e02
@@ -34,7 +34,7 @@ public class RedundantCastUtil {
|
||||
@NotNull
|
||||
public static List<PsiTypeCastExpression> getRedundantCastsInside(@NotNull PsiElement where) {
|
||||
MyCollectingVisitor visitor = new MyCollectingVisitor();
|
||||
if (where instanceof PsiEnumConstant) {
|
||||
if (where instanceof PsiField) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
else {
|
||||
@@ -74,11 +74,6 @@ public class RedundantCastUtil {
|
||||
// avoid multiple visit
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitField(PsiField field) {
|
||||
// avoid multiple visit
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerCast(@NotNull PsiTypeCastExpression typeCast) {
|
||||
myFoundCasts.add(typeCast);
|
||||
@@ -176,41 +171,31 @@ public class RedundantCastUtil {
|
||||
private void processPossibleTypeCast(PsiExpression rExpr, @Nullable PsiType lType) {
|
||||
rExpr = deparenthesizeExpression(rExpr);
|
||||
if (rExpr instanceof PsiTypeCastExpression) {
|
||||
PsiExpression castOperand = deparenthesizeExpression(((PsiTypeCastExpression)rExpr).getOperand());
|
||||
PsiExpression castOperand = getInnerMostOperand(((PsiTypeCastExpression)rExpr));
|
||||
if (castOperand != null) {
|
||||
if (castOperand instanceof PsiFunctionalExpression && lType != null) {
|
||||
final PsiTypeElement typeElement = ((PsiTypeCastExpression)rExpr).getCastType();
|
||||
final PsiType castType = typeElement != null ? typeElement.getType() : null;
|
||||
if (lType.equals(castType)) {
|
||||
addToResults((PsiTypeCastExpression)rExpr);
|
||||
if (castOperand instanceof PsiFunctionalExpression) {
|
||||
if (lType != null) {
|
||||
final PsiTypeElement typeElement = ((PsiTypeCastExpression)rExpr).getCastType();
|
||||
final PsiType castType = typeElement != null ? typeElement.getType() : null;
|
||||
if (lType.equals(castType)) {
|
||||
addToResults((PsiTypeCastExpression)rExpr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
PsiType operandType = getNestedCastOperandType(castOperand);
|
||||
if (operandType != null) {
|
||||
if (lType != null && TypeConversionUtil.isAssignable(lType, operandType, false)) {
|
||||
PsiType opType = getOpTypeWithExpected(castOperand, lType);
|
||||
if (opType != null) {
|
||||
if (castOperand instanceof PsiConditionalExpression) {
|
||||
if (!isApplicableForConditionalBranch(opType, ((PsiConditionalExpression)castOperand).getThenExpression())) return;
|
||||
if (!isApplicableForConditionalBranch(opType, ((PsiConditionalExpression)castOperand).getElseExpression())) return;
|
||||
}
|
||||
if (lType != null && TypeConversionUtil.isAssignable(lType, opType, false)) {
|
||||
addToResults((PsiTypeCastExpression)rExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiType getNestedCastOperandType(PsiExpression castOperand) {
|
||||
if (castOperand instanceof PsiTypeCastExpression) {
|
||||
PsiExpression nestedCastOperand = ((PsiTypeCastExpression)castOperand).getOperand();
|
||||
while (nestedCastOperand instanceof PsiTypeCastExpression) {
|
||||
nestedCastOperand = deparenthesizeExpression(((PsiTypeCastExpression)nestedCastOperand).getOperand());
|
||||
}
|
||||
return nestedCastOperand != null ? nestedCastOperand.getType() : null;
|
||||
}
|
||||
else if (castOperand instanceof PsiFunctionalExpression) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return castOperand.getType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
@@ -259,10 +244,7 @@ public class RedundantCastUtil {
|
||||
PsiExpression qualifier = deparenthesizeExpression(expression.getQualifierExpression());
|
||||
if (qualifier instanceof PsiTypeCastExpression) {
|
||||
PsiTypeCastExpression typeCast = (PsiTypeCastExpression)qualifier;
|
||||
PsiExpression operand = deparenthesizeExpression(typeCast.getOperand());
|
||||
while (operand instanceof PsiTypeCastExpression) {
|
||||
operand = deparenthesizeExpression(((PsiTypeCastExpression)operand).getOperand());
|
||||
}
|
||||
PsiExpression operand = getInnerMostOperand(typeCast);
|
||||
if (operand == null) return;
|
||||
|
||||
PsiTypeElement typeElement = typeCast.getCastType();
|
||||
@@ -278,6 +260,14 @@ public class RedundantCastUtil {
|
||||
super.visitReferenceExpression(expression);
|
||||
}
|
||||
|
||||
private static PsiExpression getInnerMostOperand(PsiTypeCastExpression typeCast) {
|
||||
PsiExpression operand = deparenthesizeExpression(typeCast.getOperand());
|
||||
while (operand instanceof PsiTypeCastExpression) {
|
||||
operand = deparenthesizeExpression(((PsiTypeCastExpression)operand).getOperand());
|
||||
}
|
||||
return operand;
|
||||
}
|
||||
|
||||
private static boolean isCastInReferenceQualifierRedundant(final PsiReferenceExpression refExpression,
|
||||
final PsiExpression castOperand) {
|
||||
final JavaResolveResult resolveResult = refExpression.advancedResolve(false);
|
||||
@@ -627,9 +617,9 @@ public class RedundantCastUtil {
|
||||
if (checkTypeElement == null) return;
|
||||
PsiExpression typeCast = deparenthesizeExpression(expression.getOperand());
|
||||
if (typeCast instanceof PsiTypeCastExpression) {
|
||||
PsiExpression operand = ((PsiTypeCastExpression)typeCast).getOperand();
|
||||
PsiExpression operand = getInnerMostOperand((PsiTypeCastExpression)typeCast);
|
||||
if (operand != null) {
|
||||
PsiType opType = getNestedCastOperandType(operand);
|
||||
PsiType opType = operand.getType();
|
||||
//15.20.2. Type Comparison Operator instanceof:
|
||||
//If a cast (p15.16) of the RelationalExpression to the ReferenceType would be rejected as a compile-time error,
|
||||
//then the instanceof relational expression likewise produces a compile-time error.
|
||||
@@ -647,9 +637,9 @@ public class RedundantCastUtil {
|
||||
public void visitThrowStatement(PsiThrowStatement statement) {
|
||||
PsiExpression typeCast = deparenthesizeExpression(statement.getException());
|
||||
if (typeCast instanceof PsiTypeCastExpression) {
|
||||
PsiExpression operand = ((PsiTypeCastExpression)typeCast).getOperand();
|
||||
PsiExpression operand = getInnerMostOperand((PsiTypeCastExpression)typeCast);
|
||||
if (operand != null) {
|
||||
PsiType opType = getNestedCastOperandType(operand);
|
||||
PsiType opType = operand.getType();
|
||||
final PsiClass thrownClass = PsiUtil.resolveClassInType(opType);
|
||||
if (InheritanceUtil.isInheritor(thrownClass, false, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION)) {
|
||||
addToResults((PsiTypeCastExpression)typeCast);
|
||||
@@ -690,10 +680,7 @@ public class RedundantCastUtil {
|
||||
public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
|
||||
PsiExpression lockExpression = deparenthesizeExpression(statement.getLockExpression());
|
||||
if (lockExpression instanceof PsiTypeCastExpression) {
|
||||
PsiExpression operand = deparenthesizeExpression(((PsiTypeCastExpression)lockExpression).getOperand());
|
||||
while (operand instanceof PsiTypeCastExpression) {
|
||||
operand = deparenthesizeExpression(((PsiTypeCastExpression)operand).getOperand());
|
||||
}
|
||||
PsiExpression operand = getInnerMostOperand((PsiTypeCastExpression)lockExpression);
|
||||
if (operand != null) {
|
||||
PsiType opType = operand.getType();
|
||||
if (!(operand instanceof PsiFunctionalExpression) && !(opType instanceof PsiPrimitiveType) && opType != null) {
|
||||
@@ -748,6 +735,9 @@ public class RedundantCastUtil {
|
||||
if (parent instanceof PsiSwitchBlock) return;
|
||||
if (parent instanceof PsiArrayAccessExpression) return;
|
||||
if (parent instanceof PsiReferenceExpression) return;
|
||||
if (parent instanceof PsiAssignmentExpression) return;
|
||||
if (parent instanceof PsiVariable) return;
|
||||
if (parent instanceof PsiArrayInitializerExpression) return;
|
||||
|
||||
if (isTypeCastSemantic(typeCast)) return;
|
||||
|
||||
@@ -757,29 +747,8 @@ public class RedundantCastUtil {
|
||||
final PsiExpression operand = deparenthesizeExpression(typeCast.getOperand());
|
||||
if (operand == null) return;
|
||||
|
||||
PsiType opType = operand.getType();
|
||||
final PsiType expectedTypeByParent = PsiTypesUtil.getExpectedTypeByParent(typeCast);
|
||||
|
||||
if (expectedTypeByParent != null) {
|
||||
try {
|
||||
final Project project = operand.getProject();
|
||||
final String uniqueVariableName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("l", parent, false);
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(
|
||||
expectedTypeByParent.getCanonicalText() + " " + uniqueVariableName + " = " + operand.getText() + ";", parent);
|
||||
final PsiExpression initializer = ((PsiLocalVariable)declarationStatement.getDeclaredElements()[0]).getInitializer();
|
||||
LOG.assertTrue(initializer != null, operand.getText());
|
||||
opType = initializer.getType();
|
||||
|
||||
if (initializer instanceof PsiMethodCallExpression) {
|
||||
JavaResolveResult newResult = ((PsiMethodCallExpression)initializer).resolveMethodGenerics();
|
||||
if (newResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)newResult).getInferenceErrorMessage() != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException ignore) {}
|
||||
}
|
||||
PsiType opType = getOpTypeWithExpected(operand, expectedTypeByParent);
|
||||
|
||||
if (opType == null) return;
|
||||
if (operand instanceof PsiConditionalExpression) {
|
||||
@@ -839,6 +808,32 @@ public class RedundantCastUtil {
|
||||
addIfNarrowing(typeCast, opType, expectedTypeByParent);
|
||||
}
|
||||
|
||||
private static PsiType getOpTypeWithExpected(PsiExpression operand, PsiType expectedTypeByParent) {
|
||||
PsiType opType = operand.getType();
|
||||
|
||||
if (expectedTypeByParent != null) {
|
||||
try {
|
||||
final Project project = operand.getProject();
|
||||
final String uniqueVariableName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("l", operand, false);
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(
|
||||
expectedTypeByParent.getCanonicalText() + " " + uniqueVariableName + " = " + operand.getText() + ";", operand);
|
||||
final PsiExpression initializer = ((PsiLocalVariable)declarationStatement.getDeclaredElements()[0]).getInitializer();
|
||||
LOG.assertTrue(initializer != null, operand.getText());
|
||||
opType = initializer.getType();
|
||||
|
||||
if (initializer instanceof PsiMethodCallExpression) {
|
||||
JavaResolveResult newResult = ((PsiMethodCallExpression)initializer).resolveMethodGenerics();
|
||||
if (newResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)newResult).getInferenceErrorMessage() != null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException ignore) {}
|
||||
}
|
||||
return opType;
|
||||
}
|
||||
|
||||
private static boolean isApplicableForConditionalBranch(PsiType opType, PsiExpression thenExpression) {
|
||||
if (thenExpression != null) {
|
||||
final PsiType thenType = thenExpression.getType();
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ import java.io.*;
|
||||
interface Predicate<T> {
|
||||
boolean test(String s);
|
||||
}
|
||||
interface I {}
|
||||
class Test {
|
||||
private static boolean test(String s) {
|
||||
return false;
|
||||
@@ -9,6 +10,6 @@ class Test {
|
||||
|
||||
{
|
||||
Predicate<String> mh1 = (Predicate<String> & Serializable)Test::test;
|
||||
Predicate<String> mh0 = (<warning descr="Casting 'Test::test' to 'Predicate<String> & Predicate<String>' is redundant">Predicate<String> & <error descr="Repeated interface">Predicate<String></error></warning>)Test::test;
|
||||
Predicate<String> mh0 = (I & Predicate<String>) (<warning descr="Casting 'Test::test' to 'Predicate<String>' is redundant">Predicate<String></warning>)Test::test;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user