action-update-thread: Make XDebuggerTreeActionBase.update() BGT-friendly

Change XDebuggerTreeActionBase.getSelectedNodes() implementation to use
a (precached) SELECTED_NODES from the data context.

Update most of its inheritors to use ActionUpdateThread.BGT.

GitOrigin-RevId: 7ca1072a0c67a7cf07111a082ae16f28ed3ba687
This commit is contained in:
Eldar Abusalimov
2022-07-01 03:32:45 +00:00
committed by intellij-monorepo-bot
parent e47387dc91
commit 0e723f7cd6
15 changed files with 109 additions and 85 deletions
@@ -5,6 +5,7 @@ import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.settings.JavaDebuggerSettings;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
@@ -88,6 +89,11 @@ public class CustomizeContextViewAction extends XDebuggerTreeActionBase {
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull AnActionEvent e) {
e.getPresentation().setText(ActionsBundle.actionText("Debugger.CustomizeContextView"));
@@ -6,6 +6,7 @@ import com.intellij.debugger.ui.impl.watch.UserExpressionDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.render.CustomFieldInplaceEditor;
import com.intellij.debugger.ui.tree.render.EnumerationChildrenRenderer;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -24,6 +25,11 @@ public class EditCustomFieldAction extends XDebuggerTreeActionBase {
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull final AnActionEvent e) {
boolean enabled = false;
@@ -5,6 +5,7 @@ import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.render.CustomFieldInplaceEditor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -22,6 +23,11 @@ public class NewCustomFieldAction extends XDebuggerTreeActionBase {
CustomFieldInplaceEditor.editNew(node);
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull final AnActionEvent e) {
boolean enabled = false;
@@ -187,10 +187,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware {
@NotNull
public static List<JavaValue> getSelectedValues(@NotNull AnActionEvent event) {
List<XValueNodeImpl> selectedNodes = event.getData(XDebuggerTree.SELECTED_NODES);
if (selectedNodes == null) {
return Collections.emptyList();
}
List<XValueNodeImpl> selectedNodes = XDebuggerTree.getSelectedNodes(event.getDataContext());
return StreamEx.of(selectedNodes)
.map(XValueNodeImpl::getValueContainer)
.select(JavaValue.class)
@@ -13,6 +13,7 @@ import com.intellij.debugger.memory.agent.MemoryAgentActionResult;
import com.intellij.debugger.memory.agent.ui.RetainedSizeDialog;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
@@ -98,6 +99,11 @@ public class CalculateRetainedSizeAction extends DebuggerTreeAction {
});
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
if (!super.isEnabled(node, e)) return false;
@@ -4,6 +4,7 @@ package com.intellij.debugger.memory.action;
import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.memory.ui.InstancesWindow;
import com.intellij.debugger.memory.ui.JavaReferenceInfo;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -19,6 +20,11 @@ import java.util.Collections;
import java.util.List;
public class ShowInstancesByClassAction extends DebuggerTreeAction {
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
final ObjectReference ref = getObjectReference(node);
@@ -7,6 +7,7 @@ import com.intellij.debugger.memory.action.DebuggerTreeAction;
import com.intellij.debugger.memory.component.MemoryViewDebugProcessData;
import com.intellij.debugger.memory.ui.StackFramePopup;
import com.intellij.debugger.memory.utils.StackFrameItem;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugSession;
@@ -19,6 +20,11 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class JumpToAllocationSourceAction extends DebuggerTreeAction {
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull AnActionEvent e) {
e.getPresentation().setVisible(getStack(e) != null);
@@ -66,6 +66,11 @@ public class XDebuggerTreeInlayPopup<D> extends XDebuggerTreePopup<D> {
presentation.setText(XDebuggerBundle.message("debugger.inline.watches.popup.action.add.as.inline.watch"));
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
node.calculateEvaluationExpression()
@@ -420,11 +420,14 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
return e.getData(XDEBUGGER_TREE_KEY);
}
@Nullable
public static XDebuggerTree getTree(DataContext context) {
public static @Nullable XDebuggerTree getTree(@NotNull DataContext context) {
return XDEBUGGER_TREE_KEY.getData(context);
}
public static @NotNull List<XValueNodeImpl> getSelectedNodes(@NotNull DataContext context) {
return ContainerUtil.notNullize(SELECTED_NODES.getData(context));
}
public void invokeLater(Runnable runnable) {
EdtExecutorService.getInstance().execute(runnable);
}
@@ -1,6 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.xdebugger.XDebugSession;
@@ -15,6 +16,11 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
@@ -18,15 +18,13 @@ package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreePath;
import java.util.Collections;
import java.util.List;
public abstract class XDebuggerTreeActionBase extends AnAction {
@@ -53,28 +51,12 @@ public abstract class XDebuggerTreeActionBase extends AnAction {
return node.getName() != null;
}
@NotNull
public static List<XValueNodeImpl> getSelectedNodes(DataContext dataContext) {
XDebuggerTree tree = XDebuggerTree.getTree(dataContext);
if (tree == null) return Collections.emptyList();
TreePath[] paths = tree.getSelectionPaths();
if (paths == null || paths.length == 0) {
return Collections.emptyList();
}
return StreamEx.of(paths).map(TreePath::getLastPathComponent).select(XValueNodeImpl.class).toList();
public static @NotNull List<XValueNodeImpl> getSelectedNodes(@NotNull DataContext dataContext) {
return XDebuggerTree.getSelectedNodes(dataContext);
}
@Nullable
public static XValueNodeImpl getSelectedNode(final DataContext dataContext) {
XDebuggerTree tree = XDebuggerTree.getTree(dataContext);
if (tree == null) return null;
TreePath path = tree.getSelectionPath();
if (path == null) return null;
Object node = path.getLastPathComponent();
return node instanceof XValueNodeImpl ? (XValueNodeImpl)node : null;
public static @Nullable XValueNodeImpl getSelectedNode(@NotNull DataContext dataContext) {
return ContainerUtil.getFirstItem(getSelectedNodes(dataContext));
}
@Nullable
@@ -1,6 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -10,6 +11,11 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
public class XInspectAction extends XDebuggerTreeActionBase {
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
protected void perform(XValueNodeImpl node, @NotNull final String nodeName, AnActionEvent e) {
XDebuggerTree tree = node.getTree();
@@ -1,6 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.xdebugger.impl.ui.tree.SetValueInplaceEditor;
@@ -9,6 +10,11 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
public class XSetValueAction extends XDebuggerTreeActionBase {
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull final AnActionEvent e) {
super.update(e);
@@ -17,17 +17,14 @@ package com.jetbrains.python.debugger.containerview;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.debugger.PyDebugValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreePath;
import java.util.List;
/**
* @author amarch
@@ -48,51 +45,42 @@ public class PyViewNumericContainerAction extends XDebuggerTreeActionBase {
PyDataView.getInstance(project).show(debugValue);
}
private static TreePath @Nullable [] getSelectedPaths(DataContext dataContext) {
XDebuggerTree tree = XDebuggerTree.getTree(dataContext);
return tree == null ? null : tree.getSelectionPaths();
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull AnActionEvent e) {
e.getPresentation().setVisible(false);
TreePath[] paths = getSelectedPaths(e.getDataContext());
if (paths != null) {
if (paths.length > 1) {
e.getPresentation().setVisible(false);
return;
}
List<XValueNodeImpl> selectedNodes = getSelectedNodes(e.getDataContext());
if (selectedNodes.size() != 1) {
e.getPresentation().setVisible(false);
return;
}
XValueNodeImpl node = getSelectedNode(e.getDataContext());
if (node != null && node.getValueContainer() instanceof PyDebugValue && node.isComputed()) {
PyDebugValue debugValue = (PyDebugValue)node.getValueContainer();
XValueNodeImpl node = selectedNodes.get(0);
if (!(node.getValueContainer() instanceof PyDebugValue) || !node.isComputed()) {
e.getPresentation().setVisible(false);
return;
}
String nodeType = debugValue.getType();
if ("ndarray".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.array"));
e.getPresentation().setVisible(true);
}
else if ("DataFrame".equals(nodeType) || "GeoDataFrame".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.dataframe"));
e.getPresentation().setVisible(true);
}
else if ("Series".equals(nodeType) || "GeoSeries".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.series"));
e.getPresentation().setVisible(true);
}
else {
e.getPresentation().setVisible(false);
}
}
else
{
e.getPresentation().setVisible(false);
}
PyDebugValue debugValue = (PyDebugValue)node.getValueContainer();
String nodeType = debugValue.getType();
if ("ndarray".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.array"));
e.getPresentation().setVisible(true);
}
else if ("DataFrame".equals(nodeType) || "GeoDataFrame".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.dataframe"));
e.getPresentation().setVisible(true);
}
else if ("Series".equals(nodeType) || "GeoSeries".equals(nodeType)) {
e.getPresentation().setText(PyBundle.message("debugger.numeric.view.as.series"));
e.getPresentation().setVisible(true);
}
else {
e.getPresentation().setVisible(false);
}
}
}
@@ -11,7 +11,6 @@ import com.intellij.ui.SimpleTextAttributes
import com.intellij.util.ui.JBUI
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink
import com.intellij.xdebugger.frame.XValueChildrenList
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl
import com.jetbrains.python.PyBundle
@@ -71,6 +70,16 @@ fun loadTypeRendererChildren(frameAccessor: PyFrameAccessor,
}
class ConfigureTypeRenderersAction : XDebuggerTreeActionBase() {
init {
templatePresentation.text = PyBundle.message("action.PyDebugger.CustomizeDataView.text")
}
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
override fun update(e: AnActionEvent) {
e.presentation.isVisible = getSelectedNodes(e.dataContext).size <= 1
}
override fun perform(node: XValueNodeImpl, nodeName: String, e: AnActionEvent) {
val project = e.project ?: ProjectManager.getInstance().defaultProject
val debugValue = node.valueContainer as? PyDebugValue ?: return
@@ -88,20 +97,6 @@ class ConfigureTypeRenderersAction : XDebuggerTreeActionBase() {
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
override fun update(e: AnActionEvent) {
e.presentation.isVisible = false
val tree = XDebuggerTree.getTree(e.dataContext)
tree?.selectionPaths?.let {
if (it.size > 1) return
e.presentation.text = PyBundle.message("action.PyDebugger.CustomizeDataView.text")
e.presentation.isVisible = true
}
}
companion object {
fun showSettingsWithNewRenderer(project: Project, debugValue: PyDebugValue) {
ShowSettingsUtil.getInstance().showSettingsDialog(project, PyUserTypeRenderersConfigurable::class.java) {