Skip to content
Next Next commit
Keep underscore removable properties as constants.
  • Loading branch information
ilonatommy committed Sep 29, 2022
commit 93911d9ee91ecdd0a9ea867c8b82c140f9c39433
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@

using System;
using Newtonsoft.Json.Linq;
using BrowserDebugProxy;
using System.Collections.Generic;

namespace Microsoft.WebAssembly.Diagnostics;

internal static class HelperExtensions
{
private const int MaxLogMessageLineLength = 65536;
private static readonly bool TruncateLogMessages = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WASM_DONT_TRUNCATE_LOG_MESSAGES"));
private static Dictionary<ProxyInternalUseProperty, string> proxyInternalUsePropNames = new Dictionary<ProxyInternalUseProperty, string>() {
{ ProxyInternalUseProperty.Hidden, "__hidden" },
{ ProxyInternalUseProperty.State, "__state" },
{ ProxyInternalUseProperty.Section, "__section" },
{ ProxyInternalUseProperty.Owner, "__owner" },
{ ProxyInternalUseProperty.IsStatic, "__isStatic" },
{ ProxyInternalUseProperty.IsNewSlot, "__isNewSlot" },
{ ProxyInternalUseProperty.IsBackingField, "__isBackingField" },
{ ProxyInternalUseProperty.ParentTypeId, "__parentTypeId" }
};

public static string Truncate(this string message, int maxLen, string suffix = "")

Expand All @@ -29,6 +41,8 @@ public static void AddRange(this JArray arr, JArray addedArr)
arr.Add(item);
}

public static string ToUnderscoredString(this ProxyInternalUseProperty val) => proxyInternalUsePropNames[val];

public static bool IsNullValuedObject(this JObject obj)
=> obj != null && obj["type"]?.Value<string>() == "object" && obj["subtype"]?.Value<string>() == "null";
}
52 changes: 32 additions & 20 deletions src/mono/wasm/debugger/BrowserDebugProxy/MemberObjectsExplorer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,21 @@ private static async Task<JObject> ReadFieldValue(
// for backing fields, we are getting it from the properties
typePropertiesBrowsableInfo.TryGetValue(field.Name, out state);
}
fieldValue["__state"] = state?.ToString();
fieldValue[ProxyInternalUseProperty.State.ToUnderscoredString()] = state?.ToString();

fieldValue["__section"] = field.Attributes switch
fieldValue[ProxyInternalUseProperty.Section.ToUnderscoredString()] = field.Attributes switch
{
FieldAttributes.Private => "private",
_ => "result"
};

if (field.IsBackingField)
{
fieldValue["__isBackingField"] = true;
fieldValue["__parentTypeId"] = parentTypeId;
fieldValue[ProxyInternalUseProperty.IsBackingField.ToUnderscoredString()] = true;
fieldValue[ProxyInternalUseProperty.ParentTypeId.ToUnderscoredString()] = parentTypeId;
}
if (field.Attributes.HasFlag(FieldAttributes.Static))
fieldValue["__isStatic"] = true;
fieldValue[ProxyInternalUseProperty.IsStatic.ToUnderscoredString()] = true;

