From a35e4128e646e49d177d59b4075d2e0297113a7f Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 17 Aug 2018 13:12:11 +0700 Subject: [PATCH] IDEA-197026 "Redundant null-check" inspection: make a quick-fix to replace "foo != null" with "foo" Primitive type name is added to the message --- .../ObviousNullCheckInspection.java | 28 ++++++++++++++++--- .../obviousNotNull/ObviousNullCheck.java | 4 +-- .../obviousNotNull/afterNotNull.java | 11 ++++++++ .../obviousNotNull/beforeNotNull.java | 11 ++++++++ .../src/messages/InspectionsBundle.properties | 1 + 5 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/inspection/obviousNotNull/afterNotNull.java create mode 100644 java/java-tests/testData/inspection/obviousNotNull/beforeNotNull.java diff --git a/java/java-impl/src/com/intellij/codeInspection/ObviousNullCheckInspection.java b/java/java-impl/src/com/intellij/codeInspection/ObviousNullCheckInspection.java index c6fafeb05178..00a5be5c1d77 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ObviousNullCheckInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/ObviousNullCheckInspection.java @@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.psiutils.CommentTracker; import com.siyeh.ig.psiutils.ExpressionUtils; @@ -44,8 +45,9 @@ public class ObviousNullCheckInspection extends AbstractBaseJavaLocalInspectionT if(nullCheckParameter.myNull) { holder.registerProblem(nullArg, InspectionsBundle.message("inspection.redundant.null.check.always.fail.message", explanation)); } else { - holder.registerProblem(nullArg, InspectionsBundle.message("inspection.redundant.null.check.message", explanation), - new RemoveNullCheckFix()); + PsiReferenceExpression comparedToNull = ExpressionUtils.getReferenceExpressionFromNullComparison(nullArg, false); + LocalQuickFix fix = comparedToNull == null ? new RemoveNullCheckFix() : new RemoveExcessiveNullComparisonFix(); + holder.registerProblem(nullArg, InspectionsBundle.message("inspection.redundant.null.check.message", explanation), fix); } } }; @@ -56,11 +58,11 @@ public class ObviousNullCheckInspection extends AbstractBaseJavaLocalInspectionT if (arg == null || ExpressionUtils.isNullLiteral(arg)) return null; if (arg instanceof PsiNewExpression) return "newly created object"; if (arg instanceof PsiLiteralExpression) return "literal"; - if (arg.getType() instanceof PsiPrimitiveType) return "a value of primitive type"; + if (arg.getType() instanceof PsiPrimitiveType) return "a value of primitive type '" + arg.getType().getCanonicalText() + "'"; if (arg instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)arg).getOperationTokenType() == JavaTokenType.PLUS) { return "concatenation"; } - if (arg instanceof PsiThisExpression) return "this object"; + if (arg instanceof PsiThisExpression) return "'this' object"; return null; } @@ -108,6 +110,24 @@ public class ObviousNullCheckInspection extends AbstractBaseJavaLocalInspectionT } } + public static class RemoveExcessiveNullComparisonFix implements LocalQuickFix { + @Nls(capitalization = Nls.Capitalization.Sentence) + @NotNull + @Override + public String getFamilyName() { + return InspectionsBundle.message("inspection.redundant.null.check.fix.notnull.family.name"); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiExpression arg = ObjectUtils.tryCast(descriptor.getStartElement(), PsiExpression.class); + if (arg == null) return; + PsiReferenceExpression comparedToNull = ExpressionUtils.getReferenceExpressionFromNullComparison(arg, false); + if (comparedToNull == null) return; + new CommentTracker().replaceAndRestoreComments(arg, comparedToNull); + } + } + public static class RemoveNullCheckFix implements LocalQuickFix { @Nls @NotNull diff --git a/java/java-tests/testData/inspection/obviousNotNull/ObviousNullCheck.java b/java/java-tests/testData/inspection/obviousNotNull/ObviousNullCheck.java index 4ff7c77a815e..1f8ecde0544d 100644 --- a/java/java-tests/testData/inspection/obviousNotNull/ObviousNullCheck.java +++ b/java/java-tests/testData/inspection/obviousNotNull/ObviousNullCheck.java @@ -7,7 +7,7 @@ abstract class ObviousNullCheck { abstract String getBar(); void test(String param) { - assertNotNull(5 + 6); + assertNotNull(5 + 6); assertNull("Null!", param); assertNull(param, "Null!"); @@ -16,7 +16,7 @@ abstract class ObviousNullCheck { Objects.requireNonNull("xyz", "xyz"); Objects.requireNonNull((getFoo() + getBar())); Objects.requireNonNull(new ArrayList(), "new returned null"); - Objects.requireNonNull(this); + Objects.requireNonNull(this); String s = Objects.requireNonNull(" x "); String s1 = trim(" x "); diff --git a/java/java-tests/testData/inspection/obviousNotNull/afterNotNull.java b/java/java-tests/testData/inspection/obviousNotNull/afterNotNull.java new file mode 100644 index 000000000000..cb9a30808a12 --- /dev/null +++ b/java/java-tests/testData/inspection/obviousNotNull/afterNotNull.java @@ -0,0 +1,11 @@ +// "Remove erroneous '!= null'" "true" + +import java.util.Objects; + +public class Test { + void test(String foo) { + Objects.requireNonNull(foo); + } + + native int foo(); +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/obviousNotNull/beforeNotNull.java b/java/java-tests/testData/inspection/obviousNotNull/beforeNotNull.java new file mode 100644 index 000000000000..30559829d9c6 --- /dev/null +++ b/java/java-tests/testData/inspection/obviousNotNull/beforeNotNull.java @@ -0,0 +1,11 @@ +// "Remove erroneous '!= null'" "true" + +import java.util.Objects; + +public class Test { + void test(String foo) { + Objects.requireNonNull(foo != null); + } + + native int foo(); +} \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index 691a4ec27dcd..dbe0b714a5e4 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -926,6 +926,7 @@ inspection.replace.with.trivial.lambda.fix.name=Replace with lambda returning '' inspection.redundant.null.check.message=Redundant null-check: {0} is never null inspection.redundant.null.check.always.fail.message=Null-check will always fail: {0} is never null inspection.redundant.null.check.fix.family.name=Remove redundant null-check +inspection.redundant.null.check.fix.notnull.family.name=Remove erroneous '!= null' inspection.comparator.result.comparison.display.name=Suspicious usage of compare method inspection.comparator.result.comparison.problem.display.name=Comparison of compare method result with specific constant