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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user