diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java index 3ba554c46100..1357ab5af407 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java @@ -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); } diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonValidationError.java b/json/src/com/jetbrains/jsonSchema/impl/JsonValidationError.java index 6a75e0d0ba69..d698787660de 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonValidationError.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonValidationError.java @@ -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; } diff --git a/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java b/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java index 78c283c541a4..53b460cd87c9 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java +++ b/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java @@ -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 myPointer; +import java.util.List; + +public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix { 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 newElementRef = Ref.create(null); + PsiElement element = descriptor.getPsiElement(); Ref 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 hadComma) { + JsonElementGenerator generator = new JsonElementGenerator(project); + Object defaultValueObject = myData.defaultValue; + String defaultValue = defaultValueObject instanceof String ? StringUtil.wrapWithDoubleQuote(defaultValueObject.toString()) : null; + Ref 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 psiElementsToIgnore, + @Nullable Runnable refreshViews) { + List> 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; + } } diff --git a/json/src/com/jetbrains/jsonSchema/impl/fixes/RemoveProhibitedPropertyFix.java b/json/src/com/jetbrains/jsonSchema/impl/fixes/RemoveProhibitedPropertyFix.java index e5203cf8cb08..21200c87d916 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/fixes/RemoveProhibitedPropertyFix.java +++ b/json/src/com/jetbrains/jsonSchema/impl/fixes/RemoveProhibitedPropertyFix.java @@ -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 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); diff --git a/json/src/com/jetbrains/jsonSchema/impl/fixes/SuggestEnumValuesFix.java b/json/src/com/jetbrains/jsonSchema/impl/fixes/SuggestEnumValuesFix.java index 2cd3e3ff89e1..ec87708f4c0d 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/fixes/SuggestEnumValuesFix.java +++ b/json/src/com/jetbrains/jsonSchema/impl/fixes/SuggestEnumValuesFix.java @@ -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 myPointer; +import java.util.List; - public SuggestEnumValuesFix(PsiElement node) { - myPointer = SmartPointerManager.createPointer(node); +public class SuggestEnumValuesFix implements LocalQuickFix, BatchQuickFix { + 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 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"); + } + } }