diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java index c3f841ddeab0..2e830e3d6013 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java @@ -15,13 +15,12 @@ */ package com.intellij.debugger.engine.evaluation.expression; -import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Couple; import com.intellij.psi.CommonClassNames; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.intellij.util.containers.HashMap; import com.sun.jdi.*; import org.jetbrains.annotations.NotNull; @@ -78,25 +77,32 @@ public class UnBoxingEvaluator implements Evaluator { private static Value convertToPrimitive(EvaluationContextImpl context, ObjectReference value, final String conversionMethodName, String conversionMethodSignature) throws EvaluateException { - final DebugProcessImpl process = context.getDebugProcess(); - final ClassType wrapperClass = (ClassType)value.referenceType(); - // for speedup first try value field - Field valueField = wrapperClass.fieldByName("value"); - if (valueField != null) { - Value primitiveValue = value.getValue(valueField); - if (primitiveValue != null) { - LOG.assertTrue(DebuggerUtilsEx.signatureToName(conversionMethodSignature).startsWith(primitiveValue.type().name())); - return primitiveValue; - } + Value primitiveValue = getInnerPrimitiveValue(value); + if (primitiveValue != null) { + return primitiveValue; } - Method method = wrapperClass.concreteMethodByName(conversionMethodName, conversionMethodSignature); + Method method = ((ClassType)value.referenceType()).concreteMethodByName(conversionMethodName, conversionMethodSignature); if (method == null) { throw new EvaluateException("Cannot convert to primitive value of type " + value.type() + ": Unable to find method " + conversionMethodName + conversionMethodSignature); } - return process.invokeMethod(context, value, method, Collections.emptyList()); + return context.getDebugProcess().invokeMethod(context, value, method, Collections.emptyList()); + } + + @Nullable + public static PrimitiveValue getInnerPrimitiveValue(ObjectReference value) { + ReferenceType type = value.referenceType(); + Field valueField = type.fieldByName("value"); + if (valueField != null) { + Value primitiveValue = value.getValue(valueField); + if (primitiveValue instanceof PrimitiveValue) { + LOG.assertTrue(type.name().equals(PsiJavaParserFacadeImpl.getPrimitiveType(primitiveValue.type().name()).getBoxedTypeName())); + return (PrimitiveValue)primitiveValue; + } + } + return null; } } \ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java new file mode 100644 index 000000000000..52c047081ee6 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2017 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.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.engine.evaluation.expression.UnBoxingEvaluator; +import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.CommonClassNames; +import com.sun.jdi.ObjectReference; + +/** + * @author egor + */ +public abstract class UnboxableTypeRenderer extends CompoundReferenceRenderer { + public UnboxableTypeRenderer(String className, NodeRendererSettings rendererSettings) { + super(rendererSettings, StringUtil.getShortName(className), new LabelRenderer() { + @Override + public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) + throws EvaluateException { + return DebuggerUtils.getValueAsString(evaluationContext, UnBoxingEvaluator.getInnerPrimitiveValue((ObjectReference)descriptor.getValue())); + } + }, null); + LOG.assertTrue(UnBoxingEvaluator.isTypeUnboxable(className)); + setClassName(className); + setEnabled(true); + } + + public static class BooleanRenderer extends UnboxableTypeRenderer { + public BooleanRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_BOOLEAN, rendererSettings); + } + } + + public static class ByteRenderer extends UnboxableTypeRenderer { + public ByteRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_BYTE, rendererSettings); + } + } + + public static class CharacterRenderer extends UnboxableTypeRenderer { + public CharacterRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_CHARACTER, rendererSettings); + } + } + + public static class ShortRenderer extends UnboxableTypeRenderer { + public ShortRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_SHORT, rendererSettings); + } + } + + public static class IntegerRenderer extends UnboxableTypeRenderer { + public IntegerRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_INTEGER, rendererSettings); + } + } + + public static class LongRenderer extends UnboxableTypeRenderer { + public LongRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_LONG, rendererSettings); + } + } + + public static class FloatRenderer extends UnboxableTypeRenderer { + public FloatRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_FLOAT, rendererSettings); + } + } + + public static class DoubleRenderer extends UnboxableTypeRenderer { + public DoubleRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_DOUBLE, rendererSettings); + } + } +} 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 ef55ee92e099..a48a908d6c4c 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java @@ -72,20 +72,19 @@ public abstract class DebuggerUtils { return ((StringReference)value).value(); } if (isInteger(value)) { - long v = ((PrimitiveValue)value).longValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).longValue()); } - if (isNumeric(value)) { - double v = ((PrimitiveValue)value).doubleValue(); - return String.valueOf(v); + if (value instanceof FloatValue) { + return String.valueOf(((FloatValue)value).floatValue()); + } + if (value instanceof DoubleValue) { + return String.valueOf(((DoubleValue)value).doubleValue()); } if (value instanceof BooleanValue) { - boolean v = ((PrimitiveValue)value).booleanValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).booleanValue()); } if (value instanceof CharValue) { - char v = ((PrimitiveValue)value).charValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).charValue()); } if (value instanceof ObjectReference) { if (value instanceof ArrayReference) { diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 89c31ce067d9..160f2f5a7490 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1757,6 +1757,14 @@ + + + + + + + +