PSI leak via the LocalQuickFix

This commit is contained in:
Alexey Kudravtsev
2011-03-31 14:57:33 +04:00
parent 1d6649bfb9
commit ed07bd205d
12 changed files with 271 additions and 154 deletions
@@ -25,21 +25,22 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.refactoring.actions.TypeCookAction;
import org.jetbrains.annotations.NotNull;
public class GenerifyFileFix implements IntentionAction, LocalQuickFix {
private final PsiFile myFile;
private final String myFileName;
public GenerifyFileFix(PsiFile file) {
myFile = file;
public GenerifyFileFix(String fileName) {
myFileName = fileName;
}
@NotNull
public String getText() {
return QuickFixBundle.message("generify.text", myFile.getName());
return QuickFixBundle.message("generify.text", myFileName);
}
@NotNull
@@ -55,21 +56,23 @@ public class GenerifyFileFix implements IntentionAction, LocalQuickFix {
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
if (isAvailable(project, null, null)) {
final PsiElement element = descriptor.getPsiElement();
if (element == null) return;
if (isAvailable(project, null, element.getContainingFile())) {
new WriteCommandAction(project) {
protected void run(Result result) throws Throwable {
invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), descriptor.getPsiElement().getContainingFile());
invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), element.getContainingFile());
}
}.execute();
}
}
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return myFile.isValid() && PsiManager.getInstance(project).isInProject(myFile);
return file != null && file.isValid() && PsiManager.getInstance(project).isInProject(file);
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
if (!CodeInsightUtilBase.prepareFileForWrite(myFile)) return;
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
new TypeCookAction().getHandler().invoke(project, editor, file, null);
}
@@ -315,24 +315,20 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
@Nullable
private static LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
if (!(element instanceof PsiExpression)) return null;
final PsiExpression expression = (PsiExpression)element;
while (element.getParent() instanceof PsiExpression) {
element = element.getParent();
}
final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
// simplify intention already active
if (!fix.isAvailable(element.getProject(), null, element.getContainingFile()) ||
SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
return null;
}
SimplifyBooleanExpressionFix fix = createIntention(element, value);
if (fix == null) return null;
final String text = fix.getText();
return new LocalQuickFix() {
@NotNull public String getName() {
return fix.getText();
@NotNull
public String getName() {
return text;
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement psiElement = descriptor.getPsiElement();
if (psiElement == null) return;
final SimplifyBooleanExpressionFix fix = createIntention(psiElement, value);
if (fix==null) return;
try {
LOG.assertTrue(psiElement.isValid());
fix.invoke(project, null, psiElement.getContainingFile());
@@ -349,6 +345,21 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
};
}
private static SimplifyBooleanExpressionFix createIntention(PsiElement element, boolean value) {
if (!(element instanceof PsiExpression)) return null;
final PsiExpression expression = (PsiExpression)element;
while (element.getParent() instanceof PsiExpression) {
element = element.getParent();
}
final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
// simplify intention already active
if (!fix.isAvailable(element.getProject(), null, element.getContainingFile()) ||
SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
return null;
}
return fix;
}
private static class RedundantInstanceofFix implements LocalQuickFix {
@NotNull
public String getName() {
@@ -33,6 +33,7 @@ import com.intellij.ui.FieldPanel;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -326,7 +327,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
final PsiDocTag tag = factory.createDocTagFromText("@" + myTag + " " + myValue);
if (docComment != null) {
PsiElement addedTag;
final PsiElement anchor = getAnchor();
final PsiElement anchor = getAnchor(descriptor);
if (anchor != null) {
addedTag = docComment.addBefore(tag, anchor);
}
@@ -343,7 +344,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
@Nullable
protected PsiElement getAnchor() {
protected PsiElement getAnchor(ProblemDescriptor descriptor) {
return null;
}
@@ -742,24 +743,36 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
PsiParameter param,
final InspectionManager manager, boolean isOnTheFly) {
String message = InspectionsBundle.message("inspection.javadoc.method.problem.missing.param.tag", "<code>@param</code>", "<code>" + param.getName() + "</code>");
return createDescriptor(elementToHighlight, message, new AddMissingParamTagFix(param), manager, isOnTheFly);
return createDescriptor(elementToHighlight, message, new AddMissingParamTagFix(param.getName()), manager, isOnTheFly);
}
private static class AddMissingParamTagFix extends AddMissingTagFix {
private final PsiParameter myParam;
private final String myName;
public AddMissingParamTagFix(final PsiParameter param) {
super("param", param.getName());
myParam = param;
public AddMissingParamTagFix(String name) {
super("param", name);
myName = name;
}
@NotNull
public String getName() {
return InspectionsBundle.message("inspection.javadoc.problem.add.param.tag", myParam.getName());
return InspectionsBundle.message("inspection.javadoc.problem.add.param.tag", myName);
}
@Nullable
protected PsiElement getAnchor() {
protected PsiElement getAnchor(ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
PsiElement parent = element == null ? null : element.getParent();
if (!(parent instanceof PsiMethod)) return null;
PsiParameter[] parameters = ((PsiMethod)parent).getParameterList().getParameters();
PsiParameter myParam = ContainerUtil.find(parameters, new Condition<PsiParameter>() {
@Override
public boolean value(PsiParameter psiParameter) {
return myName.equals(psiParameter.getName());
}
});
if (myParam == null) return null;
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(myParam, PsiMethod.class);
LOG.assertTrue(psiMethod != null);
final PsiDocComment docComment = psiMethod.getDocComment();
@@ -938,12 +951,12 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
if (tagInfo == null) {
problems.add(
createDescriptor(nameElement, InspectionsBundle.message("inspection.javadoc.problem.wrong.tag", "<code>" + tagName + "</code>"),
new AddUnknownTagToCustoms(tag), inspectionManager, isOnTheFly));
new AddUnknownTagToCustoms(tag.getName()), inspectionManager, isOnTheFly));
}
else {
problems.add(createDescriptor(nameElement, InspectionsBundle.message("inspection.javadoc.problem.disallowed.tag",
"<code>" + tagName + "</code>"),
new AddUnknownTagToCustoms(tag), inspectionManager, isOnTheFly));
new AddUnknownTagToCustoms(tag.getName()), inspectionManager, isOnTheFly));
}
}
return false;
@@ -1129,15 +1142,15 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
private class AddUnknownTagToCustoms implements LocalQuickFix {
PsiDocTag myTag;
private final String myTag;
public AddUnknownTagToCustoms(PsiDocTag tag) {
public AddUnknownTagToCustoms(String tag) {
myTag = tag;
}
@NotNull
public String getName() {
return QuickFixBundle.message("add.doctag.to.custom.tags", myTag.getName());
return QuickFixBundle.message("add.doctag.to.custom.tags", myTag);
}
@NotNull
@@ -1146,12 +1159,12 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
if (myTag == null || !myTag.isValid()) return;
if (myTag == null) return;
if (myAdditionalJavadocTags.length() > 0) {
myAdditionalJavadocTags += "," + myTag.getName();
myAdditionalJavadocTags += "," + myTag;
}
else {
myAdditionalJavadocTags = myTag.getName();
myAdditionalJavadocTags = myTag;
}
final InspectionProfile inspectionProfile =
InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
@@ -179,7 +179,7 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
}
}
}
fixes.add(new RemoveTagFix(tagName, paramName, tag));
fixes.add(new RemoveTagFix(tagName, paramName));
problems.add(inspectionManager.createProblemDescriptor(valueElement, reference.getRangeInElement(), cannotResolveSymbolMessage(params),
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, onTheFly,
@@ -300,12 +300,10 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
private static class RemoveTagFix implements LocalQuickFix {
private final String myTagName;
private final CharSequence myParamName;
private final PsiDocTag myTag;
public RemoveTagFix(String tagName, CharSequence paramName, PsiDocTag tag) {
public RemoveTagFix(String tagName, CharSequence paramName) {
myTagName = tagName;
myParamName = paramName;
myTag = tag;
}
@NotNull
@@ -319,6 +317,8 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiDocTag myTag = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiDocTag.class);
if (myTag == null) return;
myTag.delete();
}
}
@@ -213,7 +213,7 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool
if (GenericsHighlightUtil.isUncheckedCast(castType, exprType)) {
final String description =
JavaErrorMessages.message("generics.unchecked.cast", HighlightUtil.formatType(exprType), HighlightUtil.formatType(castType));
registerProblem(description, expression, myOnTheFly ? new GenerifyFileFix(operand.getContainingFile()) : null);
registerProblem(description, expression, myOnTheFly ? new GenerifyFileFix(operand.getContainingFile().getName()) : null);
}
}
@@ -227,7 +227,7 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool
if (IGNORE_UNCHECKED_CALL) return;
registerProblem(description, callExpression instanceof PsiMethodCallExpression
? ((PsiMethodCallExpression)callExpression).getMethodExpression()
: callExpression, myOnTheFly ? new GenerifyFileFix(callExpression.getContainingFile()) : null);
: callExpression, myOnTheFly ? new GenerifyFileFix(callExpression.getContainingFile().getName()) : null);
}
else {
if (IGNORE_UNCHECKED_ASSIGNMENT) return;
@@ -245,7 +245,7 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool
final PsiType parameterType = substitutor.substitute(parameter.getType());
final PsiType expressionType = substitutor.substitute(expression.getType());
if (expressionType != null) {
checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myOnTheFly ? new GenerifyFileFix(expression.getContainingFile()) : null);
checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myOnTheFly ? new GenerifyFileFix(expression.getContainingFile().getName()) : null);
}
}
}
@@ -0,0 +1,93 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class LocalQuickFixAndIntentionActionOnPsiElement implements LocalQuickFix, IntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.LocalQuickFixAndIntentionAction");
private final SmartPsiElementPointer<PsiElement> myStartElement;
private final SmartPsiElementPointer<PsiElement> myEndElement;
protected LocalQuickFixAndIntentionActionOnPsiElement(@Nullable PsiElement element) {
this(element, element);
}
protected LocalQuickFixAndIntentionActionOnPsiElement(@Nullable PsiElement startElement, @Nullable PsiElement endElement) {
if (startElement == null || endElement == null) {
myStartElement = myEndElement = null;
return;
}
LOG.assertTrue(startElement.isValid());
LOG.assertTrue(endElement == startElement || endElement.isValid());
PsiFile containingFile = startElement.getContainingFile();
LOG.assertTrue(endElement == startElement || containingFile == endElement.getContainingFile());
myStartElement = SmartPointerManager.getInstance(containingFile.getProject()).createSmartPsiElementPointer(startElement);
myEndElement = endElement == startElement ? null : SmartPointerManager.getInstance(containingFile.getProject()).createSmartPsiElementPointer(endElement);
}
@Override
public final void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (file == null||myStartElement==null) return;
final PsiElement startElement = myStartElement.getElement();
final PsiElement endElement = myEndElement == null ? startElement : myEndElement.getElement();
if (startElement == null || endElement == null) return;
invoke(project, file, startElement, endElement);
}
@Override
public final void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
if (myStartElement == null) return;
final PsiElement startElement = myStartElement.getElement();
final PsiElement endElement = myEndElement == null ? startElement : myEndElement.getElement();
if (startElement == null || endElement == null) return;
invoke(project, startElement.getContainingFile(), startElement, endElement);
}
@Override
public final boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (myStartElement == null) return false;
final PsiElement startElement = myStartElement.getElement();
final PsiElement endElement = myEndElement == null ? startElement : myEndElement.getElement();
return startElement != null &&
endElement != null &&
startElement.isValid() &&
(endElement == startElement || endElement.isValid()) &&
isAvailable(project, file, startElement, endElement);
}
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
return true;
}
public PsiElement getStartElement() {
return myStartElement.getElement();
}
public abstract void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement);
}
@@ -77,7 +77,7 @@ public class IfCanBeSwitchInspection extends BaseInspection {
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
return new IfCanBeSwitchFix((PsiExpression) infos[0]);
return new IfCanBeSwitchFix(minimumBranches);
}
@Override
@@ -146,12 +146,11 @@ public class IfCanBeSwitchInspection extends BaseInspection {
}
private static class IfCanBeSwitchFix extends InspectionGadgetsFix {
private final int myMinimumBranches;
private final PsiExpression switchExpression;
public IfCanBeSwitchFix(PsiExpression switchExpression) {
this.switchExpression = switchExpression;
}
public IfCanBeSwitchFix(int minimumBranches) {
myMinimumBranches = minimumBranches;
}
@NotNull
public String getName() {
@@ -193,8 +192,12 @@ public class IfCanBeSwitchInspection extends BaseInspection {
final List<IfStatementBranch> branches =
new ArrayList<IfStatementBranch>(20);
while (true) {
final PsiExpression condition = ifStatement.getCondition();
final PsiExpression switchExpression =
SwitchUtils.getSwitchExpression(ifStatement, myMinimumBranches);
if (switchExpression == null) return;
while (true) {
final PsiExpression condition = ifStatement.getCondition();
final List<PsiExpression> labels =
getValuesFromExpression(condition, switchExpression,
new ArrayList());
@@ -361,33 +361,24 @@ public class I18nInspection extends BaseLocalInspectionTool {
return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
}
private static LocalQuickFix createIntroduceConstantFix(final PsiExpression... expressions) {
//noinspection unchecked
final SmartPsiElementPointer<PsiExpression>[] pointers = new SmartPsiElementPointer[expressions.length];
for(int i=0; i<expressions.length; i++) {
pointers [i] = SmartPointerManager.getInstance(expressions [i].getProject()).createSmartPsiElementPointer(expressions [i]);
}
private static LocalQuickFix createIntroduceConstantFix() {
return new LocalQuickFix() {
@NotNull
public String getName() {
return IntroduceConstantHandler.REFACTORING_NAME;
}
public void applyFix(@NotNull final Project project, @NotNull ProblemDescriptor descriptor) {
final Runnable runnable = new Runnable() {
public void run() {
List<PsiExpression> exprList = new ArrayList<PsiExpression>();
for (SmartPsiElementPointer<PsiExpression> ptr : pointers) {
PsiExpression expr = ptr.getElement();
if (expr != null && expr.isValid()) {
exprList.add(expr);
}
}
new IntroduceConstantHandler().invoke(project, exprList.toArray(new PsiExpression[exprList.size()]));
}
};
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
//do it later because it is invoked from write action
ApplicationManager.getApplication().invokeLater(runnable);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
PsiElement element = descriptor.getPsiElement();
if (!(element instanceof PsiExpression)) return;
PsiExpression[] expressions = {(PsiExpression)element};
new IntroduceConstantHandler().invoke(project, expressions);
}
}, project.getDisposed());
}
@NotNull
@@ -439,7 +430,7 @@ public class I18nInspection extends BaseLocalInspectionTool {
fixes.add(I18N_QUICK_FIX);
if (!isNotConstantFieldInitializer(expression)) {
fixes.add(createIntroduceConstantFix(expression));
fixes.add(createIntroduceConstantFix());
}
final Project project = expression.getManager().getProject();
@@ -454,9 +445,10 @@ public class I18nInspection extends BaseLocalInspectionTool {
}
}
final ProblemDescriptor problem = myManager
.createProblemDescriptor(expression,
description, myOnTheFly, fixes.toArray(new LocalQuickFix[fixes.size()]), ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
LocalQuickFix[] farr = fixes.toArray(new LocalQuickFix[fixes.size()]);
final ProblemDescriptor problem = myManager.createProblemDescriptor(expression,
description, myOnTheFly, farr,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
myProblems.add(problem);
}
}
@@ -101,7 +101,7 @@ public class HtmlUnknownAttributeInspection extends HtmlUnknownTagInspection {
boolean maySwitchToHtml5 = HtmlUtil.isCustomHtml5Attribute(name) && !HtmlUtil.hasNonHtml5Doctype(tag);
LocalQuickFix[] quickfixes = new LocalQuickFix[maySwitchToHtml5 ? 3 : 2];
quickfixes[0] = new AddCustomTagOrAttributeIntentionAction(getShortName(), name, XmlEntitiesInspection.UNKNOWN_ATTRIBUTE);
quickfixes[1] = new RemoveAttributeIntentionAction(name, attribute);
quickfixes[1] = new RemoveAttributeIntentionAction(name);
if (maySwitchToHtml5) {
quickfixes[2] = new SwitchToHtml5WithHighPriorityAction();
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import org.jetbrains.annotations.NotNull;
@@ -32,11 +33,9 @@ import org.jetbrains.annotations.NotNull;
*/
public class RemoveAttributeIntentionAction implements LocalQuickFix {
private final String myLocalName;
private final XmlAttribute myAttribute;
public RemoveAttributeIntentionAction(final String localName, final XmlAttribute attribute) {
public RemoveAttributeIntentionAction(final String localName) {
myLocalName = localName;
myAttribute = attribute;
}
@NotNull
@@ -50,28 +49,18 @@ public class RemoveAttributeIntentionAction implements LocalQuickFix {
}
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
PsiElement e = descriptor.getPsiElement();
final XmlAttribute myAttribute = PsiTreeUtil.getParentOfType(e, XmlAttribute.class);
if (myAttribute == null) return;
if (!CodeInsightUtilBase.prepareFileForWrite(myAttribute.getContainingFile())) {
return;
}
PsiElement next = findNextAttribute(myAttribute);
new WriteCommandAction(project) {
protected void run(final Result result) throws Throwable {
myAttribute.delete();
}
}.execute();
//if (next != null) {
// editor.getCaretModel().moveToOffset(next.getTextRange().getStartOffset());
//}
}
private static PsiElement findNextAttribute(final XmlAttribute attribute) {
PsiElement nextSibling = attribute.getNextSibling();
while (nextSibling != null) {
if (nextSibling instanceof XmlAttribute) return nextSibling;
nextSibling = nextSibling.getNextSibling();
}
return null;
}
}
@@ -21,15 +21,16 @@ import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.daemon.XmlErrorMessages;
import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor;
import com.intellij.codeInspection.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.html.HtmlTag;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.xml.XmlBundle;
import com.intellij.xml.util.XmlUtil;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -107,29 +108,7 @@ public class XmlWrongRootElementInspection extends HtmlLocalInspectionTool {
if (tag instanceof HtmlTag) {
return; // it is legal to have html / head / body omitted
}
final LocalQuickFix localQuickFix = new LocalQuickFix() {
@NotNull
public String getName() {
return XmlBundle.message("change.root.element.to", doctype.getNameElement().getText());
}
@NotNull
public String getFamilyName() {
return getName();
}
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
if (!CodeInsightUtilBase.prepareFileForWrite(tag.getContainingFile())) {
return;
}
new WriteCommandAction(project) {
protected void run(final Result result) throws Throwable {
tag.setName(doctype.getNameElement().getText());
}
}.execute();
}
};
final LocalQuickFix localQuickFix = new MyLocalQuickFix(doctype.getNameElement().getText());
holder.registerProblem(XmlChildRole.START_TAG_NAME_FINDER.findChild(tag.getNode()).getPsi(),
XmlErrorMessages.message("wrong.root.element"),
@@ -147,4 +126,36 @@ public class XmlWrongRootElementInspection extends HtmlLocalInspectionTool {
}
}
}
private static class MyLocalQuickFix implements LocalQuickFix {
private final String myText;
public MyLocalQuickFix(String text) {
myText = text;
}
@NotNull
public String getName() {
return XmlBundle.message("change.root.element.to", myText);
}
@NotNull
public String getFamilyName() {
return getName();
}
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final XmlTag myTag = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), XmlTag.class);
if (!CodeInsightUtilBase.prepareFileForWrite(myTag.getContainingFile())) {
return;
}
new WriteCommandAction(project) {
protected void run(final Result result) throws Throwable {
myTag.setName(myText);
}
}.execute();
}
}
}
@@ -68,41 +68,7 @@ public class CheckEmptyTagInspection extends XmlSuppressableInspectionTool {
return;
}
final LocalQuickFix fix = new LocalQuickFix() {
@NotNull
public String getName() {
return XmlBundle.message("html.inspections.check.empty.script.tag.fix.message");
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final XmlTag tag = (XmlTag)descriptor.getPsiElement();
if (tag == null) return;
final PsiFile psiFile = tag.getContainingFile();
if (psiFile == null) return;
ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(psiFile.getVirtualFile());
final StringBuilder builder = new StringBuilder(tag.getText());
builder.replace(builder.length() - 2, builder.length(), "></" + tag.getLocalName() + ">");
try {
final FileType fileType = psiFile.getFileType();
PsiFile file = PsiFileFactory.getInstance(tag.getProject()).createFileFromText(
"dummy." + (fileType == StdFileTypes.JSP || tag.getContainingFile().getLanguage() == HTMLLanguage.INSTANCE ? "html" : "xml"), builder.toString());
tag.replace(((XmlFile)file).getDocument().getRootTag());
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
//to appear in "Apply Fix" statement when multiple Quick Fixes exist
@NotNull
public String getFamilyName() {
return getName();
}
};
final LocalQuickFix fix = new MyLocalQuickFix();
holder.registerProblem(tag,
XmlBundle.message("html.inspections.check.empty.script.message"),
@@ -138,4 +104,40 @@ public class CheckEmptyTagInspection extends XmlSuppressableInspectionTool {
public String getShortName() {
return "CheckEmptyScriptTag";
}
private static class MyLocalQuickFix implements LocalQuickFix {
@NotNull
public String getName() {
return XmlBundle.message("html.inspections.check.empty.script.tag.fix.message");
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final XmlTag tag = (XmlTag)descriptor.getPsiElement();
if (tag == null) return;
final PsiFile psiFile = tag.getContainingFile();
if (psiFile == null) return;
ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(psiFile.getVirtualFile());
final StringBuilder builder = new StringBuilder(tag.getText());
builder.replace(builder.length() - 2, builder.length(), "></" + tag.getLocalName() + ">");
try {
final FileType fileType = psiFile.getFileType();
PsiFile file = PsiFileFactory.getInstance(tag.getProject()).createFileFromText(
"dummy." + (fileType == StdFileTypes.JSP || tag.getContainingFile().getLanguage() == HTMLLanguage.INSTANCE ? "html" : "xml"), builder.toString());
tag.replace(((XmlFile)file).getDocument().getRootTag());
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
//to appear in "Apply Fix" statement when multiple Quick Fixes exist
@NotNull
public String getFamilyName() {
return getName();
}
}
}