if (getObjectOptions.HasFlag(GetObjectCommandOptions.WithSetter))
{
Expand Down Expand Up @@ -365,14 +365,14 @@ public static async Task<Dictionary<string, JObject>> ExpandPropertyValues(
continue;
}

bool isExistingMemberABackingField = existingMember["__isBackingField"]?.Value<bool>() == true;
bool isExistingMemberABackingField = existingMember[ProxyInternalUseProperty.IsBackingField.ToUnderscoredString()]?.Value<bool>() == true;
if (isOwn && !isExistingMemberABackingField)
{
// repeated propname on the same type! cannot happen
throw new Exception($"Internal Error: should not happen. propName: {propName}. Existing all members: {string.Join(",", allMembers.Keys)}");
}

bool isExistingMemberABackingFieldOwnedByThisType = isExistingMemberABackingField && existingMember["__owner"]?.Value<string>() == typeName;
bool isExistingMemberABackingFieldOwnedByThisType = isExistingMemberABackingField && existingMember[ProxyInternalUseProperty.Owner.ToUnderscoredString()]?.Value<string>() == typeName;
if (isExistingMemberABackingField && (isOwn || isExistingMemberABackingFieldOwnedByThisType))
{
// this is the property corresponding to the backing field in *this* type
Expand All @@ -386,8 +386,8 @@ public static async Task<Dictionary<string, JObject>> ExpandPropertyValues(
{
// this has `new` keyword if it is newSlot but direct child was not a newSlot:
var child = allMembers.FirstOrDefault(
kvp => (kvp.Key == propName || kvp.Key.StartsWith($"{propName} (")) && kvp.Value["__parentTypeId"]?.Value<int>() == typeId).Value;
bool wasOverriddenByDerivedType = child != null && child["__isNewSlot"]?.Value<bool>() != true;
kvp => (kvp.Key == propName || kvp.Key.StartsWith($"{propName} (")) && kvp.Value[ProxyInternalUseProperty.ParentTypeId.ToUnderscoredString()]?.Value<int>() == typeId).Value;
bool wasOverriddenByDerivedType = child != null && child[ProxyInternalUseProperty.IsNewSlot.ToUnderscoredString()]?.Value<bool>() != true;
if (wasOverriddenByDerivedType)
{
/*
Expand All @@ -413,7 +413,7 @@ public static async Task<Dictionary<string, JObject>> ExpandPropertyValues(
*/

JObject backingFieldForHiddenProp = allMembers.GetValueOrDefault(overriddenOrHiddenPropName);
if (backingFieldForHiddenProp is null || backingFieldForHiddenProp["__isBackingField"]?.Value<bool>() != true)
if (backingFieldForHiddenProp is null || backingFieldForHiddenProp[ProxyInternalUseProperty.IsBackingField.ToUnderscoredString()]?.Value<bool>() != true)
{
// hiding with a non-auto property, so nothing to adjust
// add the new property
Expand All @@ -433,7 +433,7 @@ async Task UpdateBackingFieldWithPropertyAttributes(JObject backingField, string
MethodAttributes.Private => "private",
_ => "result"
};
backingField["__state"] = state?.ToString();
backingField[ProxyInternalUseProperty.State.ToUnderscoredString()] = state?.ToString();

if (state is null)
return;
Expand Down Expand Up @@ -476,16 +476,16 @@ async Task AddProperty(
}

propRet["isOwn"] = isOwn;
propRet["__section"] = getterAttrs switch
propRet[ProxyInternalUseProperty.Section.ToUnderscoredString()] = getterAttrs switch
{
MethodAttributes.Private => "private",
_ => "result"
};
propRet["__state"] = state?.ToString();
propRet[ProxyInternalUseProperty.State.ToUnderscoredString()] = state?.ToString();
if (parentTypeId != -1)
{
propRet["__parentTypeId"] = parentTypeId;
propRet["__isNewSlot"] = isNewSlot;
propRet[ProxyInternalUseProperty.ParentTypeId.ToUnderscoredString()] = parentTypeId;
propRet[ProxyInternalUseProperty.IsNewSlot.ToUnderscoredString()] = isNewSlot;
}

string namePrefix = GetNamePrefixForValues(propNameWithSufix, typeName, isOwn, state);
Expand Down Expand Up @@ -590,7 +590,7 @@ public static async Task<GetMembersResult> GetObjectMemberValues(
if (getCommandType.HasFlag(GetObjectCommandOptions.AccessorPropertiesOnly))
{
foreach (var f in allFields)
f["__hidden"] = true;
f[ProxyInternalUseProperty.Hidden.ToUnderscoredString()] = true;
}
AddOnlyNewFieldValuesByNameTo(allFields, allMembers, typeName, isOwn);
}
Expand Down Expand Up @@ -636,8 +636,8 @@ static void AddOnlyNewFieldValuesByNameTo(JArray namedValues, IDictionary<string
if (valuesDict.TryAdd(name, item as JObject))
{
// new member
if (item["__isBackingField"]?.Value<bool>() == true)
item["__owner"] = typeName;
if (item[ProxyInternalUseProperty.IsBackingField.ToUnderscoredString()]?.Value<bool>() == true)
item[ProxyInternalUseProperty.Owner.ToUnderscoredString()] = typeName;
continue;
}

Expand All @@ -654,6 +654,18 @@ static void AddOnlyNewFieldValuesByNameTo(JArray namedValues, IDictionary<string

}

public enum ProxyInternalUseProperty
{
Hidden,
State,
Section,
Owner,
IsStatic,
IsNewSlot,
IsBackingField,
ParentTypeId
}

internal sealed class GetMembersResult
{
// public / protected / internal:
Expand Down Expand Up @@ -698,10 +710,10 @@ public static GetMembersResult FromValues(JArray values, bool splitMembersByAcce

private void Split(JToken member)
{
if (member["__hidden"]?.Value<bool>() == true)
if (member[ProxyInternalUseProperty.Hidden.ToUnderscoredString()]?.Value<bool>() == true)
return;

if (member["__section"]?.Value<string>() is not string section)
if (member[ProxyInternalUseProperty.Section.ToUnderscoredString()]?.Value<string>() is not string section)
{
Result.Add(member);
return;
Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ internal async Task<ValueOrError<GetMembersResult>> RuntimeGetObjectMembers(Sess
case "object":
var resObj = await MemberObjectsExplorer.GetObjectMemberValues(
context.SdbAgent, objectId.Value, getObjectOptions, token, sortByAccessLevel, includeStatic: true);
// cleanUp underscores
return ValueOrError<GetMembersResult>.WithValue(resObj);
case "pointer":
var resPointer = new JArray { await context.SdbAgent.GetPointerContent(objectId.Value, token) };
Expand Down
6 changes: 3 additions & 3 deletions src/mono/wasm/debugger/BrowserDebugProxy/ValueTypeClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ JObject GetFieldWithMetadata(FieldTypeClass field, JObject fieldValue, bool isSt
if (isStatic)
fieldValue["name"] = field.Name;
FieldAttributes attr = field.Attributes & FieldAttributes.FieldAccessMask;
fieldValue["__section"] = attr == FieldAttributes.Private ? "private" : "result";
fieldValue[ProxyInternalUseProperty.Section.ToUnderscoredString()] = attr == FieldAttributes.Private ? "private" : "result";

if (field.IsBackingField)
{
fieldValue["__isBackingField"] = true;
fieldValue[ProxyInternalUseProperty.IsBackingField.ToUnderscoredString()] = true;
return fieldValue;
}
typeFieldsBrowsableInfo.TryGetValue(field.Name, out DebuggerBrowsableState? state);
fieldValue["__state"] = state?.ToString();
fieldValue[ProxyInternalUseProperty.State.ToUnderscoredString()] = state?.ToString();
return fieldValue;
}
}
Expand Down