Skip to content

Commit ae2847e

Browse files
Added attributes to VariablePresentationHint as specified in protocol definition (#625)
* added attributes to VariablePresentationHint as specified in protocol definition * Fixed issue with lazy VariablePresentationHint. Restricted constant to Primitive & StringRefs
1 parent a4c27fb commit ae2847e

2 files changed

Lines changed: 47 additions & 17 deletions

File tree

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
import com.sun.jdi.StringReference;
6666
import com.sun.jdi.Type;
6767
import com.sun.jdi.Value;
68+
import com.sun.jdi.PrimitiveType;
69+
import com.sun.jdi.ClassNotLoadedException;
6870

6971
public class VariablesRequestHandler implements IDebugRequestHandler {
7072
protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
@@ -82,7 +84,7 @@ public class VariablesRequestHandler implements IDebugRequestHandler {
8284
* single-threaded JDWP request processing strategy,
8385
* a single JDWP latency is about 10ms.
8486
*/
85-
static final long USABLE_JDWP_LATENCY = 10/**ms*/;
87+
static final long USABLE_JDWP_LATENCY = 10/*ms*/;
8688

8789
@Override
8890
public List<Command> getTargetCommands() {
@@ -370,10 +372,12 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
370372
referenceId = context.getRecyclableIdPool().addObject(containerNode.getThreadId(), varProxy);
371373
}
372374

375+
String[] rawAttributes = extractAttributes(javaVariable);
376+
373377
Types.Variable typedVariables = new Types.Variable(name, valueString, typeString, referenceId, evaluateName);
374378
typedVariables.indexedVariables = Math.max(indexedVariables, 0);
375-
if (varProxy != null && varProxy.isLazyVariable()) {
376-
typedVariables.presentationHint = new VariablePresentationHint(true);
379+
if ((varProxy != null && varProxy.isLazyVariable()) || (rawAttributes.length > 0)) {
380+
typedVariables.presentationHint = new VariablePresentationHint(varProxy != null && varProxy.isLazyVariable(), rawAttributes);
377381
}
378382

379383
if (detailsValue != null) {
@@ -391,6 +395,36 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
391395
return CompletableFuture.completedFuture(response);
392396
}
393397

398+
private String[] extractAttributes(Variable variable) {
399+
final List<String> attributes = new ArrayList<>();
400+
if (variable.field != null) {
401+
if (variable.field.isStatic()) {
402+
attributes.add("static");
403+
}
404+
if (variable.field.isFinal()) {
405+
// static final Primitive or StringRef fields are compile-time constants in Java
406+
boolean isPrimitive;
407+
try {
408+
isPrimitive = variable.field.type() instanceof PrimitiveType;
409+
} catch (ClassNotLoadedException e) { /* type() not yet loaded indicates some ReferenceType */
410+
isPrimitive = false;
411+
}
412+
boolean canBeTrueConstant = (isPrimitive || variable.field instanceof StringReference);
413+
if (variable.field.isStatic() && canBeTrueConstant) {
414+
attributes.add("constant");
415+
}
416+
attributes.add("readOnly");
417+
}
418+
}
419+
// local 'final' variables get inlined by the compiler and do not appear
420+
421+
if (variable.value instanceof StringReference) {
422+
attributes.add("rawString");
423+
}
424+
425+
return attributes.toArray(new String[0]);
426+
}
427+
394428
private boolean supportsLogicStructureView(IDebugAdapterContext context) {
395429
return (!useAsyncJDWP(context) || context.getJDWPLatency() <= USABLE_JDWP_LATENCY)
396430
&& DebugSettings.getCurrent().showLogicalStructure;

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,13 @@ public static class StackFrame {
4949
/**
5050
* Constructs a StackFrame with the given information.
5151
*
52-
* @param id
53-
* the stack frame id
54-
* @param name
55-
* the stack frame name
56-
* @param src
57-
* source info of the stack frame
58-
* @param ln
59-
* line number of the stack frame
60-
* @param col
61-
* column number of the stack frame
62-
* @param presentationHint
63-
* An optional hint for how to present this frame in the UI.
64-
* Values: 'normal', 'label', 'subtle'
52+
* @param id the stack frame id
53+
* @param name the stack frame name
54+
* @param src source info of the stack frame
55+
* @param ln line number of the stack frame
56+
* @param col column number of the stack frame
57+
* @param presentationHint An optional hint for how to present this frame in the UI.
58+
* Values: 'normal', 'label', 'subtle'
6559
*/
6660
public StackFrame(int id, String name, Source src, int ln, int col, String presentationHint) {
6761
this.id = id;
@@ -408,9 +402,11 @@ public static class ExceptionDetails {
408402

409403
public static class VariablePresentationHint {
410404
public boolean lazy;
405+
public String[] attributes;
411406

412-
public VariablePresentationHint(boolean lazy) {
407+
public VariablePresentationHint(boolean lazy, String[] attributes) {
413408
this.lazy = lazy;
409+
this.attributes = attributes;
414410
}
415411
}
416412

0 commit comments

Comments
 (0)