Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Show as Binary #429

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ hs_err_pid*
target/
.settings
**/.checkstyle
target/
bin/
**/lib/

jdt-language-server-latest.tar.gz
jdtls/

!.mvn/wrapper/maven-wrapper.jar
!.mvn/wrapper/maven-wrapper.jar
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.SerializedName;
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum;
import com.microsoft.java.debug.core.protocol.JsonUtils;
import com.microsoft.java.debug.core.protocol.Requests.ClassFilters;
import com.microsoft.java.debug.core.protocol.Requests.StepFilters;
Expand All @@ -32,7 +33,7 @@ public final class DebugSettings {
public int numericPrecision = 0;
public boolean showStaticVariables = false;
public boolean showQualifiedNames = false;
public boolean showHex = false;
public NumericFormatEnum formatType = NumericFormatEnum.DEC;
public boolean showLogicalStructure = true;
public boolean showToString = true;
public String logLevel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
package com.microsoft.java.debug.core.adapter.formatter;

public enum NumericFormatEnum {
BIN,
HEX,
OCT,
DEC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,15 @@ public class NumericFormatter implements IValueFormatter {
public static final String NUMERIC_PRECISION_OPTION = "numeric_precision";
private static final NumericFormatEnum DEFAULT_NUMERIC_FORMAT = NumericFormatEnum.DEC;
private static final int DEFAULT_NUMERIC_PRECISION = 0;
private static final Map<NumericFormatEnum, String> enumFormatMap = new HashMap<>();

static {
enumFormatMap.put(NumericFormatEnum.DEC, "%d");
enumFormatMap.put(NumericFormatEnum.HEX, "%#x");
enumFormatMap.put(NumericFormatEnum.OCT, "%#o");
}
private static final String HEX_PREFIX = "0x";
private static final String OCT_PREFIX = "0";
private static final String BIN_PREFIX = "0b";

/**
* Get the string representations for an object.
*
* @param obj the value object
* @param obj the value object
* @param options extra information for printing
* @return the string representations.
*/
Expand Down Expand Up @@ -91,7 +88,6 @@ public Value valueOf(String value, Type type, Map<String, Object> options) {
throw new UnsupportedOperationException(String.format("%s is not a numeric type.", type.name()));
}


/**
* The conditional function for this formatter.
*
Expand Down Expand Up @@ -122,11 +118,21 @@ public Map<String, Object> getDefaultOptions() {

static String formatNumber(long value, Map<String, Object> options) {
NumericFormatEnum formatEnum = getNumericFormatOption(options);
return String.format(enumFormatMap.get(formatEnum), value);
switch (formatEnum) {
case HEX:
return HEX_PREFIX + Long.toHexString(value);
case OCT:
return OCT_PREFIX + Long.toOctalString(value);
case BIN:
return BIN_PREFIX + Long.toBinaryString(value);
default:
return Long.toString(value);
}
}

private static long parseNumber(String number) {
return Long.decode(number);
return number.startsWith(BIN_PREFIX)
? Long.parseLong(number.substring(2), 2) : Long.decode(number);
}

private static double parseFloatDouble(String number) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
EvaluateArguments evalArguments = (EvaluateArguments) arguments;
final boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;
Map<String, Object> options = context.getVariableFormatter().getDefaultOptions();
VariableUtils.applyFormatterOptions(options, evalArguments.format != null && evalArguments.format.hex);
VariableUtils.applyFormatterOptions(options, evalArguments.format);
String expression = evalArguments.expression;

if (StringUtils.isBlank(expression)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@
import com.microsoft.java.debug.core.DebugSettings;
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum;
import com.microsoft.java.debug.core.protocol.Events.InvalidatedAreas;
import com.microsoft.java.debug.core.protocol.Events.InvalidatedEvent;
import com.microsoft.java.debug.core.protocol.Messages.Response;
import com.microsoft.java.debug.core.protocol.Requests;
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
import com.microsoft.java.debug.core.protocol.Requests.Command;
import com.microsoft.java.debug.core.protocol.Requests.RefreshVariablesArguments;

import static com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum.HEX;
import static com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum.DEC;

public class RefreshVariablesHandler implements IDebugRequestHandler {

@Override
Expand All @@ -37,7 +42,7 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
IDebugAdapterContext context) {
RefreshVariablesArguments refreshArgs = (RefreshVariablesArguments) arguments;
if (refreshArgs != null) {
DebugSettings.getCurrent().showHex = refreshArgs.showHex;
DebugSettings.getCurrent().formatType = getFormatType(refreshArgs.showHex, refreshArgs.formatType);
DebugSettings.getCurrent().showQualifiedNames = refreshArgs.showQualifiedNames;
DebugSettings.getCurrent().showStaticVariables = refreshArgs.showStaticVariables;
DebugSettings.getCurrent().showLogicalStructure = refreshArgs.showLogicalStructure;
Expand All @@ -47,4 +52,15 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
context.getProtocolServer().sendEvent(new InvalidatedEvent(InvalidatedAreas.VARIABLES));
return CompletableFuture.completedFuture(response);
}

private NumericFormatEnum getFormatType(boolean showHex, String formatType) {
if (formatType != null) {
try {
return NumericFormatEnum.valueOf(formatType);
} catch (IllegalArgumentException exp) {
// can't parse format so just return default value;
}
}
return showHex ? NumericFormatEnum.HEX : NumericFormatEnum.DEC;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;
IVariableFormatter variableFormatter = context.getVariableFormatter();
Map<String, Object> options = variableFormatter.getDefaultOptions();
VariableUtils.applyFormatterOptions(options, setVarArguments.format != null && setVarArguments.format.hex);
VariableUtils.applyFormatterOptions(options, setVarArguments.format);

Object container = context.getRecyclableIdPool().getObjectById(setVarArguments.variablesReference);
// container is null means the stack frame is continued by user manually.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;

Map<String, Object> options = variableFormatter.getDefaultOptions();
VariableUtils.applyFormatterOptions(options, varArgs.format != null && varArgs.format.hex);
VariableUtils.applyFormatterOptions(options, varArgs.format);
IEvaluationProvider evaluationEngine = context.getProvider(IEvaluationProvider.class);

List<Types.Variable> list = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatter;
import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter;
import com.microsoft.java.debug.core.adapter.formatter.StringObjectFormatter;
import com.microsoft.java.debug.core.protocol.Requests;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
Expand Down Expand Up @@ -256,13 +257,15 @@ public static List<Variable> listStaticVariables(StackFrame stackFrame) {
* variable view/debug console.
*
* @param defaultOptions the initial options for adding options from user settings
* @param hexInArgument when request sent by vscode declare hex format explicitly, settings this parameter true to override value in DebugSettings class.
* @param format when request sent by vscode declare format explicitly, settings this parameter true to override value in DebugSettings class.
*/
public static void applyFormatterOptions(Map<String, Object> defaultOptions, boolean hexInArgument) {
public static void applyFormatterOptions(Map<String, Object> defaultOptions, Requests.ValueFormat format) {
Map<String, Object> options = defaultOptions;
boolean showFullyQualifiedNames = DebugSettings.getCurrent().showQualifiedNames;
if (hexInArgument || DebugSettings.getCurrent().showHex) {
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, NumericFormatEnum.HEX);
if (format == null) {
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, DebugSettings.getCurrent().formatType);
} else {
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, parseValueFormat(format));
}
if (showFullyQualifiedNames) {
options.put(SimpleTypeFormatter.QUALIFIED_CLASS_NAME_OPTION, true);
Expand All @@ -277,6 +280,17 @@ public static void applyFormatterOptions(Map<String, Object> defaultOptions, boo
}
}

private static NumericFormatEnum parseValueFormat(Requests.ValueFormat format) {
if (format.type != null) {
try {
return NumericFormatEnum.valueOf(format.type);
} catch (IllegalArgumentException exp) {
// can't parse format so just return default value;
}
}
return format.hex ? NumericFormatEnum.HEX : NumericFormatEnum.DEC;
}

/**
* Get the name for evaluation of variable.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
public class Requests {

public static class ValueFormat {
@Deprecated
public boolean hex;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hex is part of the specification: https://microsoft.github.io/debug-adapter-protocol/specification#Types_ValueFormat, what's the rationale for deprecating this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of new functionality we can format values to different formats now, beside hex. And I added new property ValueFormat#type instead of ValueFormat#hex to support that possibility. I assumed we can delete ValueFormat#hex in future with no harm because of no need and marked hex as deprecated. Just tell me if I did something wrong and I'll fix it. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mylog00 The data types under the folder com/microsoft/java/debug/core/protocol are generated from the DAP spec, we can't just change it on debugger side.

It's OK to extend the debug settings to support more format types, but remember to support the old valueFormat.hex as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed @Deprecated annotation and added doc to new property ValueFormat#type. Support of the old valueFormat.hex already was in my code for backward compatibility.
Should I create PR to DAP or do something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When contributing to the DAP, you need to open an issue to discuss the proposal first. Only if the proposal is accepted, then open a PR.

A quick search and found a duplicated issue for more formatting options. microsoft/debug-adapter-protocol#197

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! If there is no other issue could you approve this PR?)

public String type;
}

public static class Arguments {
Expand Down Expand Up @@ -300,7 +302,9 @@ public static class SetVariableArguments extends Arguments {
public static class RefreshVariablesArguments extends Arguments {
public boolean showStaticVariables = false;
public boolean showQualifiedNames = false;
@Deprecated
public boolean showHex = false;
public String formatType = null;
public boolean showLogicalStructure = true;
public boolean showToString = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void testToString() throws Exception {
}

@Test
public void testToHexOctString() throws Exception {
public void testToHexOctBinString() throws Exception {
Value i = this.getLocalValue("i");

Map<String, Object> options = formatter.getDefaultOptions();
Expand All @@ -113,7 +113,11 @@ public void testToHexOctString() throws Exception {

options.put(NUMERIC_FORMAT_OPTION, NumericFormatEnum.OCT);
assertEquals("NumericFormatter should be able to format an oct integer.",
"0" +Integer.toOctalString(111), formatter.toString(i, options));
"0" + Integer.toOctalString(111), formatter.toString(i, options));

options.put(NUMERIC_FORMAT_OPTION, NumericFormatEnum.BIN);
assertEquals("NumericFormatter should be able to format an bin integer.",
"0b" + Integer.toBinaryString(111), formatter.toString(i, options));
}

@Test
Expand All @@ -127,7 +131,6 @@ public void testValueOf() throws Exception {
assertEquals("Should create an integer with right value.", "111", newValue.toString());

options.put(NUMERIC_FORMAT_OPTION, NumericFormatEnum.HEX);

newValue = formatter.valueOf(formatter.toString(i, options), i.type(), options);
assertNotNull("NumericFormatter should be able to create integer by string.", newValue);
assertTrue("Should create an integer value.", newValue instanceof IntegerValue);
Expand All @@ -139,6 +142,12 @@ public void testValueOf() throws Exception {
assertTrue("Should create an integer value.", newValue instanceof IntegerValue);
assertEquals("Should create an integer with right value.", "111", newValue.toString());

options.put(NUMERIC_FORMAT_OPTION, NumericFormatEnum.BIN);
newValue = formatter.valueOf(formatter.toString(i, options), i.type(), options);
assertNotNull("NumericFormatter should be able to create integer by string.", newValue);
assertTrue("Should create an integer value.", newValue instanceof IntegerValue);
assertEquals("Should create an integer with right value.", "111", newValue.toString());


newValue = formatter.valueOf("-12121212", i.type(), options);
assertNotNull("NumericFormatter should be able to create integer by string.", newValue);
Expand Down