Skip to content

Commit

Permalink
Add [DebuggerDisplay] to Json types (dotnet/corefx#38275)
Browse files Browse the repository at this point in the history
* Add [DebuggerDisplay] to Json types

Note that there is an issue with turning the TokenType to string in Utf8JsonReader. Probably reflection related? I've been unable to create a more focused repro.

* Add some simple sanity tests

* Address some feedback.

* Use JsonValueType


Commit migrated from dotnet/corefx@b506d4a
  • Loading branch information
JeremyKuhne authored and ahsonkhan committed Jun 13, 2019
1 parent 760185c commit 82f07be
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public partial struct JsonElement
/// <summary>
/// An enumerable and enumerator for the contents of a JSON array.
/// </summary>
[DebuggerDisplay("{Current,nq}")]
public struct ArrayEnumerator : IEnumerable<JsonElement>, IEnumerator<JsonElement>
{
private readonly JsonElement _target;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public partial struct JsonElement
/// <summary>
/// An enumerable and enumerator for the properties of a JSON object.
/// </summary>
[DebuggerDisplay("{Current,nq}")]
public struct ObjectEnumerator : IEnumerable<JsonProperty>, IEnumerator<JsonProperty>
{
private readonly JsonElement _target;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Buffers;
using System.Buffers.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace System.Text.Json
{
/// <summary>
/// Represents a specific JSON value within a <see cref="JsonDocument"/>.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public readonly partial struct JsonElement
{
private readonly JsonDocument _parent;
Expand Down Expand Up @@ -1286,5 +1283,7 @@ private void CheckValidInstance()
throw new InvalidOperationException();
}
}

private string DebuggerDisplay => $"Type = {Type} : \"{ToString()}\"";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;

namespace System.Text.Json
{
/// <summary>
/// Represents a single property for a JSON object.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public readonly struct JsonProperty
{
/// <summary>
Expand Down Expand Up @@ -99,5 +101,8 @@ public override string ToString()
{
return Value.GetPropertyRawText();
}

private string DebuggerDisplay
=> Value.Type == JsonValueType.Undefined ? "<Undefined>" : $"\"{ToString()}\"";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace System.Text.Json
/// To be able to set max depth while reading OR allow skipping comments, create an instance of
/// <see cref="JsonReaderState"/> and pass that in to the reader.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public ref partial struct Utf8JsonReader
{
private ReadOnlySpan<byte> _buffer;
Expand Down Expand Up @@ -2434,5 +2435,28 @@ private bool ConsumeMultiLineComment(ReadOnlySpan<byte> localBuffer, int previou
_tokenType = JsonTokenType.Comment;
return true;
}

private string DebuggerDisplay => $"TokenType = {DebugTokenType} (TokenStartIndex = {TokenStartIndex}) Consumed = {BytesConsumed}";

// Using TokenType.ToString() (or {TokenType}) fails to render in the debug window. The
// message "The runtime refused to evaluate the expression at this time." is shown. This
// is a workaround until we root cause and fix the issue.
private string DebugTokenType
=> TokenType switch
{
JsonTokenType.Comment => nameof(JsonTokenType.Comment),
JsonTokenType.EndArray => nameof(JsonTokenType.EndArray),
JsonTokenType.EndObject => nameof(JsonTokenType.EndObject),
JsonTokenType.False => nameof(JsonTokenType.False),
JsonTokenType.None => nameof(JsonTokenType.None),
JsonTokenType.Null => nameof(JsonTokenType.Null),
JsonTokenType.Number => nameof(JsonTokenType.Number),
JsonTokenType.PropertyName => nameof(JsonTokenType.PropertyName),
JsonTokenType.StartArray => nameof(JsonTokenType.StartArray),
JsonTokenType.StartObject => nameof(JsonTokenType.StartObject),
JsonTokenType.String => nameof(JsonTokenType.String),
JsonTokenType.True => nameof(JsonTokenType.True),
_ => ((byte)TokenType).ToString()
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace System.Text.Json
/// To be able to format the output with indentation and whitespace OR to skip validation, create an instance of
/// <see cref="JsonWriterOptions"/> and pass that in to the writer.
/// </remarks>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed partial class Utf8JsonWriter : IDisposable
#if BUILDING_INBOX_LIBRARY
, IAsyncDisposable
Expand Down Expand Up @@ -1091,5 +1092,7 @@ private void SetFlagToAddListSeparatorBeforeNextItem()
{
_currentDepth |= 1 << 31;
}

private string DebuggerDisplay => $"BytesCommitted = {BytesCommitted} BytesPending = {BytesPending} CurrentDepth = {CurrentDepth}";
}
}
42 changes: 42 additions & 0 deletions src/libraries/System.Text.Json/tests/DebuggerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Reflection;
using Xunit;

namespace System.Text.Json.Tests
{
public class DebuggerTests
{
[Fact]
public void DefaultJsonElement()
{
// Validating that we don't throw on default
JsonElement element = default;
GetDebuggerDisplayProperty(element);
}

[Fact]
public void DefaultJsonProperty()
{
// Validating that we don't throw on default
JsonProperty property = default;
GetDebuggerDisplayProperty(property);
}

[Fact]
public void DefaultUtf8JsonWriter()
{
// Validating that we don't throw on new object
Utf8JsonWriter writer = new Utf8JsonWriter(new MemoryStream());
GetDebuggerDisplayProperty(writer);
}

private static string GetDebuggerDisplayProperty<T>(T value)
{
return (string)typeof(T).GetProperty("DebuggerDisplay", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<Compile Include="BitStackTests.cs" />
<Compile Include="BufferFactory.cs" />
<Compile Include="BufferSegment.cs" />
<Compile Include="DebuggerTests.cs" />
<Compile Include="FixedSizedBufferWriter.cs" />
<Compile Include="InvalidBufferWriter.cs" />
<Compile Include="JsonDateTimeTestData.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void Verify()
Assert.IsType<JsonElement>(Object);
JsonElement jsonObject = (JsonElement)Object;
Assert.Equal(JsonValueType.Object, jsonObject.Type);
JsonProperty property = jsonObject.EnumerateObject().First();
JsonElement.ObjectEnumerator enumerator = jsonObject.EnumerateObject();
JsonProperty property = enumerator.First();
Assert.Equal("NestedArray", property.Name);
Assert.True(property.NameEquals("NestedArray"));
ValidateArray(property.Value);
Expand Down

0 comments on commit 82f07be

Please sign in to comment.