diff options
author | brendandouglas <brendandouglas@google.com> | 2018-07-16 11:47:16 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-07-16 11:48:36 -0700 |
commit | 2aa08188cd36125c616f3ff998e7d2d71f711fb4 (patch) | |
tree | ff2d01fbd0acc4f9f4014cac038d984ace60d93c /src/main | |
parent | d0d5533ff045c308b60101541badea1d79c4adc1 (diff) |
Skylark debugger: show contents of SkylarkValue objects when serializing.
Temporary solution finding the SkylarkCallable fields using reflection,
mirroring the existing handling of ClassObject.
PiperOrigin-RevId: 204779295
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skylarkdebug/server/DebuggerSerialization.java | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/DebuggerSerialization.java b/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/DebuggerSerialization.java index 0bc7b6fb01..75d7e00c8f 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/DebuggerSerialization.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkdebug/server/DebuggerSerialization.java @@ -19,13 +19,16 @@ import com.google.common.collect.Ordering; import com.google.devtools.build.lib.collect.nestedset.NestedSetView; import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos; import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos.Value; +import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.ClassObject; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; +import com.google.devtools.build.lib.syntax.FuncallExpression; import com.google.devtools.build.lib.syntax.Printer; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import java.lang.reflect.Array; import java.util.Map; +import java.util.Set; /** Helper class for creating {@link SkylarkDebuggingProtos.Value} from skylark objects. */ final class DebuggerSerialization { @@ -50,16 +53,7 @@ final class DebuggerSerialization { return Printer.repr(value); } - private static Value errorValue(String errorMessage) { - return Value.newBuilder().setLabel("Error").setDescription(errorMessage).build(); - } - private static boolean hasChildren(Object value) { - if (value instanceof ClassObject) { - // assuming ClassObject's have at least one child as a temporary optimization - // TODO(bazel-team): remove once child-listing logic is moved to SkylarkValue - return true; - } if (value instanceof SkylarkNestedSet) { return true; } @@ -78,15 +72,16 @@ final class DebuggerSerialization { if (value.getClass().isArray()) { return Array.getLength(value) > 0; } + if (value instanceof ClassObject || value instanceof SkylarkValue) { + // assuming ClassObject's have at least one child as a temporary optimization + // TODO(bazel-team): remove once child-listing logic is moved to SkylarkValue + return true; + } // fallback to assuming there are no children return false; } static ImmutableList<Value> getChildren(ThreadObjectMap objectMap, Object value) { - // TODO(bazel-team): move child-listing logic to SkylarkValue where practical - if (value instanceof ClassObject) { - return getChildren(objectMap, (ClassObject) value); - } if (value instanceof SkylarkNestedSet) { return getChildren(objectMap, (SkylarkNestedSet) value); } @@ -105,6 +100,13 @@ final class DebuggerSerialization { if (value.getClass().isArray()) { return getArrayChildren(objectMap, value); } + // TODO(bazel-team): move child-listing logic to SkylarkValue where practical + if (value instanceof ClassObject) { + return getChildren(objectMap, (ClassObject) value); + } + if (value instanceof SkylarkValue) { + return getChildren(objectMap, (SkylarkValue) value); + } // fallback to assuming there are no children return ImmutableList.of(); } @@ -115,26 +117,51 @@ final class DebuggerSerialization { ImmutableList<String> keys; try { keys = Ordering.natural().immutableSortedCopy(classObject.getFieldNames()); - } catch (EvalException e) { - return ImmutableList.of(errorValue("Error retrieving field names: " + e.getMessage())); + } catch (EvalException | IllegalArgumentException e) { + // silently return no children + return ImmutableList.of(); } for (String key : keys) { Object value; try { value = classObject.getValue(key); - } catch (EvalException e) { - return ImmutableList.of( - errorValue( - String.format("Error retrieving value for field '%s': %s", key, e.getMessage()))); - } - if (value != null) { - builder.add(getValueProto(objectMap, key, value)); + if (value != null) { + builder.add(getValueProto(objectMap, key, value)); + } + } catch (EvalException | IllegalArgumentException e) { + // silently ignore errors } } return builder.build(); } private static ImmutableList<Value> getChildren( + ThreadObjectMap objectMap, SkylarkValue skylarkValue) { + Set<String> fieldNames; + try { + fieldNames = FuncallExpression.getStructFieldNames(skylarkValue.getClass()); + } catch (IllegalArgumentException e) { + // silently return no children + return ImmutableList.of(); + } + ImmutableList.Builder<Value> children = ImmutableList.builder(); + for (String fieldName : fieldNames) { + FuncallExpression.MethodDescriptor method = + FuncallExpression.getStructField(skylarkValue.getClass(), fieldName); + try { + children.add( + getValueProto( + objectMap, + fieldName, + FuncallExpression.invokeStructField(method, fieldName, skylarkValue))); + } catch (EvalException | InterruptedException | IllegalArgumentException e) { + // silently ignore errors + } + } + return children.build(); + } + + private static ImmutableList<Value> getChildren( ThreadObjectMap objectMap, SkylarkNestedSet nestedSet) { Class<?> type = nestedSet.getContentType().getType(); return ImmutableList.<Value>builder() |