ReplaceNullCheckInspection: checkbox, fix description: IDEA-182698

This commit is contained in:
Roman Ivanov
2017-12-04 11:36:17 +07:00
parent 20211e0084
commit 5698fed80a
3 changed files with 41 additions and 9 deletions
@@ -3,6 +3,7 @@ package com.intellij.codeInspection;
import com.intellij.codeInspection.dataFlow.Nullness;
import com.intellij.codeInspection.dataFlow.NullnessUtil;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.codeInspection.util.LambdaGenerationUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -12,11 +13,14 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.*;
import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import static com.intellij.util.ObjectUtils.tryCast;
public class ReplaceNullCheckInspection extends AbstractBaseJavaLocalInspectionTool {
@@ -30,11 +34,31 @@ public class ReplaceNullCheckInspection extends AbstractBaseJavaLocalInspectionT
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_STREAM_STREAM, "of").parameterTypes("T")
);
public boolean noWarningReplacementBigger = true;
@Nullable
@Override
public JComponent createOptionsPanel() {
MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
panel
.addCheckbox(InspectionsBundle.message("inspection.require.non.null.no.warning.replacement.bigger"), "noWarningReplacementBigger");
return panel;
}
@Override
public void writeSettings(@NotNull Element node) {
if (!noWarningReplacementBigger) {
node.addContent(new Element("option")
.setAttribute("name", "noWarningReplacementBigger")
.setAttribute("value", String.valueOf(noWarningReplacementBigger)));
}
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
PsiFile file = holder.getFile();
if(!PsiUtil.isLanguageLevel9OrHigher(file)) {
if (!PsiUtil.isLanguageLevel9OrHigher(file)) {
return PsiElementVisitor.EMPTY_VISITOR;
}
return new JavaElementVisitor() {
@@ -46,9 +70,9 @@ public class ReplaceNullCheckInspection extends AbstractBaseJavaLocalInspectionT
PsiStatement nextToDelete = context.getNextToDelete();
int maybeImplicitElseLength = nextToDelete != null ? nextToDelete.getTextLength() : 0;
boolean isInfoLevel = ifStatement.getTextLength() + maybeImplicitElseLength - context.getLenAfterReplace() < MINIMAL_WARN_DELTA_SIZE;
boolean isInfoLevel = noWarningReplacementBigger && ifStatement.getTextLength() + maybeImplicitElseLength - context.getLenAfterReplace() < MINIMAL_WARN_DELTA_SIZE;
ProblemHighlightType highlight = getHighlight(context, isInfoLevel);
holder.registerProblem(ifStatement.getChildren()[0], InspectionsBundle.message("inspection.require.non.null.message", method), highlight,
holder.registerProblem(ifStatement.getFirstChild(), InspectionsBundle.message("inspection.require.non.null.message", method), highlight,
new ReplaceWithRequireNonNullFix(method, false));
}
@@ -68,8 +92,14 @@ public class ReplaceNullCheckInspection extends AbstractBaseJavaLocalInspectionT
TernaryNotNullContext context = TernaryNotNullContext.from(ternary);
if(context == null) return;
String method = getMethodWithClass(context.getNonNullExpr(), false);
String name = context.getVariable().getName();
boolean replacementShorter =
name != null
&& context.getNonNullExpr().getTextLength() + method.length() + name.length() < context.getTernary().getTextLength() + MINIMAL_WARN_DELTA_SIZE;
boolean isInfoLevel = noWarningReplacementBigger && replacementShorter;
ProblemHighlightType highlightType = isInfoLevel ? ProblemHighlightType.INFORMATION : ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
holder.registerProblem(ternary, InspectionsBundle.message("inspection.require.non.null.message", method),
ProblemHighlightType.INFORMATION, new ReplaceWithRequireNonNullFix(method, true));
highlightType, new ReplaceWithRequireNonNullFix(method, true));
}
};
}
@@ -4,15 +4,16 @@ This inspection suggests to replace null check with Objects/Stream static method
<!-- tooltip end -->
Example:
<pre><code>
if (lBrace == null) {
SelectionManager.registerError(initializer, infos);
if (message == null) {
application.messageStorage().save(new EmptyMessage());
} else {
SelectionManager.registerError(lBrace, infos);
application.messageStorage().save(message);
}
</code></pre>
<p>can be replaced with</p>
<pre><code>
SelectionManager.registerError(Objects.requireNonNullElse(lbrace, initializer), infos);
application.messageStorage()
.save(Objects.requireNonNullElseGet(message, () -> new EmptyMessage()));
</code></pre>
<p><small>New in 2017.3</small></p>
</body>
@@ -804,7 +804,8 @@ inspection.simplify.collector.fix.name=Use ''Collectors.{0}'' collector
inspection.require.non.null=Replace null check with Objects/Stream static call
inspection.require.non.null.message=Replace condition with {0}
inspection.require.non.null.description=Null check can be replaced with method call
inspection.require.non.null.description=Null check can be replaced with method call
inspection.require.non.null.no.warning.replacement.bigger=Don't warn if length of replacement bigger than original
inspection.require.non.null.option.min.size=Minimal delta length when inspection will warn
inspection.redundant.stream.optional.call.message=Redundant ''{0}'' call