mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
PSI leak via the LocalQuickFix
This commit is contained in:
+11
-8
@@ -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() {
|
||||
|
||||
+30
-17
@@ -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();
|
||||
|
||||
+4
-4
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+93
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
+6
-17
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+35
-24
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user