Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,56 @@
import com.sun.jdi.Type;
import com.sun.jdi.Value;

/**
* Formatter for array objects in the Java Debug Interface (JDI).
* Extends the ObjectFormatter to provide string representations of array objects,
* incorporating the array length into the format.
*/
public class ArrayObjectFormatter extends ObjectFormatter {

/**
* Constructs an ArrayObjectFormatter with a specific type string function.
*
* @param typeStringFunction A function that generates a string representation based on the JDI type and options.
*/
public ArrayObjectFormatter(BiFunction<Type, Map<String, Object>, String> typeStringFunction) {
super(typeStringFunction);
}

/**
* Generates a prefix for the array object string representation,
* including the array's type and length.
*
* @param value The object reference for the array.
* @param options Additional options to format the string.
* @return A string prefix for the array representation.
*/
@Override
protected String getPrefix(ObjectReference value, Map<String, Object> options) {
String arrayTypeWithLength = String.format("[%s]",
NumericFormatter.formatNumber(arrayLength(value), options));
return super.getPrefix(value, options).replaceFirst("\\[]", arrayTypeWithLength);
}

/**
* Determines if this formatter can handle the provided type,
* specifically checking for array types.
*
* @param type The JDI type of the object.
* @param options Additional options that might influence the formatting.
* @return True if the type is an array, false otherwise.
*/
@Override
public boolean acceptType(Type type, Map<String, Object> options) {
return type != null && type.signature().charAt(0) == ARRAY;
}

/**
* Calculates the length of the array.
*
* @param value The JDI value representing the array.
* @return The length of the array.
*/
private static int arrayLength(Value value) {
return ((ArrayReference) value).length();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,33 @@
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;

/**
* Formatter for boolean values in the Java Debug Interface (JDI).
* Implements the IValueFormatter interface to provide string representations
* and value conversions for boolean types.
*/
public class BooleanFormatter implements IValueFormatter {

/**
* Converts a JDI value object into its string representation.
*
* @param value The value to be formatted to string.
* @param options Additional options affecting the format; unused in this formatter.
* @return A string representation of the boolean value, or "null" if the value is null.
*/
@Override
public String toString(Object value, Map<String, Object> options) {
return value == null ? NullObjectFormatter.NULL_STRING : value.toString();
}

/**
* Determines if this formatter is applicable for the given type,
* specifically checking for boolean types.
*
* @param type The JDI type of the object.
* @param options Additional options that might influence the formatting; unused in this formatter.
* @return True if the type is a boolean, false otherwise.
*/
@Override
public boolean acceptType(Type type, Map<String, Object> options) {
if (type == null) {
Expand All @@ -35,6 +55,14 @@ public boolean acceptType(Type type, Map<String, Object> options) {
return signature0 == BOOLEAN;
}

/**
* Converts a string representation of a boolean into a JDI Value object.
*
* @param value The string value to convert.
* @param type The expected JDI type; used to fetch the VirtualMachine reference.
* @param options Additional conversion options; unused in this formatter.
* @return A JDI Value representing the boolean state indicated by the input string.
*/
@Override
public Value valueOf(String value, Type type, Map<String, Object> options) {
VirtualMachine vm = type.virtualMachine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,33 @@
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;

/**
* Formatter for character values in the Java Debug Interface (JDI).
* Implements the IValueFormatter interface to provide string representations
* and value conversions for char types.
*/
public class CharacterFormatter implements IValueFormatter {

/**
* Converts a JDI value object into its string representation.
*
* @param value The character value to be formatted to string.
* @param options Additional options affecting the format; unused in this formatter.
* @return A string representation of the character value, or "null" if the value is null.
*/
@Override
public String toString(Object value, Map<String, Object> options) {
return value == null ? NullObjectFormatter.NULL_STRING : value.toString();
}

/**
* Determines if this formatter is applicable for the given type,
* specifically checking for char types.
*
* @param type The JDI type of the object.
* @param options Additional options that might influence the formatting; unused in this formatter.
* @return True if the type is a char, false otherwise.
*/
@Override
public boolean acceptType(Type type, Map<String, Object> options) {
if (type == null) {
Expand All @@ -35,17 +55,27 @@ public boolean acceptType(Type type, Map<String, Object> options) {
return signature0 == CHAR;
}

/**
* Converts a string representation of a character into a JDI Value object.
*
* @param value The string value to convert, expected to be a single character or a character within single quotes.
* @param type The expected JDI type; used to fetch the VirtualMachine reference.
* @param options Additional conversion options; unused in this formatter.
* @return A JDI Value representing the character indicated by the input string. Handles both single characters and characters encapsulated in single quotes.
*/
@Override
public Value valueOf(String value, Type type, Map<String, Object> options) {
VirtualMachine vm = type.virtualMachine();
if (value == null) {
return null;
}
// Supports parsing character values encapsulated in single quotes, e.g., 'a'.
if (value.length() == 3
&& value.startsWith("'")
&& value.endsWith("'")) {
return type.virtualMachine().mirrorOf(value.charAt(1));
}
// Default case for single characters not encapsulated in quotes.
return vm.mirrorOf(value.charAt(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,43 @@
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Type;

/**
* Formatter for Java ClassObjectReferences in the Java Debug Interface (JDI).
* Extends the ObjectFormatter to provide customized string representations of Class objects,
* incorporating additional class type information.
*/
public class ClassObjectFormatter extends ObjectFormatter {

/**
* Constructs a ClassObjectFormatter with a specific function to generate string representations based on the JDI type.
*
* @param typeStringFunction A function that generates a string representation based on the JDI type and formatting options.
*/
public ClassObjectFormatter(BiFunction<Type, Map<String, Object>, String> typeStringFunction) {
super(typeStringFunction);
}

/**
* Generates a string prefix for ClassObjectReference instances, enhancing the default object prefix with class type information.
*
* @param value The object reference, expected to be a ClassObjectReference.
* @param options Additional formatting options that may influence the output.
* @return A string prefix that includes both the default object prefix and the class's type information.
*/
@Override
protected String getPrefix(ObjectReference value, Map<String, Object> options) {
Type classType = ((ClassObjectReference) value).reflectedType();
return String.format("%s (%s)", super.getPrefix(value, options),
typeToStringFunction.apply(classType, options));
}

/**
* Determines if this formatter can handle the provided type, specifically targeting ClassObject and its signature.
*
* @param type The JDI type of the object.
* @param options Additional options that might influence the decision; unused in this formatter.
* @return True if the type is a ClassObject or matches the Class signature, false otherwise.
*/
@Override
public boolean acceptType(Type type, Map<String, Object> options) {
return super.acceptType(type, options) && (type.signature().charAt(0) == CLASS_OBJECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@

package com.microsoft.java.debug.core.adapter.formatter;

/**
* Represents a formatter dedicated to handling specific types within the Java Debug Interface (JDI).
* This interface extends the {@link IFormatter}, inheriting its methods for converting objects to string representations
* and determining applicability based on type. Implementers of this interface should provide type-specific
* formatting logic to accurately represent objects during debugging.
*/
public interface ITypeFormatter extends IFormatter {
// Inherits all methods from IFormatter without adding new ones.
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,49 @@
import com.sun.jdi.Type;
import com.sun.jdi.Value;

/**
* A formatter dedicated to handling null values in the Java Debug Interface (JDI).
* Implements the {@link IValueFormatter} interface, providing a uniform representation
* for null objects during debugging sessions.
*/
public class NullObjectFormatter implements IValueFormatter {
public static final String NULL_STRING = "null";

/**
* Provides a string representation for null values.
*
* @param value The value to be formatted, expected to be null in this context.
* @param options Additional options affecting the format; unused in this formatter.
* @return A constant string "null" to represent null values.
*/
@Override
public String toString(Object value, Map<String, Object> options) {
return NULL_STRING;
}

/**
* Determines if this formatter is applicable for the given type,
* specifically targeting null types.
*
* @param type The JDI type of the object, expected to be null.
* @param options Additional options that might influence the decision; unused in this formatter.
* @return True if the type is null, indicating this formatter should be used.
*/
@Override
public boolean acceptType(Type type, Map<String, Object> options) {
return type == null;
}

/**
* Converts a string representation of null into a JDI Value object, which is also null.
* Throws {@link UnsupportedOperationException} if a non-null value is attempted to be set.
*
* @param value The string value to convert, expected to match "null".
* @param type The expected JDI type; unused in this formatter as the output is always null.
* @param options Additional conversion options; unused in this formatter.
* @return null, as the only supported conversion is from the string "null" to a null {@link Value}.
* @throws UnsupportedOperationException if set value is attempted with a non-null value.
*/
@Override
public Value valueOf(String value, Type type, Map<String, Object> options) {
if (value == null || NULL_STRING.equals(value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,27 @@

package com.microsoft.java.debug.core.adapter.formatter;

/**
* Defines the numeric formats that can be used for displaying numbers during debugging.
* This enumeration is utilized by formatters to convert numeric values into their
* string representations in various numeric bases.
*/
public enum NumericFormatEnum {
/**
* Represents hexadecimal format.
* Numbers displayed in this format are prefixed with '0x' to indicate hexadecimal.
*/
HEX,

/**
* Represents octal format.
* Numbers displayed in this format are prefixed with '0' to indicate octal.
*/
OCT,

/**
* Represents decimal format.
* This is the standard numeric format, displaying numbers in base 10 with no prefix.
*/
DEC
}
Loading