get rid of QuickFixProvider usages in relax-ng

This commit is contained in:
Dmitry Jemerov
2013-07-11 19:15:16 +02:00
parent d1e2ded1ba
commit a292a323ef
7 changed files with 118 additions and 139 deletions
@@ -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);
}
@@ -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<Pair<HighlightInfo.IntentionActionDescriptor,TextRange>> ranges = info.quickFixActionRanges;
if (ranges != null) {
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> 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);
}
}
}
@@ -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<RncRef> implements Function<Define, ResolveResult>,
QuickFixProvider<PatternReference>, EmptyResolveMessageProvider {
LocalQuickFixProvider, EmptyResolveMessageProvider {
public PatternReference(RncRef ref) {
super(ref);
@@ -152,14 +152,16 @@ class PatternReference extends PsiReferenceBase.Poly<RncRef> 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<RncRef> implements Function
}
@NotNull
public String getText() {
@Override
public String getName() {
return "Create Pattern '" + myReference.getCanonicalText() + "'";
}
@@ -176,11 +179,8 @@ class PatternReference extends PsiReferenceBase.Poly<RncRef> 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<RncRef> 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<RncRef> 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);
}
}
}
}
@@ -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<RncNameImpl> {
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<RncDecl> 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;
}
}
}
}
@@ -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<PrefixReference> {
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
@@ -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<XmlAttributeValue>
implements QuickFixProvider<DefinitionReference>, LocalQuickFixProvider,
implements LocalQuickFixProvider,
EmptyResolveMessageProvider, Function<Define, ResolveResult> {
private final boolean myIsParentRef;
@@ -143,16 +140,6 @@ public class DefinitionReference extends PsiReferenceBase.Poly<XmlAttributeValue
return LocalQuickFix.EMPTY_ARRAY;
}
public void registerQuickfix(HighlightInfo info, final DefinitionReference reference) {
assert reference == this;
final XmlTag tag = PsiTreeUtil.getParentOfType(getElement(), XmlTag.class);
assert tag != null;
final RngGrammar scope = myValue.getParentOfType(RngGrammar.class, true);
if (scope != null) {
QuickFixAction.registerQuickFixAction(info, new CreatePatternFix(this));
}
}
@NotNull
public String getUnresolvedMessagePattern() {
return "Unresolved pattern reference ''{0}''";
@@ -16,22 +16,17 @@
package org.intellij.plugins.relaxNG;
import com.intellij.codeInsight.daemon.QuickFixProvider;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.InspectionToolProvider;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspection;
import com.intellij.javaee.ExternalResourceManagerEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -210,18 +205,23 @@ public abstract class HighlightingTestBase extends UsefulTestCase implements Ide
protected void doTestQuickFix(String file, String ext) throws Throwable {
final PsiReference psiReference = myTestFixture.getReferenceAtCaretPositionWithAssertion(file + "." + ext);
assertNull("Reference", psiReference.resolve());
assertTrue("QuickFixProvider", psiReference instanceof QuickFixProvider);
assertTrue(psiReference.getClass().getName() + " is not a QuickFixProvider", psiReference instanceof LocalQuickFixProvider);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(0, 0).descriptionAndTooltip("").create();
((QuickFixProvider)psiReference).registerQuickfix(info, psiReference);
assertTrue("One action expected", info.quickFixActionRanges.size() == 1);
final LocalQuickFix[] fixes = ((LocalQuickFixProvider)psiReference).getQuickFixes();
final Pair<HighlightInfo.IntentionActionDescriptor, TextRange> 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);
}