IDEA-234690 Batch receive object's children - array elements

GitOrigin-RevId: 38cf5c7f8e2a7ce276c6f95c72b4f39245345b30
This commit is contained in:
Egor Ushakov
2020-03-10 09:01:29 +00:00
committed by intellij-monorepo-bot
parent 7859e32e76
commit f3d13a09b2
2 changed files with 103 additions and 73 deletions
@@ -1,9 +1,9 @@
// Copyright 2000-2018 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.
// Copyright 2000-2020 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.debugger.ui.impl.watch;
import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.JavaValueModifier;
import com.intellij.debugger.engine.evaluation.EvaluateException;
@@ -14,6 +14,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.ui.tree.ArrayElementDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiExpression;
@@ -26,6 +27,7 @@ import org.jetbrains.annotations.NotNull;
public class ArrayElementDescriptorImpl extends ValueDescriptorImpl implements ArrayElementDescriptor{
private final int myIndex;
private final ArrayReference myArray;
private Ref<Value> myPresetValue;
public ArrayElementDescriptorImpl(Project project, ArrayReference array, int index) {
super(project);
@@ -49,8 +51,15 @@ public class ArrayElementDescriptorImpl extends ValueDescriptorImpl implements A
return String.valueOf(myIndex);
}
public void setValue(Value value) {
myPresetValue = Ref.create(value);
}
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
if (myPresetValue != null) {
return myPresetValue.get();
}
return getArrayElement(myArray, myIndex);
}
@@ -1,9 +1,9 @@
// Copyright 2000-2018 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.
// Copyright 2000-2020 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.debugger.ui.tree.render;
import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.JavaDebuggerBundle;
import com.intellij.debugger.actions.ArrayAction;
import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
@@ -18,7 +18,6 @@ import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.settings.ViewsGeneralSettings;
import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.NodeDescriptorFactory;
@@ -42,10 +41,7 @@ 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.nodes.XValueNodeImpl;
import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
import com.sun.jdi.Type;
import com.sun.jdi.Value;
import com.sun.jdi.*;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -53,6 +49,7 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.List;
public class ArrayRenderer extends NodeRendererImpl{
private static final Logger LOG = Logger.getInstance(ArrayRenderer.class);
@@ -115,56 +112,77 @@ public class ArrayRenderer extends NodeRendererImpl{
ENTRIES_LIMIT = 1;
}
int added = 0;
boolean hiddenNulls = false;
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;
}
try {
int added = 0;
boolean hiddenNulls = false;
int end = Math.min(arrayLength - 1, END_INDEX);
int idx = START_INDEX;
if (arrayLength > START_INDEX) {
ArrayValuesCache arrayValuesCache = new ArrayValuesCache(array);
for (; idx <= end; idx++) {
Value val = arrayValuesCache.getValue(idx);
if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && val == null) {
hiddenNulls = true;
continue;
}
DebuggerTreeNode arrayItemNode =
nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext);
ArrayElementDescriptorImpl descriptor =
(ArrayElementDescriptorImpl)descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx);
descriptor.setValue(val);
DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptor, evaluationContext);
builder.addChildren(Collections.singletonList(arrayItemNode), false);
added++;
if (added >= ENTRIES_LIMIT) {
break;
builder.addChildren(Collections.singletonList(arrayItemNode), false);
added++;
if (added >= ENTRIES_LIMIT) {
break;
}
}
}
}
builder.addChildren(Collections.emptyList(), true);
builder.addChildren(Collections.emptyList(), true);
if (added == 0) {
if (START_INDEX == 0 && arrayLength - 1 <= END_INDEX) {
builder.setMessage(JavaDebuggerBundle.message("message.node.all.elements.null"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
if (added == 0) {
if (START_INDEX == 0 && arrayLength - 1 <= END_INDEX) {
builder.setMessage(JavaDebuggerBundle.message("message.node.all.elements.null"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES,
null);
}
else {
builder.setMessage(JavaDebuggerBundle.message("message.node.all.array.elements.null", START_INDEX, END_INDEX), null,
SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
}
}
else {
builder.setMessage(JavaDebuggerBundle.message("message.node.all.array.elements.null", START_INDEX, END_INDEX), null,
SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
if (hiddenNulls) {
builder
.setMessage(JavaDebuggerBundle.message("message.node.elements.null.hidden"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES,
null);
}
if (!myForced && idx < end) {
builder.tooManyChildren(end - idx);
}
}
}
else {
if (hiddenNulls) {
builder.setMessage(JavaDebuggerBundle.message("message.node.elements.null.hidden"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
}
if (!myForced && idx < end) {
builder.tooManyChildren(end - idx);
}
catch (ObjectCollectedException e) {
builder.setErrorMessage(JavaDebuggerBundle.message("evaluation.error.array.collected"));
}
}
}
private static boolean elementIsNull(ArrayReference arrayReference, int index) {
try {
return ArrayElementDescriptorImpl.getArrayElement(arrayReference, index) == null;
private static class ArrayValuesCache {
private final ArrayReference myArray;
private List<Value> myCachedValues = Collections.emptyList();
private int myCachedStartIndex;
private ArrayValuesCache(ArrayReference array) {
myArray = array;
}
catch (EvaluateException e) {
return false;
Value getValue(int index) {
if (index < myCachedStartIndex || index >= myCachedStartIndex + myCachedValues.size()) {
myCachedStartIndex = index;
myCachedValues = myArray.getValues(index, Math.min(XCompositeNode.MAX_CHILDREN_TO_SHOW, myArray.length() - index));
}
return myCachedValues.get(index - myCachedStartIndex);
}
}
@@ -250,42 +268,45 @@ public class ArrayRenderer extends NodeRendererImpl{
};
cachedEvaluator.setReferenceExpression(TextWithImportsImpl.fromXExpression(myExpression));
int added = 0;
if (arrayLength - 1 >= START_INDEX) {
ErrorsValueGroup errorsGroup = null;
for (int idx = START_INDEX; idx < arrayLength; idx++) {
try {
if (DebuggerUtilsEx.evaluateBoolean(cachedEvaluator.getEvaluator(evaluationContext.getProject()),
(EvaluationContextImpl)evaluationContext.createEvaluationContext(array.getValue(idx)))) {
try {
int added = 0;
if (arrayLength - 1 >= START_INDEX) {
DebuggerTreeNode arrayItemNode =
nodeManager
.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext);
ErrorsValueGroup errorsGroup = null;
ArrayValuesCache arrayValuesCache = new ArrayValuesCache(array);
for (int idx = START_INDEX; idx < arrayLength; idx++) {
ArrayElementDescriptorImpl descriptor =
(ArrayElementDescriptorImpl)descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx);
Value val = arrayValuesCache.getValue(idx);
descriptor.setValue(val);
try {
if (DebuggerUtilsEx.evaluateBoolean(cachedEvaluator.getEvaluator(evaluationContext.getProject()),
(EvaluationContextImpl)evaluationContext.createEvaluationContext(val))) {
builder.addChildren(Collections.singletonList(arrayItemNode), false);
added++;
//if (added > ENTRIES_LIMIT) {
// break;
//}
DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptor, evaluationContext);
builder.addChildren(Collections.singletonList(arrayItemNode), false);
added++;
//if (added > ENTRIES_LIMIT) {
// break;
//}
}
}
}
catch (EvaluateException e) {
if (errorsGroup == null) {
errorsGroup = new ErrorsValueGroup();
builder.addChildren(XValueChildrenList.bottomGroup(errorsGroup), false);
catch (EvaluateException e) {
if (errorsGroup == null) {
errorsGroup = new ErrorsValueGroup();
builder.addChildren(XValueChildrenList.bottomGroup(errorsGroup), false);
}
JavaValue childValue = JavaValue.create(null, descriptor, ((EvaluationContextImpl)evaluationContext), nodeManager, false);
errorsGroup.addErrorValue(e.getMessage(), childValue);
}
JavaValue childValue = JavaValue
.create(null,
(ValueDescriptorImpl)descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx),
((EvaluationContextImpl)evaluationContext),
nodeManager,
false);
errorsGroup.addErrorValue(e.getMessage(), childValue);
}
}
}
builder.addChildren(Collections.emptyList(), true);
builder.addChildren(Collections.emptyList(), true);
}
catch (ObjectCollectedException e) {
builder.setErrorMessage(JavaDebuggerBundle.message("evaluation.error.array.collected"));
}
//if (added != 0 && END_INDEX < arrayLength - 1) {
// builder.setRemaining(arrayLength - 1 - END_INDEX);