From 367d5a99e58b33cf76267f2899fa4521f291c54a Mon Sep 17 00:00:00 2001
From: peter
Date: Tue, 16 Aug 2016 13:35:41 +0200
Subject: [PATCH] make actions not require transactions by default (fixes
IDEA-146640 and numerous exceptions)
---
.../openapi/application/TransactionGuard.java | 6 ++----
.../com/intellij/openapi/actionSystem/AnAction.java | 8 +++++++-
.../codeInsight/actions/CodeInsightAction.java | 6 +++++-
.../refactoring/actions/BaseRefactoringAction.java | 5 +++++
.../openapi/editor/actionSystem/EditorAction.java | 5 -----
.../src/com/intellij/openapi/ui/DialogWrapper.java | 12 +++---------
.../openapi/ui/impl/DialogWrapperPeerImpl.java | 5 -----
7 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java b/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java
index a94dfd7adfdc..8f183710f6fc 100644
--- a/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java
+++ b/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java
@@ -55,11 +55,9 @@ import org.jetbrains.annotations.Nullable;
* FAQ
*
* Q: When should transactions be used?
- * A: Whenever the code inside isn't prepared to model being modified from the outside world. Which is, almost always. AnAction-s
- * are wrapped into transactions by default. It only makes sense to opt out (by overriding AnAction#startInTransaction), if your actions
+ * A: Whenever the code inside isn't prepared to model being modified from the outside world. Which is, almost always. Well known base AnAction
+ * classes that work with PSI are wrapped into transactions by default. It only makes sense to opt out (by overriding AnAction#startInTransaction), if your actions
* don't modify the PSI/document/VFS model in any way, and can be invoked in a dialog that's shown from invokeLater.
- * Example: editor actions in dialogs like "Enter Password", which doesn't care about model and can be requested to be shown from background threads
- * in any modality state.
*
*
* Q: I've got "Write access is allowed from model transactions only"
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
index 0478f98236af..57d5ed9094c4 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
@@ -319,8 +319,14 @@ public abstract class AnAction implements PossiblyDumbAware {
return this instanceof DumbAware;
}
+ /**
+ * @return whether this action should be wrapped into a single transaction. PSI/VFS-related actions
+ * that can show progresses or modal dialogs should return true. The default value is false, to prevent
+ * transaction-related assertions from actions in harmless dialogs like "Enter password" shown inside invokeLater.
+ * @see com.intellij.openapi.application.TransactionGuard
+ */
public boolean startInTransaction() {
- return true;
+ return false;
}
public interface TransparentUpdate {
diff --git a/platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java b/platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java
index d32873f26133..a17df5d15cf9 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java
@@ -23,7 +23,6 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import org.jetbrains.annotations.NotNull;
@@ -42,6 +41,11 @@ public abstract class CodeInsightAction extends AnAction {
}
}
+ @Override
+ public boolean startInTransaction() {
+ return true;
+ }
+
@Nullable
protected Editor getEditor(@NotNull DataContext dataContext, @NotNull Project project, boolean forUpdate) {
return CommonDataKeys.EDITOR.getData(dataContext);
diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java
index b3624bcfe022..7fbad12a03b0 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java
@@ -55,6 +55,11 @@ public abstract class BaseRefactoringAction extends AnAction {
protected abstract boolean isEnabledOnElements(@NotNull PsiElement[] elements);
+ @Override
+ public boolean startInTransaction() {
+ return true;
+ }
+
protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext context) {
return true;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
index c3d1fa5db9ca..a6a92aa498af 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
@@ -44,11 +44,6 @@ public abstract class EditorAction extends AnAction implements DumbAware {
setEnabledInModalContext(true);
}
- @Override
- public boolean startInTransaction() {
- return false;
- }
-
public final EditorActionHandler setupHandler(@NotNull EditorActionHandler newHandler) {
ensureHandlersLoaded();
EditorActionHandler tmp = myHandler;
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index 898e9b7298bd..347182a0047c 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -747,7 +747,7 @@ public abstract class DialogWrapper {
final char mnemonic = (char)eachInfo.getMnemonic();
JRootPane rootPane = getPeer().getRootPane();
if (rootPane != null) {
- new NoTransactionAction() {
+ new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
final JBOptionButton buttonToActivate = eachInfo.getButton();
@@ -1275,7 +1275,7 @@ public abstract class DialogWrapper {
myPeer.setContentPane(root);
final CustomShortcutSet sc = new CustomShortcutSet(SHOW_OPTION_KEYSTROKE);
- final AnAction toggleShowOptions = new NoTransactionAction() {
+ final AnAction toggleShowOptions = new DumbAwareAction() {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
expandNextOptionButton();
@@ -1335,7 +1335,7 @@ public abstract class DialogWrapper {
}
private static void installEnterHook(JComponent root, Disposable disposable) {
- new NoTransactionAction() {
+ new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
@@ -2171,10 +2171,4 @@ public abstract class DialogWrapper {
public enum DialogStyle {NO_STYLE, COMPACT}
- private static abstract class NoTransactionAction extends DumbAwareAction {
- @Override
- public boolean startInTransaction() {
- return false;
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
index e15b6351e343..66fc9d009eb8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
@@ -479,11 +479,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
private class AnCancelAction extends AnAction implements DumbAware {
- @Override
- public boolean startInTransaction() {
- return false;
- }
-
@Override
public void update(AnActionEvent e) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();