mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
do not remove invoked quick fix from the list if it did nothing to fix IDEA-173961 "Interrupted" quick fix disappears from popup
This commit is contained in:
+31
-1
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.hint.EditorHintListener;
|
||||
import com.intellij.codeInsight.intention.AbstractIntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionActionDelegate;
|
||||
import com.intellij.codeInsight.intention.IntentionManager;
|
||||
import com.intellij.codeInsight.intention.impl.IntentionHintComponent;
|
||||
import com.intellij.codeInspection.*;
|
||||
@@ -36,6 +37,7 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
|
||||
import com.intellij.codeInspection.ex.InspectionToolRegistrar;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.ex.QuickFixWrapper;
|
||||
import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspectionBase;
|
||||
import com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection;
|
||||
import com.intellij.configurationStore.StorageUtilKt;
|
||||
@@ -2651,7 +2653,32 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
assertEmpty(fixes);
|
||||
}
|
||||
|
||||
public void testStupidQuickFixIsStillVisibleAfterAppliedButDidNothing() {
|
||||
MyInspection tool = new MyInspection();
|
||||
enableInspectionTool(tool);
|
||||
disposeOnTearDown(() -> disableInspectionTool(tool.getShortName()));
|
||||
|
||||
@Language("JAVA")
|
||||
String text = "class X { void f() { if (this == null) {} else return; } }";
|
||||
configureByText(JavaFileType.INSTANCE, text);
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> myEditor.getDocument().setText(text));
|
||||
getEditor().getCaretModel().moveToOffset(getFile().getText().indexOf("if (") + 1);
|
||||
assertEmpty(doHighlighting(HighlightSeverity.ERROR));
|
||||
List<IntentionAction> fixes = findStupidFixes();
|
||||
IntentionAction fix = assertOneElement(fixes);
|
||||
((MyInspection.StupidQuickFixWhichDoesntCheckItsOwnApplicability)((QuickFixWrapper)((IntentionActionDelegate)fix).getDelegate()).getFix()).doFix = false;
|
||||
fix.invoke(getProject(), getEditor(), getFile()); // did nothing
|
||||
|
||||
fixes = findStupidFixes();
|
||||
assertOneElement(fixes);
|
||||
|
||||
assertEmpty(doHighlighting(HighlightSeverity.ERROR));
|
||||
fixes = findStupidFixes();
|
||||
assertOneElement(fixes);
|
||||
}
|
||||
|
||||
private List<IntentionAction> findStupidFixes() {
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
return CodeInsightTestFixtureImpl.getAvailableIntentions(getEditor(), getFile())
|
||||
.stream().filter(f->f.getFamilyName().equals(new MyInspection.StupidQuickFixWhichDoesntCheckItsOwnApplicability().getFamilyName()))
|
||||
.collect(Collectors.toList());
|
||||
@@ -2692,6 +2719,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
};
|
||||
}
|
||||
private static class StupidQuickFixWhichDoesntCheckItsOwnApplicability implements LocalQuickFix {
|
||||
private boolean doFix = true;
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -2708,7 +2736,9 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
WriteCommandAction.runWriteCommandAction(project, () -> ((PsiIfStatement)descriptor.getPsiElement().getParent()).getElseBranch().delete());
|
||||
if (doFix) {
|
||||
WriteCommandAction.runWriteCommandAction(project, () -> ((PsiIfStatement)descriptor.getPsiElement().getParent()).getElseBranch().delete());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,14 +59,12 @@ import com.intellij.openapi.roots.ModuleRootEvent;
|
||||
import com.intellij.openapi.roots.ModuleRootListener;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.SimpleModificationTracker;
|
||||
import com.intellij.openapi.util.UserDataHolderEx;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileListener;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFilePropertyEvent;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.impl.status.TogglePopupHintsPanel;
|
||||
@@ -94,7 +92,10 @@ import java.util.List;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class DaemonListeners implements Disposable {
|
||||
public class DaemonListeners
|
||||
extends SimpleModificationTracker // modCount will change whenever daemon-worthy event happens
|
||||
implements Disposable {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.DaemonListeners");
|
||||
|
||||
private final Project myProject;
|
||||
@@ -280,7 +281,7 @@ public class DaemonListeners implements Disposable {
|
||||
});
|
||||
|
||||
connection.subscribe(PowerSaveMode.TOPIC, () -> stopDaemon(true, "Power save mode change"));
|
||||
connection.subscribe(EditorColorsManager.TOPIC, scheme -> stopDaemonAndRestartAllFiles("Editor color scheme changed"));
|
||||
connection.subscribe(EditorColorsManager.TOPIC, __ -> stopDaemonAndRestartAllFiles("Editor color scheme changed"));
|
||||
|
||||
commandProcessor.addCommandListener(new MyCommandListener(), this);
|
||||
application.addApplicationListener(new MyApplicationListener(), this);
|
||||
@@ -291,6 +292,7 @@ public class DaemonListeners implements Disposable {
|
||||
virtualFileManager.addVirtualFileListener(new VirtualFileListener() {
|
||||
@Override
|
||||
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
|
||||
incModificationCount();
|
||||
String propertyName = event.getPropertyName();
|
||||
if (VirtualFile.PROP_NAME.equals(propertyName)) {
|
||||
stopDaemonAndRestartAllFiles("Virtual file name changed");
|
||||
@@ -318,6 +320,31 @@ public class DaemonListeners implements Disposable {
|
||||
stopDaemon(true, "Virtual file property change");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
incModificationCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforePropertyChange(@NotNull VirtualFilePropertyEvent event) {
|
||||
incModificationCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeContentsChange(@NotNull VirtualFileEvent event) {
|
||||
incModificationCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {
|
||||
incModificationCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {
|
||||
incModificationCount();
|
||||
}
|
||||
}, this);
|
||||
|
||||
((EditorEventMulticasterEx)eventMulticaster).addErrorStripeListener(new ErrorStripeHandler(myProject), this);
|
||||
@@ -614,12 +641,14 @@ public class DaemonListeners implements Disposable {
|
||||
}
|
||||
|
||||
private void stopDaemon(boolean toRestartAlarm, @NonNls @NotNull String reason) {
|
||||
incModificationCount();
|
||||
if (myDaemonCodeAnalyzer.stopProcess(toRestartAlarm, reason)) {
|
||||
myDaemonEventPublisher.daemonCancelEventOccurred(reason);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopDaemonAndRestartAllFiles(@NotNull String reason) {
|
||||
incModificationCount();
|
||||
if (myDaemonCodeAnalyzer.doRestart()) {
|
||||
myDaemonEventPublisher.daemonCancelEventOccurred(reason);
|
||||
}
|
||||
|
||||
+10
-1
@@ -16,11 +16,13 @@
|
||||
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonListeners;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionActionDelegate;
|
||||
import com.intellij.openapi.actionSystem.ShortcutProvider;
|
||||
import com.intellij.openapi.actionSystem.ShortcutSet;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
@@ -178,12 +180,19 @@ public class IntentionActionWithTextCaching implements Comparable<IntentionActio
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
// if anything changed after action executed, mark it invoked.
|
||||
// alternatively, the action could have shown the dialog where user pressed cancel, so do nothing in this case
|
||||
long startModificationCount = DaemonListeners.getInstance(project).getModificationCount();
|
||||
try {
|
||||
myAction.invoke(project, editor, file);
|
||||
}
|
||||
finally {
|
||||
if (myMarkInvoked != null) {
|
||||
myMarkInvoked.accept(IntentionActionWithTextCaching.this, myAction);
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
if (startModificationCount != DaemonListeners.getInstance(project).getModificationCount()) {
|
||||
myMarkInvoked.accept(IntentionActionWithTextCaching.this, myAction);
|
||||
}
|
||||
}, project.getDisposed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -63,6 +63,7 @@ public class IntentionListStep implements ListPopupStep<IntentionActionWithTextC
|
||||
@Nullable
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
@NotNull
|
||||
private final Project myProject;
|
||||
private static final TObjectHashingStrategy<IntentionActionWithTextCaching> ACTION_TEXT_AND_CLASS_EQUALS = new TObjectHashingStrategy<IntentionActionWithTextCaching>() {
|
||||
@Override
|
||||
@@ -284,7 +285,7 @@ public class IntentionListStep implements ListPopupStep<IntentionActionWithTextC
|
||||
}
|
||||
|
||||
private void markInvoked(@NotNull IntentionAction action) {
|
||||
if (myEditor != null) {
|
||||
if (myEditor != null && !myEditor.isDisposed() && !myProject.isDisposed()) {
|
||||
ShowIntentionsPass.markActionInvoked(myFile.getProject(), myEditor, action);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user