remove @WrapInTransaction anno because writing is now allowed from actions so not many clients will need it

This commit is contained in:
peter
2016-03-22 15:11:30 +01:00
parent e521f8626f
commit 21b30faafc
16 changed files with 17 additions and 108 deletions
@@ -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();
@@ -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);
@@ -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;
}
}
@@ -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;
@@ -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];
}
@@ -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.<p/>
* 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.<p/>
*
* 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.<p/>
*
* 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.<p/>
*
@@ -68,16 +69,10 @@ import org.jetbrains.annotations.NotNull;
* project: they'd be blocked by the running transaction.
*
* Q: I've got <b>"Write access is allowed from model transactions only"</b> exception, what do I do?<br/>
* 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)}.
* <p/>
*
* 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.<p/>
*
* Q: I've got <b>"Nested transactions are not allowed"</b> exception, what do I do?<br/>
* 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
@@ -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 {
/**
@@ -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;
}
@@ -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);
@@ -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() {
@@ -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) {
@@ -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();
}
}
@@ -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
@@ -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;
@@ -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) {
@@ -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;