From 0e2ab30850a813bbddf57e102175390e7bfa6b10 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 18 May 2011 13:41:06 +0200 Subject: [PATCH] MapEntry renderer - now render separately key and value with appropriate renderers instead of evaluating their toStrings() --- .../settings/NodeRendererSettings.java | 134 +++++++++++++++++- .../MethodReturnValueDescriptorImpl.java | 5 - .../ui/impl/watch/ValueDescriptorImpl.java | 76 +++++----- .../debugger/ui/tree/ValueDescriptor.java | 2 +- .../ui/tree/render/ClassRenderer.java | 2 +- .../render/EnumerationChildrenRenderer.java | 3 +- .../debugger/ui/tree/render/HexRenderer.java | 6 +- .../ui/tree/render/LabelRenderer.java | 11 +- .../ui/tree/render/RendererProvider.java | 32 ----- .../ui/tree/render/ToStringRenderer.java | 4 +- .../ui/tree/render/ValueLabelRenderer.java | 3 +- .../debugger/engine/DebuggerUtils.java | 15 ++ 12 files changed, 193 insertions(+), 100 deletions(-) delete mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/tree/render/RendererProvider.java 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 0e5276b6cc73..0b57402e3061 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java @@ -15,23 +15,28 @@ */ package com.intellij.debugger.settings; +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.debugger.ui.tree.render.*; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMExternalizerUtil; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.*; import com.intellij.util.EventDispatcher; import com.intellij.util.containers.InternalIterator; +import com.sun.jdi.Value; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -73,7 +78,7 @@ public class NodeRendererSettings implements PersistentStateComponent { ), createCompoundReferenceRenderer( "Map.Entry", "java.util.Map$Entry", - createLabelRenderer(null, "\" \" + getKey() + \" -> \" + getValue()", null), + new MapEntryLabelRenderer()/*createLabelRenderer(null, "\" \" + getKey() + \" -> \" + getValue()", null)*/, createEnumerationChildrenRenderer(new String[][]{{"key", "getKey()"}, {"value", "getValue()"}}) ), createCompoundReferenceRenderer( @@ -326,7 +331,7 @@ public class NodeRendererSettings implements PersistentStateComponent { } private CompoundReferenceRenderer createCompoundReferenceRenderer( - @NonNls final String rendererName, @NonNls final String className, final LabelRenderer labelRenderer, final ChildrenRenderer childrenRenderer + @NonNls final String rendererName, @NonNls final String className, final ValueLabelRenderer labelRenderer, final ChildrenRenderer childrenRenderer ) { CompoundReferenceRenderer renderer = new CompoundReferenceRenderer(this, rendererName, labelRenderer, childrenRenderer); renderer.setClassName(className); @@ -374,4 +379,121 @@ public class NodeRendererSettings implements PersistentStateComponent { return labelRenderer; } + private static class MapEntryLabelRenderer extends ReferenceRenderer implements ValueLabelRenderer{ + private static final Computable NULL_LABEL_COMPUTABLE = new Computable() { + @Override + public String compute() { + return "null"; + } + }; + + private final MyCachedEvaluator myKeyExpression = new MyCachedEvaluator(); + private final MyCachedEvaluator myValueExpression = new MyCachedEvaluator(); + + private MapEntryLabelRenderer() { + super("java.util.Map$Entry"); + myKeyExpression.setReferenceExpression(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "this.getKey()")); + myValueExpression.setReferenceExpression(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "this.getValue()")); + } + + public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) throws EvaluateException { + final DescriptorUpdater descriptorUpdater = new DescriptorUpdater(descriptor, listener); + + final Value originalValue = descriptor.getValue(); + final Pair, ValueDescriptorImpl> keyPair = createValueComputable(evaluationContext, originalValue, myKeyExpression, descriptorUpdater); + final Pair, ValueDescriptorImpl> valuePair = createValueComputable(evaluationContext, originalValue, myValueExpression, descriptorUpdater); + + descriptorUpdater.setKeyDescriptor(keyPair.second); + descriptorUpdater.setValueDescriptor(valuePair.second); + + return DescriptorUpdater.constructLabelText(keyPair.first.compute(), valuePair.first.compute()); + } + + private Pair, ValueDescriptorImpl> createValueComputable(final EvaluationContext evaluationContext, + Value originalValue, + final MyCachedEvaluator evaluator, + final DescriptorLabelListener listener) throws EvaluateException { + final Value eval = doEval(evaluationContext, originalValue, evaluator); + if (eval != null) { + final WatchItemDescriptor evalDescriptor = new WatchItemDescriptor(evaluationContext.getProject(), evaluator.getReferenceExpression(), eval); + evalDescriptor.setShowIdLabel(false); + return new Pair, ValueDescriptorImpl>(new Computable() { + public String compute() { + evalDescriptor.updateRepresentation((EvaluationContextImpl)evaluationContext, listener); + return evalDescriptor.getValueLabel(); + } + }, evalDescriptor); + } + return new Pair, ValueDescriptorImpl>(NULL_LABEL_COMPUTABLE, null); + } + + public String getUniqueId() { + return "MapEntry renderer"; + } + + private Value doEval(EvaluationContext evaluationContext, Value originalValue, MyCachedEvaluator cachedEvaluator) + throws EvaluateException { + final DebugProcess debugProcess = evaluationContext.getDebugProcess(); + if (originalValue == null) { + return null; + } + try { + final ExpressionEvaluator evaluator = cachedEvaluator.getEvaluator(debugProcess.getProject()); + if(!debugProcess.isAttached()) { + throw EvaluateExceptionUtil.PROCESS_EXITED; + } + final EvaluationContext thisEvaluationContext = evaluationContext.createEvaluationContext(originalValue); + return evaluator.evaluate(thisEvaluationContext); + } + catch (final EvaluateException ex) { + throw new EvaluateException(DebuggerBundle.message("error.unable.to.evaluate.expression") + " " + ex.getMessage(), ex); + } + } + + private class MyCachedEvaluator extends CachedEvaluator { + protected String getClassName() { + return MapEntryLabelRenderer.this.getClassName(); + } + + public ExpressionEvaluator getEvaluator(Project project) throws EvaluateException { + return super.getEvaluator(project); + } + } + } + + private static class DescriptorUpdater implements DescriptorLabelListener { + private final ValueDescriptor myTargetDescriptor; + @Nullable + private ValueDescriptorImpl myKeyDescriptor; + @Nullable + private ValueDescriptorImpl myValueDescriptor; + private final DescriptorLabelListener myDelegate; + + private DescriptorUpdater(ValueDescriptor descriptor, DescriptorLabelListener delegate) { + myTargetDescriptor = descriptor; + myDelegate = delegate; + } + + public void setKeyDescriptor(@Nullable ValueDescriptorImpl keyDescriptor) { + myKeyDescriptor = keyDescriptor; + } + + public void setValueDescriptor(@Nullable ValueDescriptorImpl valueDescriptor) { + myValueDescriptor = valueDescriptor; + } + + public void labelChanged() { + myTargetDescriptor.setValueLabel(constructLabelText(getDescriptorLabel(myKeyDescriptor), getDescriptorLabel(myValueDescriptor))); + myDelegate.labelChanged(); + } + + static String constructLabelText(final String keylabel, final String valueLabel) { + return keylabel + " -> " + valueLabel; + } + + private static String getDescriptorLabel(final ValueDescriptorImpl keyDescriptor) { + return keyDescriptor == null? "null" : keyDescriptor.getValueLabel(); + } + } + } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodReturnValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodReturnValueDescriptorImpl.java index b534f2253966..2ab0b0256485 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodReturnValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodReturnValueDescriptorImpl.java @@ -18,7 +18,6 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.debugger.DebuggerContext; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiExpression; import com.sun.jdi.ClassNotLoadedException; @@ -69,10 +68,6 @@ public class MethodReturnValueDescriptorImpl extends ValueDescriptorImpl{ throw new EvaluateException("Evaluation not supported for method return value"); } - protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) { - return super.calcRepresentation(context, labelListener); - } - public boolean canSetValue() { return false; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 0895b5447e0f..bd9ba6cf46ad 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -29,17 +29,16 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.debugger.ui.tree.render.Renderer; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiExpression; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.concurrency.Semaphore; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.sun.jdi.*; import org.jetbrains.annotations.Nullable; @@ -64,7 +63,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements private boolean myIsDirty = false; private boolean myIsLvalue = false; private boolean myIsExpandable; - public static final int MAX_DISPLAY_LABEL_LENGTH = 1024/*kb*/ *1024 /*bytes*/ / 2; // 1 Mb string + + private boolean myShowIdLabel = true; protected ValueDescriptorImpl(Project project, Value value) { myProject = project; @@ -99,6 +99,14 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements return myValueException == null; } + public boolean isShowIdLabel() { + return myShowIdLabel; + } + + public void setShowIdLabel(boolean showIdLabel) { + myShowIdLabel = showIdLabel; + } + public Value getValue() { // the following code makes sence only if we do not use ObjectReference.enableCollection() / disableCollection() // to keep temporary objects @@ -211,23 +219,41 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements myValue = ((ValueDescriptorImpl)oldDescriptor).getValue(); } - protected void setLvalue (boolean value) { + protected void setLvalue(boolean value) { myIsLvalue = value; } protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener){ - myIsExpandable = (myValueException == null || myValueException.getExceptionFromTargetVM() != null) && getRenderer(context.getDebugProcess()).isExpandable(getValue(), context, this); + DebuggerManagerThreadImpl.assertIsManagerThread(); - return setValueLabel(calcValueLabel(context, labelListener)); + final NodeRenderer renderer = getRenderer(context.getDebugProcess()); + + final EvaluateException valueException = myValueException; + myIsExpandable = (valueException == null || valueException.getExceptionFromTargetVM() != null) && renderer.isExpandable(getValue(), context, this); + + String label; + if (valueException == null) { + try { + label = renderer.calcLabel(this, context, labelListener); + } + catch (EvaluateException e) { + label = setValueLabelFailed(e); + } + } + else { + label = setValueLabelFailed(valueException); + } + + return setValueLabel(label); } private String getCustomLabel(String label) { //translate only strings in quotes final StringBuilder buf = StringBuilderSpinAllocator.alloc(); try { - if(getValue() instanceof ObjectReference) { - final ObjectReference value = (ObjectReference)getValue(); - final String idLabel = value != null? getIdLabel(value) : ""; + final Value value = getValue(); + if(isShowIdLabel() && value instanceof ObjectReference) { + final String idLabel = getIdLabel((ObjectReference)value); if(!label.startsWith(idLabel)) { buf.append(idLabel); } @@ -237,24 +263,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements buf.append("null"); } else { - final boolean isQuoted = label.length() > 1 && StringUtil.startsWithChar(label, '\"') && StringUtil.endsWithChar(label, '\"'); - if(isQuoted) { - label = label.substring(1, label.length() - 1); - buf.append('"'); - } - if (label.length() > MAX_DISPLAY_LABEL_LENGTH) { - label = DebuggerUtils.translateStringValue(label.substring(0, MAX_DISPLAY_LABEL_LENGTH)); - buf.append(label); - if (!label.endsWith("...")) { - buf.append("..."); - } - } - else { - buf.append(DebuggerUtils.translateStringValue(label)); - } - if (isQuoted) { - buf.append('"'); - } + buf.append(label); } return buf.toString(); } @@ -278,19 +287,6 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements public abstract String calcValueName(); - private String calcValueLabel(EvaluationContextImpl evaluationContext, final DescriptorLabelListener labelListener) { - DebuggerManagerThreadImpl.assertIsManagerThread(); - try { - if(myValueException != null) { - throw myValueException; - } - return getRenderer(evaluationContext.getDebugProcess()).calcLabel(this, evaluationContext, labelListener); - } - catch (EvaluateException e) { - return setValueLabelFailed(e); - } - } - public void displayAs(NodeDescriptor descriptor) { if (descriptor instanceof ValueDescriptorImpl) { ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java index 284334301e23..c4051e286b22 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java @@ -28,7 +28,7 @@ public interface ValueDescriptor extends NodeDescriptor{ Value getValue(); - String setValueLabel(String customLabel); + String setValueLabel(String label); String setValueLabelFailed(EvaluateException e); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java index 201d63fd3038..fcbbbc32b3dd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java @@ -98,7 +98,7 @@ public class ClassRenderer extends NodeRendererImpl{ try { if (value instanceof StringReference) { buf.append('\"'); - buf.append(((StringReference)value).value()); + buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value())); buf.append('\"'); } else if (value instanceof ClassObjectReference) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java index fc5969e2aa45..36878a21dfd0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java @@ -98,8 +98,7 @@ public final class EnumerationChildrenRenderer extends com.intellij.debugger.ui. NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager(); List children = new ArrayList(); - for (Iterator> iterator = myChildren.iterator(); iterator.hasNext();) { - Pair pair = iterator.next(); + for (Pair pair : myChildren) { children.add(nodeManager.createNode(descriptorFactory.getUserExpressionDescriptor( builder.getParentDescriptor(), new UserExpressionData((ValueDescriptorImpl)builder.getParentDescriptor(), getClassName(), pair.getFirst(), pair.getSecond())), evaluationContext) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/HexRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/HexRenderer.java index 42810d0f264b..6af36f052582 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/HexRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/HexRenderer.java @@ -16,14 +16,10 @@ package com.intellij.debugger.ui.tree.render; import com.intellij.debugger.DebuggerContext; -import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.ui.tree.render.ChildrenBuilder; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; -import com.intellij.debugger.ui.tree.render.NodeRendererImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiExpression; import com.sun.jdi.*; @@ -61,7 +57,7 @@ public class HexRenderer extends NodeRendererImpl{ @SuppressWarnings({"HardCodedStringLiteral"}) public String calcLabel(ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) { Value value = valueDescriptor.getValue(); - StringBuffer buf = new StringBuffer(16); + StringBuilder buf = new StringBuilder(16); if(value == null) { buf.append("null"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java index a481ec7e0415..60a5019c24a4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java @@ -15,6 +15,7 @@ */ package com.intellij.debugger.ui.tree.render; +import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.evaluation.EvaluateException; @@ -23,7 +24,6 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.engine.evaluation.TextWithImports; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.DebuggerBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; @@ -62,11 +62,12 @@ public class LabelRenderer extends com.intellij.debugger.ui.tree.render.Referenc public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) throws EvaluateException { - String result; - LOG.assertTrue(!(descriptor instanceof PrimitiveValue)); - final DebugProcess debugProcess = evaluationContext.getDebugProcess(); final Value value = descriptor.getValue(); + LOG.assertTrue(!(value instanceof PrimitiveValue)); + + String result; + final DebugProcess debugProcess = evaluationContext.getDebugProcess(); if (value != null) { try { final ExpressionEvaluator evaluator = myLabelExpression.getEvaluator(debugProcess.getProject()); @@ -76,7 +77,7 @@ public class LabelRenderer extends com.intellij.debugger.ui.tree.render.Referenc } EvaluationContext thisEvaluationContext = evaluationContext.createEvaluationContext(value); Value labelValue = evaluator.evaluate(thisEvaluationContext); - result = DebuggerUtils.getValueAsString(thisEvaluationContext, labelValue); + result = DebuggerUtils.convertToPresentationString(DebuggerUtils.getValueAsString(thisEvaluationContext, labelValue)); } catch (final EvaluateException ex) { throw new EvaluateException(DebuggerBundle.message("error.unable.to.evaluate.expression") + " " + ex.getMessage(), ex); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/RendererProvider.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/RendererProvider.java deleted file mode 100644 index 1268c747b453..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/RendererProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.debugger.ui.tree.render; - -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.options.UnnamedConfigurable; -import com.intellij.openapi.project.Project; - -import java.util.List; - -public interface RendererProvider extends ApplicationComponent{ - Renderer createRenderer(String category); - - List getAvailableNodeRenderers(); - - UnnamedConfigurable getRendererConfigurable(Project project, NodeRenderer renderer); - - boolean isSingle(NodeRenderer renderer); -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java index 75830bc64d23..569eabf896e2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java @@ -18,6 +18,7 @@ package com.intellij.debugger.ui.tree.render; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerContext; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.impl.DebuggerUtilsEx; @@ -73,7 +74,8 @@ public class ToStringRenderer extends NodeRendererImpl { final Value value = valueDescriptor.getValue(); BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) { public void evaluationResult(String message) { - valueDescriptor.setValueLabel(message != null ? "\"" + DebuggerUtilsEx.truncateString(message) + "\"" : ""); + final String truncated = DebuggerUtilsEx.truncateString(message); + valueDescriptor.setValueLabel(message != null ? "\"" + DebuggerUtils.convertToPresentationString(truncated) + "\"" : ""); labelListener.labelChanged(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java index fe56cdb43990..9b0618ce2e2d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java @@ -25,6 +25,5 @@ import com.intellij.debugger.ui.tree.ValueDescriptor; * Time: 10:12:39 PM */ public interface ValueLabelRenderer extends Renderer { - String calcLabel (ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) - throws EvaluateException; + String calcLabel (ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) throws EvaluateException; } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java index bcea69bbd442..382bcff89b41 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java @@ -121,6 +121,21 @@ public abstract class DebuggerUtils { } } + public static final int MAX_DISPLAY_LABEL_LENGTH = 1024/*kb*/ *1024 /*bytes*/ / 2; // 1 Mb string + + public static String convertToPresentationString(String str) { + if (str.length() > MAX_DISPLAY_LABEL_LENGTH) { + str = translateStringValue(str.substring(0, MAX_DISPLAY_LABEL_LENGTH)); + StringBuilder buf = new StringBuilder(); + buf.append(str); + if (!str.endsWith("...")) { + buf.append("..."); + } + return buf.toString(); + } + return translateStringValue(str); + } + @Nullable public static Method findMethod(ReferenceType refType, @NonNls String methodName, @NonNls String methodSignature) { if (refType instanceof ArrayType) {