introduced renderers for unboxable types

This commit is contained in:
Egor.Ushakov
2017-04-13 12:49:41 +03:00
parent 66cb95f230
commit 410fc5c262
4 changed files with 128 additions and 23 deletions
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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) {
+8
View File
@@ -1757,6 +1757,14 @@
<debugger.sourcePositionHighlighter implementation="com.intellij.debugger.engine.JavaSourcePositionHighlighter"/>
<java.elementFinder implementation="com.intellij.debugger.impl.AlternativeJreClassFinder" order="last"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$BooleanRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$ByteRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$CharacterRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$ShortRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$IntegerRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$LongRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$FloatRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$DoubleRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.ColorObjectRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.ImageObjectRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.IconObjectRenderer"/>