From dbcd92f5ccc4585c7d4245aa53ba2bf9d2c644c6 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 22 Jun 2017 13:31:56 +0300 Subject: [PATCH] IDEA-174221 Confusing representation of array with many nulls in debugger --- .../intellij/debugger/engine/JavaValue.java | 1 - .../settings/NodeRendererSettings.java | 6 +-- .../ui/tree/render/ArrayRenderer.java | 38 ++++++++----------- .../ui/tree/nodes/XValueContainerNode.java | 17 ++++----- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index 1caa0f7faa56..c21611927e57 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -366,7 +366,6 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV @Override public void initChildrenArrayRenderer(ArrayRenderer renderer) { renderer.START_INDEX = myCurrentChildrenStart; - renderer.END_INDEX = myCurrentChildrenStart + XCompositeNode.MAX_CHILDREN_TO_SHOW - 1; myCurrentChildrenStart += XCompositeNode.MAX_CHILDREN_TO_SHOW; } diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java index 536a7d8a9728..faf1cf8bdec1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java @@ -134,7 +134,6 @@ public class NodeRendererSettings implements PersistentStateComponent { } try { - element.addContent(writeRenderer(myArrayRenderer)); element.addContent(writeRenderer(myToStringRenderer)); element.addContent(writeRenderer(myClassRenderer)); element.addContent(writeRenderer(myPrimitiveRenderer)); @@ -169,10 +168,7 @@ public class NodeRendererSettings implements PersistentStateComponent { continue; } try { - if (ArrayRenderer.UNIQUE_ID.equals(id)) { - myArrayRenderer.readExternal(elem); - } - else if (ToStringRenderer.UNIQUE_ID.equals(id)) { + if (ToStringRenderer.UNIQUE_ID.equals(id)) { myToStringRenderer.readExternal(elem); } else if (ClassRenderer.UNIQUE_ID.equals(id)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java index 7f01e744dec8..6613dd590bb9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java @@ -39,7 +39,6 @@ import com.intellij.debugger.ui.tree.NodeDescriptorFactory; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.icons.AllIcons; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; @@ -52,6 +51,7 @@ import com.intellij.psi.PsiExpression; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.IncorrectOperationException; import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.frame.XCompositeNode; import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.frame.XValueChildrenList; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; @@ -74,8 +74,8 @@ public class ArrayRenderer extends NodeRendererImpl{ public static final @NonNls String UNIQUE_ID = "ArrayRenderer"; public int START_INDEX = 0; - public int END_INDEX = 100; - public int ENTRIES_LIMIT = 101; + public int END_INDEX = Integer.MAX_VALUE; + public int ENTRIES_LIMIT = XCompositeNode.MAX_CHILDREN_TO_SHOW; private boolean myForced = false; @@ -119,19 +119,16 @@ public class ArrayRenderer extends NodeRendererImpl{ ArrayReference array = (ArrayReference)value; int arrayLength = array.length(); if (arrayLength > 0) { - if (ENTRIES_LIMIT > END_INDEX - START_INDEX + 1) { - ENTRIES_LIMIT = END_INDEX - START_INDEX; - } - if (ENTRIES_LIMIT <= 0) { ENTRIES_LIMIT = 1; } int added = 0; boolean hiddenNulls = false; - if (arrayLength - 1 >= START_INDEX) { - int end = arrayLength - 1 < END_INDEX ? arrayLength - 1 : END_INDEX; - for (int idx = START_INDEX; idx <= end; idx++) { + int end = Math.min(arrayLength - 1, END_INDEX); + int idx = START_INDEX; + if (arrayLength > START_INDEX) { + for (; idx <= end; idx++) { if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && elementIsNull(array, idx)) { hiddenNulls = true; continue; @@ -142,7 +139,7 @@ public class ArrayRenderer extends NodeRendererImpl{ builder.addChildren(Collections.singletonList(arrayItemNode), false); added++; - if (added > ENTRIES_LIMIT) { + if (added >= ENTRIES_LIMIT) { break; } } @@ -163,8 +160,8 @@ public class ArrayRenderer extends NodeRendererImpl{ if (hiddenNulls) { builder.setMessage(DebuggerBundle.message("message.node.elements.null.hidden"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES, null); } - if (!myForced && END_INDEX < arrayLength - 1) { - builder.tooManyChildren(arrayLength - 1 - END_INDEX); + if (!myForced && idx < end) { + builder.tooManyChildren(end - idx); } } } @@ -231,9 +228,10 @@ public class ArrayRenderer extends NodeRendererImpl{ builder.initChildrenArrayRenderer(this); - if (ENTRIES_LIMIT > END_INDEX - START_INDEX + 1) { - ENTRIES_LIMIT = END_INDEX - START_INDEX; - } + builder.setMessage(DebuggerBundle.message("message.node.filtered") + " " + myExpression.getExpression(), + AllIcons.General.Filter, + SimpleTextAttributes.REGULAR_ATTRIBUTES, + FILTER_HYPERLINK); if (ENTRIES_LIMIT <= 0) { ENTRIES_LIMIT = 1; @@ -290,13 +288,7 @@ public class ArrayRenderer extends NodeRendererImpl{ } } - builder.setMessage(DebuggerBundle.message("message.node.filtered") + " " + myExpression.getExpression(), - AllIcons.General.Filter, - SimpleTextAttributes.REGULAR_ATTRIBUTES, - FILTER_HYPERLINK); - - // setMessage removes the loading message - //builder.addChildren(Collections.emptyList(), true); + builder.addChildren(Collections.emptyList(), true); //if (added != 0 && END_INDEX < arrayLength - 1) { // builder.setRemaining(arrayLength - 1 - END_INDEX); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index 9e12d8b171f2..a60b13076a84 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -195,18 +195,15 @@ public abstract class XValueContainerNode messages, boolean temporary) { myCachedAllChildren = null; - List allMessageChildren = ContainerUtil.concat(myMessageChildren != null ? myMessageChildren : Collections.emptyList(), - myTemporaryMessageChildren != null ? myTemporaryMessageChildren : Collections.emptyList()); - final int[] indices = getNodesIndices(allMessageChildren); - final TreeNode[] nodes = allMessageChildren.toArray(new TreeNode[allMessageChildren.size()]); - fireNodesRemoved(indices, nodes); - if (!temporary) { - myMessageChildren = messages; - myTemporaryMessageChildren = null; + List toDelete = temporary ? myTemporaryMessageChildren : myMessageChildren; + if (toDelete != null) { + fireNodesRemoved(getNodesIndices(toDelete), toDelete.toArray(new TreeNode[toDelete.size()])); + } + if (temporary) { + myTemporaryMessageChildren = messages; } else { - myTemporaryMessageChildren = messages; - myMessageChildren = null; + myMessageChildren = messages; } myCachedAllChildren = null; fireNodesInserted(messages);