From a292a323efd407aaf277494e3bd67904a8b9e048 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 11 Jul 2013 15:23:09 +0200 Subject: [PATCH] get rid of QuickFixProvider usages in relax-ng --- .../intellij/lang/annotation/Annotation.java | 3 +- .../relaxNG/compact/ReferenceAnnotator.java | 25 ++--- .../compact/psi/impl/PatternReference.java | 49 ++++---- .../relaxNG/compact/psi/impl/RncNameImpl.java | 105 +++++++++--------- .../references/PrefixReferenceProvider.java | 28 ++--- .../xml/dom/impl/DefinitionReference.java | 15 +-- .../plugins/relaxNG/HighlightingTestBase.java | 32 +++--- 7 files changed, 118 insertions(+), 139 deletions(-) diff --git a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java index 9d4ac365d945..bd203783f62f 100644 --- a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java +++ b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java @@ -122,7 +122,8 @@ public final class Annotation implements Segment { registerFix(fix,range, null); } - public void registerFix(@NotNull LocalQuickFix fix, TextRange range, HighlightDisplayKey key, @NotNull ProblemDescriptor problemDescriptor) { + public void registerFix(@NotNull LocalQuickFix fix, @Nullable TextRange range, @Nullable HighlightDisplayKey key, + @NotNull ProblemDescriptor problemDescriptor) { if (range == null) { range = new TextRange(myStartOffset, myEndOffset); } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/ReferenceAnnotator.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/ReferenceAnnotator.java index d4f236fb878b..9b2ef11a395f 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/ReferenceAnnotator.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/ReferenceAnnotator.java @@ -17,14 +17,10 @@ package org.intellij.plugins.relaxNG.compact; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; -import com.intellij.codeInsight.daemon.QuickFixProvider; -import com.intellij.codeInsight.daemon.impl.HighlightInfo; -import com.intellij.codeInsight.daemon.impl.HighlightInfoType; -import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.*; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; @@ -33,7 +29,6 @@ import org.intellij.plugins.relaxNG.compact.psi.*; import org.jetbrains.annotations.NotNull; import java.text.MessageFormat; -import java.util.List; /** * Created by IntelliJ IDEA. @@ -110,16 +105,14 @@ public class ReferenceAnnotator extends RncElementVisitor implements Annotator { } annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); - if (reference instanceof QuickFixProvider) { - HighlightInfo info = - HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(annotation.getStartOffset(), annotation.getEndOffset()).create(); - - ((QuickFixProvider)reference).registerQuickfix(info, reference); - - List> ranges = info.quickFixActionRanges; - if (ranges != null) { - for (Pair pair : ranges) { - annotation.registerFix(pair.first.getAction(), pair.second); + if (reference instanceof LocalQuickFixProvider) { + LocalQuickFix[] fixes = ((LocalQuickFixProvider)reference).getQuickFixes(); + if (fixes != null) { + InspectionManager inspectionManager = InspectionManager.getInstance(reference.getElement().getProject()); + for (LocalQuickFix fix : fixes) { + ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(reference.getElement(), annotation.getMessage(), fix, + ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, true); + annotation.registerFix(fix, null, null, descriptor); } } } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java index 8aeab6059c17..b32f7a7ae37c 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java @@ -17,15 +17,15 @@ package org.intellij.plugins.relaxNG.compact.psi.impl; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; -import com.intellij.codeInsight.daemon.QuickFixProvider; -import com.intellij.codeInsight.daemon.impl.HighlightInfo; -import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; -import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.LocalQuickFixProvider; +import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.lang.ASTNode; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; @@ -52,7 +52,7 @@ import java.util.Set; * Date: 13.08.2007 */ class PatternReference extends PsiReferenceBase.Poly implements Function, - QuickFixProvider, EmptyResolveMessageProvider { + LocalQuickFixProvider, EmptyResolveMessageProvider { public PatternReference(RncRef ref) { super(ref); @@ -152,14 +152,16 @@ class PatternReference extends PsiReferenceBase.Poly implements Function return "Unresolved pattern reference ''{0}''"; } - public void registerQuickfix(HighlightInfo info, final PatternReference reference) { - if (reference.getScope() == null) { - return; + @Nullable + @Override + public LocalQuickFix[] getQuickFixes() { + if (getScope() != null) { + return new LocalQuickFix[] { new CreatePatternFix(this) }; } - QuickFixAction.registerQuickFixAction(info, new CreatePatternFix(reference)); + return LocalQuickFix.EMPTY_ARRAY; } - static class CreatePatternFix implements IntentionAction { + static class CreatePatternFix implements LocalQuickFix { private final PatternReference myReference; public CreatePatternFix(PatternReference reference) { @@ -167,7 +169,8 @@ class PatternReference extends PsiReferenceBase.Poly implements Function } @NotNull - public String getText() { + @Override + public String getName() { return "Create Pattern '" + myReference.getCanonicalText() + "'"; } @@ -176,11 +179,8 @@ class PatternReference extends PsiReferenceBase.Poly implements Function return "Create Pattern"; } - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return myReference.getElement().isValid() && myReference.getScope() != null; - } - - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final RncFile rncfile = (RncFile)PsiFileFactory.getInstance(myReference.getElement().getProject()).createFileFromText("dummy.rnc", RncFileType.getInstance(), "dummy = xxx"); final RncGrammar grammar = rncfile.getGrammar(); @@ -207,8 +207,6 @@ class PatternReference extends PsiReferenceBase.Poly implements Function CodeStyleManager.getInstance(e.getManager().getProject()).reformatNewlyAddedElement(blockNode, newNode); - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); - final RncDefine d = p.getElement(); assert d != null; @@ -217,13 +215,12 @@ class PatternReference extends PsiReferenceBase.Poly implements Function final int offset = definition.getTextRange().getStartOffset(); - editor.getCaretModel().moveToOffset(offset); - editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - editor.getDocument().deleteString(offset, definition.getTextRange().getEndOffset()); - } + definition.delete(); - public boolean startInWriteAction() { - return true; + VirtualFile virtualFile = myReference.getElement().getContainingFile().getVirtualFile(); + if (virtualFile != null) { + FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile, offset), true); + } } } } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java index 6dc7ad54df8e..b1cf38bd2a0f 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java @@ -16,19 +16,25 @@ package org.intellij.plugins.relaxNG.compact.psi.impl; +import com.intellij.codeInsight.CodeInsightUtilCore; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; -import com.intellij.codeInsight.daemon.QuickFixProvider; -import com.intellij.codeInsight.daemon.impl.HighlightInfo; -import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; -import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.template.*; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.LocalQuickFixProvider; +import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.PsiReference; +import com.intellij.psi.ResolveState; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.tree.IElementType; @@ -49,7 +55,7 @@ import org.jetbrains.annotations.Nullable; * Date: 14.08.2007 */ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference, - EmptyResolveMessageProvider, QuickFixProvider { + EmptyResolveMessageProvider, LocalQuickFixProvider { private enum Kind { NAMESPACE, DATATYPES @@ -140,10 +146,13 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference return "Unresolved namespace prefix ''{0}''"; } - public void registerQuickfix(HighlightInfo info, final RncNameImpl reference) { - if (reference.getPrefix() == null) return; // huh? - - QuickFixAction.registerQuickFixAction(info, new CreateDeclFix(reference)); + @Nullable + @Override + public LocalQuickFix[] getQuickFixes() { + if (getPrefix() != null) { + return new LocalQuickFix[] { new CreateDeclFix(this) }; + } + return LocalQuickFix.EMPTY_ARRAY; } private static class MyResolver extends BaseScopeProcessor { @@ -187,7 +196,7 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference } } - public static class CreateDeclFix implements IntentionAction { + public static class CreateDeclFix implements LocalQuickFix { private final RncNameImpl myReference; public CreateDeclFix(RncNameImpl reference) { @@ -195,7 +204,7 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference } @NotNull - public String getText() { + public String getName() { return getFamilyName() + " '" + myReference.getPrefix() + "'"; } @@ -204,11 +213,8 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference return "Create " + myReference.getKind().name().toLowerCase() + " declaration"; } - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return myReference.isValid(); - } - - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final String prefix = myReference.getPrefix(); final PsiFileFactory factory = PsiFileFactory.getInstance(myReference.getProject()); final RncFile psiFile = (RncFile)factory.createFileFromText("dummy.rnc", @@ -237,13 +243,7 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference CodeStyleManager.getInstance(e.getManager().getProject()).reformatNewlyAddedElement(blockNode, newNode); - final SmartPsiElementPointer p = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(e); - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); - - final RncDecl d = p.getElement(); - assert d != null; - - final PsiElement literal = d.getLastChild(); + final PsiElement literal = e.getLastChild(); assert literal != null; final ASTNode literalNode = literal.getNode(); @@ -252,34 +252,39 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference assert literalNode.getElementType() == RncTokenTypes.LITERAL; final int offset = literal.getTextRange().getStartOffset(); - editor.getDocument().deleteString(literal.getTextRange().getStartOffset(), literal.getTextRange().getEndOffset()); - final TemplateManager manager = TemplateManager.getInstance(project); - final Template t = manager.createTemplate("", ""); - t.addTextSegment("\""); - final Expression expression = new Expression() { - public Result calculateResult(ExpressionContext context) { - return new TextResult(""); + literal.delete(); + + VirtualFile virtualFile = myReference.getElement().getContainingFile().getVirtualFile(); + if (virtualFile != null) { + Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile, offset), true); + if (editor != null) { + RncDecl rncDecl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(e); + + final TemplateManager manager = TemplateManager.getInstance(project); + final Template t = manager.createTemplate("", ""); + t.addTextSegment(" \""); + final Expression expression = new Expression() { + public Result calculateResult(ExpressionContext context) { + return new TextResult(""); + } + + public Result calculateQuickResult(ExpressionContext context) { + return calculateResult(context); + } + + public LookupItem[] calculateLookupItems(ExpressionContext context) { + return LookupItem.EMPTY_ARRAY; + } + }; + t.addVariable("uri", expression, expression, true); + t.addTextSegment("\""); + t.addEndVariable(); + + editor.getCaretModel().moveToOffset(rncDecl.getTextRange().getEndOffset()); + manager.startTemplate(editor, t); } - - public Result calculateQuickResult(ExpressionContext context) { - return calculateResult(context); - } - - public LookupItem[] calculateLookupItems(ExpressionContext context) { - return LookupItem.EMPTY_ARRAY; - } - }; - t.addVariable("uri", expression, expression, true); - t.addTextSegment("\""); - t.addEndVariable(); - - editor.getCaretModel().moveToOffset(offset); - manager.startTemplate(editor, t); - } - - public boolean startInWriteAction() { - return true; + } } } } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java index df9bcc8d5cf2..a1a42ac4b64e 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java @@ -17,10 +17,9 @@ package org.intellij.plugins.relaxNG.references; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; -import com.intellij.codeInsight.daemon.QuickFixProvider; -import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.analysis.CreateNSDeclarationIntentionFix; -import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.LocalQuickFixProvider; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; @@ -62,7 +61,7 @@ public class PrefixReferenceProvider extends PsiReferenceProvider { }; } - private static class PrefixReference extends BasicAttributeValueReference implements EmptyResolveMessageProvider, QuickFixProvider { + private static class PrefixReference extends BasicAttributeValueReference implements EmptyResolveMessageProvider, LocalQuickFixProvider { public PrefixReference(XmlAttributeValue value, int length) { super(value, TextRange.from(1, length)); } @@ -94,19 +93,16 @@ public class PrefixReferenceProvider extends PsiReferenceProvider { return super.isReferenceTo(element); } - public void registerQuickfix(HighlightInfo info, PrefixReference reference) { - try { - final PsiElement element = reference.getElement(); - final XmlElementFactory factory = XmlElementFactory.getInstance(element.getProject()); - final String value = ((XmlAttributeValue)element).getValue(); - final String[] name = value.split(":"); - final XmlTag tag = factory.createTagFromText("<" + (name.length > 1 ? name[1] : value) + " />", XMLLanguage.INSTANCE); + @Nullable + @Override + public LocalQuickFix[] getQuickFixes() { + final PsiElement element = getElement(); + final XmlElementFactory factory = XmlElementFactory.getInstance(element.getProject()); + final String value = ((XmlAttributeValue)element).getValue(); + final String[] name = value.split(":"); + final XmlTag tag = factory.createTagFromText("<" + (name.length > 1 ? name[1] : value) + " />", XMLLanguage.INSTANCE); - CreateNSDeclarationIntentionFix fix = CreateNSDeclarationIntentionFix.createFix(tag, reference.getCanonicalText()); - QuickFixAction.registerQuickFixAction(info, fix); - } catch (Throwable e) { - LOG.error(e); - } + return new LocalQuickFix[] { CreateNSDeclarationIntentionFix.createFix(tag, getCanonicalText()) }; } @NotNull diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java index 31b1950c9a8f..9ac61ebb9a20 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java @@ -17,9 +17,6 @@ package org.intellij.plugins.relaxNG.xml.dom.impl; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; -import com.intellij.codeInsight.daemon.QuickFixProvider; -import com.intellij.codeInsight.daemon.impl.HighlightInfo; -import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.lookup.LookupValueFactory; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; @@ -53,7 +50,7 @@ import java.util.Set; * Date: 18.08.2007 */ public class DefinitionReference extends PsiReferenceBase.Poly - implements QuickFixProvider, LocalQuickFixProvider, + implements LocalQuickFixProvider, EmptyResolveMessageProvider, Function { private final boolean myIsParentRef; @@ -143,16 +140,6 @@ public class DefinitionReference extends PsiReferenceBase.Poly rangePair = info.quickFixActionRanges.get(0); - final IntentionAction action = rangePair.first.getAction(); - - assertTrue("action is enabled", action.isAvailable(myTestFixture.getProject(), myTestFixture.getEditor(), myTestFixture.getFile())); - myTestFixture.launchAction(action); + assertTrue("One action expected", fixes != null && fixes.length == 1); + final Project project = myTestFixture.getProject(); + new WriteCommandAction.Simple(project, myTestFixture.getFile()) { + @Override + protected void run() throws Throwable { + ProblemDescriptor problemDescriptor = InspectionManager.getInstance(project).createProblemDescriptor(psiReference.getElement(), "foo", + fixes, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + true); + fixes[0].applyFix(project, problemDescriptor); + } + }.execute(); myTestFixture.checkResultByFile(file + "_after." + ext); }