mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
api to provide cumulative quick fixes which can show one dialog for all selected problems in batch mode
This commit is contained in:
+34
-34
@@ -21,8 +21,6 @@ import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.InspectionTool;
|
||||
import com.intellij.codeInspection.ex.QuickFixAction;
|
||||
import com.intellij.codeInspection.reference.*;
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -33,7 +31,7 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.AllOverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.Query;
|
||||
@@ -319,7 +317,7 @@ public class EmptyMethodInspection extends GlobalJavaInspectionTool {
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
SafeDeleteHandler.invoke(project, PsiUtilBase.toPsiElementArray(psiElements), false);
|
||||
SafeDeleteHandler.invoke(project, PsiUtilCore.toPsiElementArray(psiElements), false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -327,13 +325,13 @@ public class EmptyMethodInspection extends GlobalJavaInspectionTool {
|
||||
}
|
||||
|
||||
|
||||
private class DeleteMethodQuickFix implements LocalQuickFix {
|
||||
private class DeleteMethodQuickFix implements LocalQuickFix, BatchQuickFix<CommonProblemDescriptor> {
|
||||
private final ProblemDescriptionsProcessor myProcessor;
|
||||
private final boolean myNeedToDEleteHierarchy;
|
||||
private final boolean myNeedToDeleteHierarchy;
|
||||
|
||||
public DeleteMethodQuickFix(final ProblemDescriptionsProcessor processor, final boolean needToDeleteHierarchy) {
|
||||
myProcessor = processor;
|
||||
myNeedToDEleteHierarchy = needToDeleteHierarchy;
|
||||
myNeedToDeleteHierarchy = needToDeleteHierarchy;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -342,28 +340,7 @@ public class EmptyMethodInspection extends GlobalJavaInspectionTool {
|
||||
}
|
||||
|
||||
public void applyFix(final @NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
RefElement refElement = (RefElement)myProcessor.getElement(descriptor);
|
||||
if (refElement.isValid() && refElement instanceof RefMethod) {
|
||||
final List<RefElement> refElements = new ArrayList<RefElement>(1);
|
||||
RefMethod refMethod = (RefMethod)refElement;
|
||||
final List<PsiElement> psiElements = new ArrayList<PsiElement>();
|
||||
if (myNeedToDEleteHierarchy) {
|
||||
deleteHierarchy(refMethod, psiElements, refElements);
|
||||
} else {
|
||||
deleteMethod(refMethod, psiElements, refElements);
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
SafeDeleteHandler.invoke(project, PsiUtilBase.toPsiElementArray(psiElements), false, new Runnable() {
|
||||
public void run() {
|
||||
QuickFixAction
|
||||
.removeElements(refElements.toArray(new RefElement[refElements.size()]), project, (InspectionTool)myProcessor);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
applyFix(project, new ProblemDescriptor[]{descriptor}, new ArrayList<PsiElement>(), null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -371,20 +348,43 @@ public class EmptyMethodInspection extends GlobalJavaInspectionTool {
|
||||
return getName();
|
||||
}
|
||||
|
||||
private void deleteHierarchy(RefMethod refMethod, List<PsiElement> result, List<RefElement> refElements) {
|
||||
private void deleteHierarchy(RefMethod refMethod, List<PsiElement> result) {
|
||||
Collection<RefMethod> derivedMethods = refMethod.getDerivedMethods();
|
||||
RefMethod[] refMethods = derivedMethods.toArray(new RefMethod[derivedMethods.size()]);
|
||||
for (RefMethod refDerived : refMethods) {
|
||||
deleteMethod(refDerived, result, refElements);
|
||||
deleteMethod(refDerived, result);
|
||||
}
|
||||
deleteMethod(refMethod, result, refElements);
|
||||
deleteMethod(refMethod, result);
|
||||
}
|
||||
|
||||
private void deleteMethod(RefMethod refMethod, List<PsiElement> result, List<RefElement> refElements) {
|
||||
refElements.add(refMethod);
|
||||
private void deleteMethod(RefMethod refMethod, List<PsiElement> result) {
|
||||
PsiElement psiElement = refMethod.getElement();
|
||||
if (psiElement == null) return;
|
||||
if (!result.contains(psiElement)) result.add(psiElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull final Project project,
|
||||
@NotNull final CommonProblemDescriptor[] descriptors,
|
||||
final List<PsiElement> psiElementsToIgnore,
|
||||
final Runnable refreshViews) {
|
||||
for (CommonProblemDescriptor descriptor : descriptors) {
|
||||
RefElement refElement = (RefElement)myProcessor.getElement(descriptor);
|
||||
if (refElement.isValid() && refElement instanceof RefMethod) {
|
||||
RefMethod refMethod = (RefMethod)refElement;
|
||||
if (myNeedToDeleteHierarchy) {
|
||||
deleteHierarchy(refMethod, psiElementsToIgnore);
|
||||
}
|
||||
else {
|
||||
deleteMethod(refMethod, psiElementsToIgnore);
|
||||
}
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
SafeDeleteHandler.invoke(project, PsiUtilCore.toPsiElementArray(psiElementsToIgnore), false, refreshViews);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 10/27/11
|
||||
*/
|
||||
public interface BatchQuickFix<D extends CommonProblemDescriptor> {
|
||||
/**
|
||||
* Called to apply the cumulative fix. Is invoked in WriteAction
|
||||
*
|
||||
* @param project {@link com.intellij.openapi.project.Project}
|
||||
* @param descriptors problem reported by the tool on which fix should work
|
||||
* @param psiElementsToIgnore elements to be excluded from view during post-refresh
|
||||
* @param refreshViews post-refresh inspection results view; would remove collected elements from the view
|
||||
*/
|
||||
void applyFix(@NotNull final Project project,
|
||||
@NotNull final D[] descriptors,
|
||||
final List<PsiElement> psiElementsToIgnore,
|
||||
final Runnable refreshViews);
|
||||
}
|
||||
@@ -16,10 +16,20 @@
|
||||
|
||||
package com.intellij.codeInspection.ex;
|
||||
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.reference.RefElement;
|
||||
import com.intellij.codeInspection.reference.RefEntity;
|
||||
import com.intellij.codeInspection.reference.RefManager;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -27,6 +37,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
public class LocalQuickFixWrapper extends QuickFixAction {
|
||||
private final QuickFix myFix;
|
||||
private String myText;
|
||||
|
||||
public LocalQuickFixWrapper(QuickFix fix, DescriptorProviderInspection tool) {
|
||||
super(fix.getName(), tool);
|
||||
myTool = tool;
|
||||
@@ -48,26 +59,6 @@ public class LocalQuickFixWrapper extends QuickFixAction {
|
||||
myText = text;
|
||||
}
|
||||
|
||||
protected boolean applyFix(RefElement[] refElements) {
|
||||
/* dead code ?!
|
||||
for (RefElement refElement : refElements) {
|
||||
ProblemDescriptor[] problems = myTool.getDescriptions(refElement);
|
||||
if (problems != null) {
|
||||
PsiElement psiElement = refElement.getElement();
|
||||
if (psiElement != null) {
|
||||
for (ProblemDescriptor problem : problems) {
|
||||
LocalQuickFix fix = problem.getFix();
|
||||
if (fix != null) {
|
||||
fix.applyFix(psiElement.getProject(), problem);
|
||||
myTool.ignoreProblem(refElement, problem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isProblemDescriptorsAcceptable() {
|
||||
return true;
|
||||
@@ -76,4 +67,79 @@ public class LocalQuickFixWrapper extends QuickFixAction {
|
||||
public QuickFix getFix() {
|
||||
return myFix;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected QuickFix getWorkingQuickFix(QuickFix[] fixes) {
|
||||
for (QuickFix fix : fixes) {
|
||||
if (!myFix.getClass().isInstance(fix)) continue;
|
||||
if (myFix instanceof IntentionWrapper && fix instanceof IntentionWrapper &&
|
||||
!(((IntentionWrapper)myFix).getAction().getClass().isInstance(((IntentionWrapper)fix).getAction()))) {
|
||||
continue;
|
||||
}
|
||||
return fix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean applyFix(RefElement[] refElements) {
|
||||
throw new UnsupportedOperationException("");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyFix(final Project project, final CommonProblemDescriptor[] descriptors, final Set<PsiElement> ignoredElements) {
|
||||
final PsiModificationTracker tracker = PsiManager.getInstance(project).getModificationTracker();
|
||||
if (myFix instanceof BatchQuickFix) {
|
||||
final ArrayList<PsiElement> collectedElementsToIgnore = new ArrayList<PsiElement>();
|
||||
final Runnable refreshViews = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
for (CommonProblemDescriptor descriptor : descriptors) {
|
||||
ignore(ignoredElements, descriptor, getWorkingQuickFix(descriptor.getFixes()));
|
||||
}
|
||||
|
||||
final RefManager refManager = myTool.getContext().getRefManager();
|
||||
final RefElement[] refElements = new RefElement[collectedElementsToIgnore.size()];
|
||||
for (int i = 0, collectedElementsToIgnoreSize = collectedElementsToIgnore.size(); i < collectedElementsToIgnoreSize; i++) {
|
||||
refElements[i] = refManager.getReference(collectedElementsToIgnore.get(i));
|
||||
}
|
||||
|
||||
removeElements(refElements, project, myTool);
|
||||
}
|
||||
};
|
||||
|
||||
((BatchQuickFix)myFix).applyFix(project, descriptors, collectedElementsToIgnore, refreshViews);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean restart = false;
|
||||
for (CommonProblemDescriptor descriptor : descriptors) {
|
||||
if (descriptor == null) continue;
|
||||
final QuickFix[] fixes = descriptor.getFixes();
|
||||
if (fixes != null) {
|
||||
final QuickFix fix = getWorkingQuickFix(fixes);
|
||||
if (fix != null) {
|
||||
final long startCount = tracker.getModificationCount();
|
||||
//CCE here means QuickFix was incorrectly inherited, is there a way to signal (plugin) it is wrong?
|
||||
fix.applyFix(project, descriptor);
|
||||
if (startCount != tracker.getModificationCount()) {
|
||||
restart = true;
|
||||
ignore(ignoredElements, descriptor, fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (restart) {
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
}
|
||||
}
|
||||
|
||||
private void ignore(Set<PsiElement> ignoredElements, CommonProblemDescriptor descriptor, QuickFix fix) {
|
||||
if (fix != null) {
|
||||
((DescriptorProviderInspection)myTool).ignoreProblem(descriptor, fix);
|
||||
}
|
||||
if (descriptor instanceof ProblemDescriptor) {
|
||||
ignoredElements.add(((ProblemDescriptor)descriptor).getPsiElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
package com.intellij.codeInspection.ex;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.CommonProblemDescriptor;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.reference.RefElement;
|
||||
import com.intellij.codeInspection.reference.RefEntity;
|
||||
import com.intellij.codeInspection.reference.RefManagerImpl;
|
||||
@@ -36,8 +37,6 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import gnu.trove.THashSet;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -110,6 +109,7 @@ public class QuickFixAction extends AnAction {
|
||||
}
|
||||
|
||||
|
||||
protected void applyFix(Project project, CommonProblemDescriptor[] descriptors, Set<PsiElement> ignoredElements) {}
|
||||
private void doApplyFix(final Project project,
|
||||
final CommonProblemDescriptor[] descriptors) {
|
||||
final Set<VirtualFile> readOnlyFiles = new THashSet<VirtualFile>();
|
||||
@@ -139,38 +139,7 @@ public class QuickFixAction extends AnAction {
|
||||
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiModificationTracker tracker = PsiManager.getInstance(project).getModificationTracker();
|
||||
for (CommonProblemDescriptor descriptor : descriptors) {
|
||||
if (descriptor == null) continue;
|
||||
final QuickFix[] fixes = descriptor.getFixes();
|
||||
if (fixes != null) {
|
||||
for (QuickFix fix : fixes) {
|
||||
if (fix != null) {
|
||||
final QuickFixAction quickFixAction = QuickFixAction.this;
|
||||
if (quickFixAction instanceof LocalQuickFixWrapper) {
|
||||
QuickFix unwrapped = ((LocalQuickFixWrapper)quickFixAction).getFix();
|
||||
|
||||
if (!unwrapped.getClass().isInstance(fix)) continue;
|
||||
if (unwrapped instanceof IntentionWrapper && fix instanceof IntentionWrapper &&
|
||||
!(((IntentionWrapper) unwrapped).getAction().getClass().isInstance(((IntentionWrapper) fix).getAction()))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final long startCount = tracker.getModificationCount();
|
||||
//CCE here means QuickFix was incorrectly inherited, is there a way to signal (plugin) it is wrong?
|
||||
fix.applyFix(project, descriptor);
|
||||
if (startCount != tracker.getModificationCount()) {
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
((DescriptorProviderInspection)myTool).ignoreProblem(descriptor, fix);
|
||||
if (descriptor instanceof ProblemDescriptor) {
|
||||
ignoredElements.add(((ProblemDescriptor)descriptor).getPsiElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
applyFix(project, descriptors, ignoredElements);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user