[code-inspections] SetInspectionOptionFix: support numerical value; used in ExtractMethodRecommenderInspection

GitOrigin-RevId: d4f587f5f1e280eca12f5b0e0ab48e232ba187f3
This commit is contained in:
Tagir Valeev
2023-02-23 13:14:33 +00:00
committed by intellij-monorepo-bot
parent a3ca6017bb
commit 5612d67279
4 changed files with 76 additions and 22 deletions
@@ -634,5 +634,7 @@ inspection.extract.method.inspection.name=Method can be extracted
inspection.extract.method.nothing=nothing
inspection.extract.method.preview.html=Extract {0} statements to a method, which accepts {1} and returns <b>{2}</b>
inspection.extract.method.message=Extract method returning ''{0}''
inspection.extract.method.option.min.length=Minimal length of code to extract:|characters
inspection.extract.method.option.max.parameters=Maximal number of parameters:
inspection.extract.method.option.min.length=Minimal length of code to extract:|symbols
inspection.extract.method.option.max.parameters=Maximal number of parameters:
inspection.extract.method.dont.suggest.parameters=Don''t suggest to extract method accepting {0}+ parameters
inspection.extract.method.dont.suggest.length=Don't suggest to extract such a short methods
@@ -104,10 +104,22 @@ public class ExtractMethodRecommenderInspection extends AbstractBaseJavaLocalIns
textRange = textRange.union(ret.getTextRangeInParent());
}
}
List<LocalQuickFix> fixes = new ArrayList<>();
fixes.add(new ExtractMethodFix(from, count, output, inputVariables));
if (inputVariables.size() > 1) {
fixes.add(new SetInspectionOptionFix(ExtractMethodRecommenderInspection.this, "maxParameters",
JavaAnalysisBundle.message("inspection.extract.method.dont.suggest.parameters", inputVariables.size()),
inputVariables.size() - 1));
}
if (textRange.getLength() < 10_000) {
fixes.add(new SetInspectionOptionFix(ExtractMethodRecommenderInspection.this, "minLength",
JavaAnalysisBundle.message("inspection.extract.method.dont.suggest.length"),
textRange.getLength() + 1));
}
holder.registerProblem(block, JavaAnalysisBundle.message("inspection.extract.method.message", output.getName()),
ProblemHighlightType.WEAK_WARNING,
textRange,
new ExtractMethodFix(from, count, output, inputVariables));
fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
return;
}
catch (PrepareFailedException | ControlFlowWrapper.ExitStatementsNotSameException | ExtractException ignored) {
@@ -226,5 +226,6 @@ html.preview.navigate.line=, line #
set.inspection.option.fix=Set inspection option
set.inspection.option.description.uncheck=Uncheck inspection option:
set.inspection.option.description.check=Check inspection option:
set.inspection.option.description.input=Update numerical inspection option:
progress.title.submit.request=Submit
progress.title.refresh=Refresh
@@ -6,7 +6,9 @@ import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInspection.ex.InspectionProfileModifiableModelKt;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.options.LocMessage;
import com.intellij.codeInspection.options.OptCheckbox;
import com.intellij.codeInspection.options.OptNumber;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.icons.AllIcons;
@@ -29,18 +31,24 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.function.Function;
import static com.intellij.openapi.util.text.HtmlChunk.*;
public class SetInspectionOptionFix extends IntentionAndQuickFixAction implements LowPriorityAction, Iconable {
private final String myShortName;
private final String myProperty;
private final @IntentionName String myMessage;
private final boolean myValue;
private final Object myValue;
private final @Nullable Function<? super InspectionProfileEntry, ? extends InspectionProfileEntry> myExtractor;
public SetInspectionOptionFix(LocalInspectionTool inspection, @NonNls String property, @IntentionName String message, boolean value) {
this(inspection.getShortName(), property, message, value, null);
}
private SetInspectionOptionFix(@NotNull String shortName, @NonNls String property, @IntentionName String message, boolean value,
public SetInspectionOptionFix(LocalInspectionTool inspection, @NonNls String property, @IntentionName String message, int value) {
this(inspection.getShortName(), property, message, value, null);
}
private SetInspectionOptionFix(@NotNull String shortName, @NonNls String property, @IntentionName String message, Object value,
@Nullable Function<? super InspectionProfileEntry, ? extends InspectionProfileEntry> extractor) {
myShortName = shortName;
myProperty = property;
@@ -83,11 +91,12 @@ public class SetInspectionOptionFix extends IntentionAndQuickFixAction implement
@Override
public void applyFix(@NotNull Project project, PsiFile file, @Nullable Editor editor) {
VirtualFile vFile = file.getVirtualFile();
Object oldValue = getOption(project, vFile);
setOption(project, vFile, myValue);
UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction(vFile) {
@Override
public void undo() {
setOption(project, vFile, !myValue);
setOption(project, vFile, oldValue);
}
@Override
@@ -109,25 +118,55 @@ public class SetInspectionOptionFix extends IntentionAndQuickFixAction implement
if (tool == null) return IntentionPreviewInfo.EMPTY;
InspectionProfileEntry inspection = myExtractor == null ? tool.getTool() : myExtractor.apply(tool.getTool());
OptPane pane = inspection.getOptionsPane();
OptCheckbox control = ObjectUtils.tryCast(pane.findControl(myProperty), OptCheckbox.class);
if (control == null) return IntentionPreviewInfo.EMPTY;
HtmlChunk label = HtmlChunk.text(control.label().label());
HtmlChunk.Element checkbox = HtmlChunk.tag("input").attr("type", "checkbox").attr("readonly", "true");
if (myValue) {
checkbox = checkbox.attr("checked", "true");
}
HtmlChunk info = HtmlChunk.tag("table")
.child(HtmlChunk.tag("tr").children(
HtmlChunk.tag("td").child(checkbox),
HtmlChunk.tag("td").child(label)
if (myValue instanceof Boolean value) {
OptCheckbox control = ObjectUtils.tryCast(pane.findControl(myProperty), OptCheckbox.class);
if (control == null) return IntentionPreviewInfo.EMPTY;
HtmlChunk label = text(control.label().label());
Element checkbox = tag("input").attr("type", "checkbox").attr("readonly", "true");
if (value) {
checkbox = checkbox.attr("checked", "true");
}
HtmlChunk info = tag("table")
.child(tag("tr").children(
tag("td").child(checkbox),
tag("td").child(label)
));
return new IntentionPreviewInfo.Html(
new HtmlBuilder().append(value ? AnalysisBundle.message("set.inspection.option.description.check")
: AnalysisBundle.message("set.inspection.option.description.uncheck"))
.br().br().append(info).toFragment());
} else if (myValue instanceof Integer value) {
OptNumber control = ObjectUtils.tryCast(pane.findControl(myProperty), OptNumber.class);
if (control == null) return IntentionPreviewInfo.EMPTY;
LocMessage.PrefixSuffix prefixSuffix = control.splitLabel().splitLabel();
Element input = tag("input").attr("type", "text").attr("value", value)
.attr("size", value.toString().length() + 1).attr("readonly", "true");
HtmlChunk info = tag("table").child(tag("tr").children(
tag("td").child(text(prefixSuffix.prefix())),
tag("td").child(input),
tag("td").child(text(prefixSuffix.suffix()))
));
return new IntentionPreviewInfo.Html(
new HtmlBuilder().append(myValue ? AnalysisBundle.message("set.inspection.option.description.check")
: AnalysisBundle.message("set.inspection.option.description.uncheck"))
.br().br().append(info).toFragment());
return new IntentionPreviewInfo.Html(
new HtmlBuilder().append(AnalysisBundle.message("set.inspection.option.description.input"))
.br().br().append(info).br().toFragment());
} else {
throw new IllegalStateException("Value of type " + myValue.getClass() + " is not supported");
}
}
private Object getOption(@NotNull Project project, @NotNull VirtualFile vFile) {
PsiFile file = PsiManager.getInstance(project).findFile(vFile);
if (file == null) return null;
InspectionToolWrapper<?, ?> tool = InspectionProfileManager.getInstance(project).getCurrentProfile().getInspectionTool(myShortName, file);
if (tool == null) return null;
InspectionProfileEntry inspection = tool.getTool();
if (myExtractor != null) {
inspection = myExtractor.apply(inspection);
}
return inspection.getOptionController().getOption(myProperty);
}
private void setOption(@NotNull Project project, @NotNull VirtualFile vFile, boolean value) {
private void setOption(@NotNull Project project, @NotNull VirtualFile vFile, Object value) {
PsiFile file = PsiManager.getInstance(project).findFile(vFile);
if (file == null) return;
InspectionProfileModifiableModelKt.modifyAndCommitProjectProfile(project, model -> {