diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java index 1b6ef6c9ad24..3b5447567c6d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java +++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java @@ -16,17 +16,17 @@ package com.intellij.compiler.actions; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.TransactionKind; -import com.intellij.openapi.application.WrapInTransaction; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.compiler.CompilerManager; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -@WrapInTransaction(TransactionKind.Common.ANY_CHANGE) public abstract class CompileActionBase extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java index b4fb55e107de..c5019eab07ab 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SafeDeleteFix.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil; import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; @@ -31,7 +30,6 @@ import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -@WrapInTransaction public class SafeDeleteFix extends LocalQuickFixAndIntentionActionOnPsiElement { public SafeDeleteFix(@NotNull PsiElement element) { super(element); diff --git a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java index ca7c9999a3ad..ba47b7f5e045 100644 --- a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java +++ b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java @@ -16,8 +16,6 @@ package com.intellij.codeInsight.intention; import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.TransactionKind; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.application.WriteActionAware; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -26,7 +24,6 @@ import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Interface for intention actions. Intention actions are invoked by pressing @@ -99,16 +96,4 @@ public interface IntentionAction extends WriteActionAware { * @return true if the intention requires a write action, false otherwise. */ boolean startInWriteAction(); - - /** - * @return the transaction kind that this intention should be executed inside, or null if no transaction is required. - * By default, the kind is taken from {@link WrapInTransaction} annotation on the intention class. If it's not present - * but the intention is to be invoked inside a write action (startInWriteAction), {@link TransactionKind#ANY_CHANGE} is used. - * @see com.intellij.openapi.application.TransactionGuard - */ - @Nullable - default TransactionKind getTransactionKind() { - WrapInTransaction annotation = getClass().getAnnotation(WrapInTransaction.class); - return annotation != null ? annotation.value() : startInWriteAction() ? TransactionKind.ANY_CHANGE : null; - } } diff --git a/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixOnPsiElementAsIntentionAdapter.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixOnPsiElementAsIntentionAdapter.java index 9681bd074353..581ecfd358bd 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixOnPsiElementAsIntentionAdapter.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFixOnPsiElementAsIntentionAdapter.java @@ -16,14 +16,12 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -@WrapInTransaction public class LocalQuickFixOnPsiElementAsIntentionAdapter implements IntentionAction { private final LocalQuickFixOnPsiElement myFix; diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java index 363523ee47ad..774ee7101b93 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java @@ -21,8 +21,6 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.QuickFix; -import com.intellij.openapi.application.TransactionKind; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -31,7 +29,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author max @@ -98,13 +95,6 @@ public class QuickFixWrapper implements IntentionAction { return getFix().startInWriteAction(); } - @Nullable - @Override - public TransactionKind getTransactionKind() { - WrapInTransaction annotation = getFix().getClass().getAnnotation(WrapInTransaction.class); - return annotation != null ? annotation.value() : startInWriteAction() ? TransactionKind.ANY_CHANGE : null; - } - public LocalQuickFix getFix() { return (LocalQuickFix)myDescriptor.getFixes()[myFixNumber]; } 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 1fa576418e82..2b80470b375c 100644 --- a/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java +++ b/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java @@ -47,10 +47,10 @@ import org.jetbrains.annotations.NotNull; * * Q: How large/long should transactions be? * A: As short as possible, but not shorter. Take them for minimal period of time that you need the model you're working with - * to be consistent. If your action doesn't require any user interaction, the whole action can be wrapped inside - * a transaction (see {@link WrapInTransaction}). If the action only displays a dialog (e.g. Settings) and does nothing else, - * it probably shouldn't take a transaction for all the dialog showing time. - * Actions inside the dialog should care of transactions themselves.

+ * to be consistent. If your action doesn't display any modal progresses or dialogs, transaction can be omitted. + * If the action only displays a dialog (e.g. Settings) and does nothing else, and that dialog is ready to possible PSI/VFS events, + * there should also be no transaction for all the dialog showing time. Actions inside the dialog should care of transactions themselves. + * If the dialog isn't prepared to any model changes from outside, a transaction around showing the dialog is advised.

* * The most complicated case is when the action both displays modal dialogs and performs modifications. The only case when those dialogs * should be shown under a transaction is when the mere reason of their showing lies somewhere in PSI/VFS/project model, and they are not @@ -60,7 +60,8 @@ import org.jetbrains.annotations.NotNull; * as the following meaningful modifications performed by the action. Most refactoring dialogs are similar and refactoring actions should * take transactions for the whole refactoring process, with all the dialogs inside.

* - * Having said all that, it's still advisable that the transactions be as short as possible and preferably exclude any modal dialogs + * But note that some background processes may need occasional transactions, and will therefore be paused until the dialog is closed. + * Therefore, it's still advisable that the transactions be as short as possible and preferably exclude any modal dialogs * for which transaction-ness is not critical. So a better overall strategy would be to either make the dialogs non-modal, * or at least make them and the code that shows them prepared for possible model changes while the dialog is shown.

* @@ -68,16 +69,10 @@ import org.jetbrains.annotations.NotNull; * project: they'd be blocked by the running transaction. * * Q: I've got "Write access is allowed from model transactions only" exception, what do I do?
- * A: Add a transaction somewhere into the call stack, to the outermost callee where having read/write model consistency is needed. - * If it's a user action, transaction should be synchronous (see {@link #startSynchronousTransaction(TransactionKind)}. For AnAction - * inheritors, {@link WrapInTransaction} annotation might be handy. Note that not all actions need to be wrapped into transactions, only - * those that require the model to be consistent. For example, actions that display settings dialogs or VCS actions are most likely exempt. + * A: You're likely inside an "invokeLater"-like call. Please consider replacing it with {@link #submitTransaction(Runnable)} or + * {@link #submitMergeableTransaction(TransactionKind, Runnable)}. *

* - * If the exception occurs not inside a user action, it's probably from some kind of "invokeLater". - * Then, replace "invokeLater" with {@link #submitTransaction(Runnable)} or - * {@link #submitMergeableTransaction(TransactionKind, Runnable)} call.

- * * Q: I've got "Nested transactions are not allowed" exception, what do I do?
* A: First, identify the place in the stack where the outer transaction is started (the exception attachment should contain it). * Then, see if there is any Swing event pumping diff --git a/platform/core-api/src/com/intellij/openapi/application/TransactionKind.java b/platform/core-api/src/com/intellij/openapi/application/TransactionKind.java index b4db511c2b63..18660fe5622d 100644 --- a/platform/core-api/src/com/intellij/openapi/application/TransactionKind.java +++ b/platform/core-api/src/com/intellij/openapi/application/TransactionKind.java @@ -19,7 +19,7 @@ import com.intellij.openapi.editor.Document; /** * A kind of transaction used in {@link TransactionGuard#submitMergeableTransaction(TransactionKind, Runnable)}, - * {@link TransactionGuard#acceptNestedTransactions(TransactionKind...)} and {@link AcceptNestedTransactions}. + * {@link TransactionGuard#acceptNestedTransactions(TransactionKind...)}. */ public interface TransactionKind { /** diff --git a/platform/core-api/src/com/intellij/openapi/application/WrapInTransaction.java b/platform/core-api/src/com/intellij/openapi/application/WrapInTransaction.java deleted file mode 100644 index 1a5cbc935a7a..000000000000 --- a/platform/core-api/src/com/intellij/openapi/application/WrapInTransaction.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.intellij.openapi.application; - -import java.lang.annotation.*; - -/** - * Add this annotation to actions (AnAction, IntentionAction or QuickFix inheritors) to make them run inside a synchronous transaction. - * - * @see TransactionGuard - * @since 146.* - * @author peter - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -public @interface WrapInTransaction { - - /** - * @return the kind of transaction to wrap the action into. By default, it's {@link TransactionKind#ANY_CHANGE}. - */ - TransactionKind.Common value() default TransactionKind.Common.ANY_CHANGE; -} diff --git a/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java index 6b73c8a7ade1..dfeb5a00e13c 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java +++ b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java @@ -18,13 +18,11 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.LowPriorityAction; -import com.intellij.openapi.application.TransactionKind; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author Danila Ponomarenko @@ -63,12 +61,6 @@ public abstract class PriorityIntentionActionWrapper implements IntentionAction return action.startInWriteAction(); } - @Nullable - @Override - public TransactionKind getTransactionKind() { - return action.getTransactionKind(); - } - private static class HighPriorityIntentionActionWrapper extends PriorityIntentionActionWrapper implements HighPriorityAction { protected HighPriorityIntentionActionWrapper(@NotNull IntentionAction action) { super(action); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/BaseCodeCompletionAction.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/BaseCodeCompletionAction.java index 2b08a932280f..47a4ec621df9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/BaseCodeCompletionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/BaseCodeCompletionAction.java @@ -22,8 +22,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.TransactionKind; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; @@ -35,7 +33,6 @@ import java.awt.event.InputEvent; /** * @author peter */ -@WrapInTransaction(TransactionKind.Common.TEXT_EDITING) public abstract class BaseCodeCompletionAction extends DumbAwareAction implements HintManagerImpl.ActionToIgnore { protected BaseCodeCompletionAction() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index 06b5e82fcddc..29bd53f53ef0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -28,12 +28,12 @@ import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.codeInspection.SuppressIntentionActionFromFix; -import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.FeatureUsageTrackerImpl; import com.intellij.injected.editor.EditorWindow; import com.intellij.lang.injection.InjectedLanguageManager; -import com.intellij.openapi.application.*; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -184,9 +184,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { if (pair == null) return false; CommandProcessor.getInstance().executeCommand(project, () -> { - TransactionKind kind = action.getTransactionKind(); - try (AccessToken ignore = kind == null ? null : TransactionGuard.getInstance().startSynchronousTransaction(kind); - AccessToken ignored = action.startInWriteAction() ? WriteAction.start() : null) { + try (AccessToken ignored = action.startInWriteAction() ? WriteAction.start() : null) { action.invoke(project, pair.second, pair.first); } catch (IncorrectOperationException e) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java index 48305e784fdf..d0e1b23cc1db 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.intention.impl.config; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.IntentionActionBean; -import com.intellij.openapi.application.TransactionKind; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -26,7 +25,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public class IntentionActionWrapper implements IntentionAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper"); @@ -106,10 +104,4 @@ public class IntentionActionWrapper implements IntentionAction { public boolean equals(Object obj) { return super.equals(obj) || getDelegate().equals(obj); } - - @Nullable - @Override - public TransactionKind getTransactionKind() { - return getDelegate().getTransactionKind(); - } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java index db468ae8e7f9..1ce55d4c8f3b 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java @@ -16,10 +16,7 @@ package com.intellij.openapi.actionSystem.ex; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.TransactionGuard; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -190,18 +187,12 @@ public class ActionUtil { } public static void performActionDumbAware(AnAction action, AnActionEvent e) { - WrapInTransaction annotation = action.getClass().getAnnotation(WrapInTransaction.class); - AccessToken token = annotation == null ? AccessToken.EMPTY_ACCESS_TOKEN - : TransactionGuard.getInstance().startSynchronousTransaction(annotation.value()); try { action.actionPerformed(e); } catch (IndexNotReadyException e1) { showDumbModeWarning(e); } - finally { - token.finish(); - } } @NotNull diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java index fd0e84fe8630..10b4f5d62f11 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java @@ -20,7 +20,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.TransactionKind; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.CaretAction; import com.intellij.openapi.editor.Editor; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SaveAllAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SaveAllAction.java index 2a7b35ebc404..1425b458c288 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/SaveAllAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/SaveAllAction.java @@ -18,11 +18,9 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.NotNull; -@WrapInTransaction public class SaveAllAction extends AnAction implements DumbAware { @Override public void actionPerformed(@NotNull AnActionEvent e) { diff --git a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java index c18de5266b3a..9a6886ccfd28 100644 --- a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java +++ b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java @@ -18,7 +18,6 @@ package com.intellij.internal; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.application.WrapInTransaction; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.DumbModeTask; @@ -30,7 +29,6 @@ import org.jetbrains.annotations.NotNull; /** * @author peter */ -@WrapInTransaction public class ToggleDumbModeAction extends DumbAwareAction { private volatile boolean myDumb = false;