From 53094fd2d209a031929764d1c3e1e06ccae34c23 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Sun, 22 Apr 2018 17:03:29 +0700 Subject: [PATCH] IDEA-190727 Replace instanceof with null-check could automatically eliminate double negation --- .../dataFlow/fix/RedundantInstanceofFix.java | 28 +++++++++++++------ .../afterInstanceOfNegated.java | 10 +++++++ .../beforeInstanceOfNegated.java | 10 +++++++ 3 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/afterInstanceOfNegated.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/beforeInstanceOfNegated.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/fix/RedundantInstanceofFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/fix/RedundantInstanceofFix.java index 96ac2bf01763..71d4456f5262 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/fix/RedundantInstanceofFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/fix/RedundantInstanceofFix.java @@ -21,7 +21,9 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; +import com.siyeh.ig.psiutils.BoolUtils; import com.siyeh.ig.psiutils.CommentTracker; import org.jetbrains.annotations.NotNull; @@ -37,22 +39,30 @@ public class RedundantInstanceofFix implements LocalQuickFix { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - final PsiElement psiElement = descriptor.getPsiElement(); - String replacement; + PsiElement psiElement = descriptor.getPsiElement(); CommentTracker ct = new CommentTracker(); + if (psiElement instanceof PsiMethodReferenceExpression) { + String replacement = CommonClassNames.JAVA_UTIL_OBJECTS + "::nonNull"; + JavaCodeStyleManager.getInstance(project).shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement)); + return; + } + String nonNullExpression = null; if (psiElement instanceof PsiInstanceOfExpression) { - replacement = ct.text(((PsiInstanceOfExpression)psiElement).getOperand()) + " != null"; + nonNullExpression = ct.text(((PsiInstanceOfExpression)psiElement).getOperand()); } else if (psiElement instanceof PsiMethodCallExpression) { PsiExpression arg = ArrayUtil.getFirstElement(((PsiMethodCallExpression)psiElement).getArgumentList().getExpressions()); if (arg == null) return; - replacement = ct.text(arg) + " != null"; + nonNullExpression = ct.text(arg); } - else if (psiElement instanceof PsiMethodReferenceExpression) { - replacement = CommonClassNames.JAVA_UTIL_OBJECTS + "::nonNull"; - } - else { - return; + if (nonNullExpression == null) return; + PsiElement parent = PsiUtil.skipParenthesizedExprUp(psiElement.getParent()); + String replacement; + if (parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent)) { + replacement = nonNullExpression + "==null"; + psiElement = parent; + } else { + replacement = nonNullExpression + "!=null"; } JavaCodeStyleManager.getInstance(project).shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement)); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/afterInstanceOfNegated.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/afterInstanceOfNegated.java new file mode 100644 index 000000000000..730c643f07f9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/afterInstanceOfNegated.java @@ -0,0 +1,10 @@ +// "Replace with a null check" "true" +class Test { + void test(String s) { + Object obj = s; + if (obj == null) { + return; + } + System.out.println("always"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/beforeInstanceOfNegated.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/beforeInstanceOfNegated.java new file mode 100644 index 000000000000..420f4f087bc0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantInstanceOf/beforeInstanceOfNegated.java @@ -0,0 +1,10 @@ +// "Replace with a null check" "true" +class Test { + void test(String s) { + Object obj = s; + if (!(obj instanceof String)) { + return; + } + System.out.println("always"); + } +} \ No newline at end of file