WEB-32826 fix bulk mode for quick fixes (+don't store extra psi element)

This commit is contained in:
Anton Lobov
2018-05-30 10:31:34 +02:00
parent dd07de149d
commit e36da4fb1a
5 changed files with 94 additions and 50 deletions
@@ -81,7 +81,7 @@ public class JsonSchemaComplianceChecker {
if (checkIfAlreadyProcessed(entry.getKey())) continue;
String value = entry.getValue().getMessage();
if (myMessagePrefix != null) value = myMessagePrefix + value;
LocalQuickFix fix = entry.getValue().createFix(entry.getKey());
LocalQuickFix fix = entry.getValue().createFix();
if (fix == null) {
myHolder.registerProblem(entry.getKey(), value);
}
@@ -2,7 +2,6 @@
package com.jetbrains.jsonSchema.impl;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.psi.PsiElement;
import com.jetbrains.jsonSchema.impl.fixes.AddMissingPropertyFix;
import com.jetbrains.jsonSchema.impl.fixes.RemoveProhibitedPropertyFix;
import com.jetbrains.jsonSchema.impl.fixes.SuggestEnumValuesFix;
@@ -76,14 +75,14 @@ public class JsonValidationError {
}
@Nullable
public LocalQuickFix createFix(PsiElement key) {
public LocalQuickFix createFix() {
switch (myFixableIssueKind) {
case MissingProperty:
return new AddMissingPropertyFix(key, (MissingPropertyIssueData)myIssueData);
return new AddMissingPropertyFix((MissingPropertyIssueData)myIssueData);
case ProhibitedProperty:
return new RemoveProhibitedPropertyFix(key, (ProhibitedPropertyIssueData)myIssueData);
return new RemoveProhibitedPropertyFix((ProhibitedPropertyIssueData)myIssueData);
case NonEnumValue:
return new SuggestEnumValuesFix(key);
return new SuggestEnumValuesFix();
default:
return null;
}
@@ -7,8 +7,7 @@ import com.intellij.codeInsight.template.TemplateManager;
import com.intellij.codeInsight.template.impl.ConstantNode;
import com.intellij.codeInsight.template.impl.MacroCallNode;
import com.intellij.codeInsight.template.macro.CompleteMacro;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.*;
import com.intellij.json.psi.JsonElementGenerator;
import com.intellij.json.psi.JsonObject;
import com.intellij.json.psi.JsonProperty;
@@ -19,22 +18,24 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.DocumentUtil;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.jsonSchema.impl.JsonValidationError;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AddMissingPropertyFix implements LocalQuickFix {
private final SmartPsiElementPointer<PsiElement> myPointer;
import java.util.List;
public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix<CommonProblemDescriptor> {
private final JsonValidationError.MissingPropertyIssueData myData;
public AddMissingPropertyFix(PsiElement node, JsonValidationError.MissingPropertyIssueData data) {
myPointer = SmartPointerManager.createPointer(node);
public AddMissingPropertyFix(JsonValidationError.MissingPropertyIssueData data) {
myData = data;
}
@@ -54,29 +55,10 @@ public class AddMissingPropertyFix implements LocalQuickFix {
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = myPointer.getElement();
if (!(element instanceof JsonObject)) return;
JsonElementGenerator generator = new JsonElementGenerator(project);
Object defaultValueObject = myData.defaultValue;
String defaultValue = defaultValueObject instanceof String ? StringUtil.wrapWithDoubleQuote(defaultValueObject.toString()) : null;
Ref<PsiElement> newElementRef = Ref.create(null);
PsiElement element = descriptor.getPsiElement();
Ref<Boolean> hadComma = Ref.create(false);
WriteAction.run(() -> {
PsiElement newElement = element
.addBefore(
generator.createProperty(myData.propertyName, defaultValue == null ? myData.propertyType.getDefaultValue() : defaultValue),
element.getLastChild());
PsiElement backward = PsiTreeUtil.skipWhitespacesBackward(newElement);
if (backward instanceof JsonProperty) {
element.addAfter(generator.createComma(), backward);
hadComma.set(true);
}
newElementRef.set(newElement);
});
PsiElement newElement = newElementRef.get();
if (!(element instanceof JsonObject)) return;
PsiElement newElement = performFix(project, element, hadComma);
JsonValue value = ((JsonProperty)newElement).getValue();
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(element.getContainingFile().getVirtualFile());
EditorEx editor = EditorUtil.getEditorEx(fileEditor);
@@ -85,7 +67,6 @@ public class AddMissingPropertyFix implements LocalQuickFix {
WriteAction.run(() ->editor.getCaretModel().moveToOffset(newElement.getTextRange().getEndOffset()));
return;
}
TemplateManager templateManager = TemplateManager.getInstance(project);
TemplateBuilderImpl builder = new TemplateBuilderImpl(newElement);
builder.replaceElement(value, myData.hasEnumItems
@@ -101,8 +82,59 @@ public class AddMissingPropertyFix implements LocalQuickFix {
templateManager.startTemplate(editor, template);
}
private PsiElement performFix(@NotNull Project project, PsiElement element, Ref<Boolean> hadComma) {
JsonElementGenerator generator = new JsonElementGenerator(project);
Object defaultValueObject = myData.defaultValue;
String defaultValue = defaultValueObject instanceof String ? StringUtil.wrapWithDoubleQuote(defaultValueObject.toString()) : null;
Ref<PsiElement> newElementRef = Ref.create(null);
WriteAction.run(() -> {
PsiElement newElement = element
.addBefore(
generator.createProperty(myData.propertyName, defaultValue == null ? myData.propertyType.getDefaultValue() : defaultValue),
element.getLastChild());
PsiElement backward = PsiTreeUtil.skipWhitespacesBackward(newElement);
if (backward instanceof JsonProperty) {
element.addAfter(generator.createComma(), backward);
hadComma.set(true);
}
newElementRef.set(newElement);
});
return newElementRef.get();
}
@Override
public boolean startInWriteAction() {
return false;
}
@Override
public void applyFix(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors,
@NotNull List<PsiElement> psiElementsToIgnore,
@Nullable Runnable refreshViews) {
List<Pair<AddMissingPropertyFix, PsiElement>> propFixes = ContainerUtil.newArrayList();
for (CommonProblemDescriptor descriptor: descriptors) {
if (!(descriptor instanceof ProblemDescriptor)) continue;
QuickFix[] fixes = descriptor.getFixes();
if (fixes == null) continue;
AddMissingPropertyFix fix = getWorkingQuickFix(fixes);
if (fix == null) continue;
propFixes.add(Pair.create(fix, ((ProblemDescriptor)descriptor).getPsiElement()));
}
DocumentUtil.writeInRunUndoTransparentAction(() -> propFixes.forEach(fix ->
fix.first.performFix(project, fix.second, Ref.create(false))));
}
@Nullable
private static AddMissingPropertyFix getWorkingQuickFix(@NotNull QuickFix[] fixes) {
for (QuickFix fix : fixes) {
if (fix instanceof AddMissingPropertyFix) {
return (AddMissingPropertyFix)fix;
}
}
return null;
}
}
@@ -7,8 +7,6 @@ import com.intellij.json.JsonElementTypes;
import com.intellij.json.psi.JsonProperty;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.jsonSchema.impl.JsonValidationError;
@@ -16,11 +14,9 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
public class RemoveProhibitedPropertyFix implements LocalQuickFix {
private final SmartPsiElementPointer<PsiElement> myPointer;
private final JsonValidationError.ProhibitedPropertyIssueData myData;
public RemoveProhibitedPropertyFix(PsiElement node, JsonValidationError.ProhibitedPropertyIssueData data) {
myPointer = SmartPointerManager.createPointer(node);
public RemoveProhibitedPropertyFix(JsonValidationError.ProhibitedPropertyIssueData data) {
myData = data;
}
@@ -40,7 +36,7 @@ public class RemoveProhibitedPropertyFix implements LocalQuickFix {
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = myPointer.getElement();
PsiElement element = descriptor.getPsiElement();
if (!(element instanceof JsonProperty)) return;
assert myData.propertyName.equals(((JsonProperty)element).getName());
PsiElement forward = PsiTreeUtil.skipWhitespacesForward(element);
@@ -3,27 +3,30 @@ package com.jetbrains.jsonSchema.impl.fixes;
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInspection.BatchQuickFix;
import com.intellij.codeInspection.CommonProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.json.psi.JsonValue;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SuggestEnumValuesFix implements LocalQuickFix {
private final SmartPsiElementPointer<PsiElement> myPointer;
import java.util.List;
public SuggestEnumValuesFix(PsiElement node) {
myPointer = SmartPointerManager.createPointer(node);
public class SuggestEnumValuesFix implements LocalQuickFix, BatchQuickFix<CommonProblemDescriptor> {
public SuggestEnumValuesFix() {
}
@Nls(capitalization = Nls.Capitalization.Sentence)
@@ -42,7 +45,7 @@ public class SuggestEnumValuesFix implements LocalQuickFix {
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = myPointer.getElement();
PsiElement element = descriptor.getPsiElement();
if (!(element instanceof JsonValue)) return;
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(element.getContainingFile().getVirtualFile());
boolean whitespaceBefore = false;
@@ -66,4 +69,18 @@ public class SuggestEnumValuesFix implements LocalQuickFix {
public boolean startInWriteAction() {
return false;
}
@Override
public void applyFix(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors,
@NotNull List<PsiElement> psiElementsToIgnore,
@Nullable Runnable refreshViews) {
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
if (editor != null) {
HintManager.getInstance().showErrorHint(editor, "Sorry, this fix is not available in batch mode");
}
else {
Messages.showErrorDialog(project, "Sorry, this fix is not available in batch mode", "Not Applicable in Batch Mode");
}
}
}