diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index e948c6abe0ebf7..e17c3d2bccc4f5 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -86,7 +86,8 @@ public static bool TryParse(string id, out DotnetObjectId objectId) case "methodId": { parts = id.Split(":"); - objectId.SubValue = int.Parse(parts[3]); + if (parts.Length > 3) + objectId.SubValue = int.Parse(parts[3]); break; } } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index f613922e6caec2..5189a0caeffc54 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -1542,6 +1542,9 @@ public async Task InvokeMethod(ArraySegment valueTypeBuffer, int public async Task InvokeMethodInObject(int objectId, int methodId, string varName, CancellationToken token) { + valueTypes.TryGetValue(objectId, out var valueType); + if (valueType != null) + return await InvokeMethod(valueType.valueTypeBuffer, methodId, varName, token); using var commandParamsObjWriter = new MonoBinaryWriter(); commandParamsObjWriter.Write(ElementType.Class, objectId); return await InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, varName, token); @@ -1569,7 +1572,7 @@ public async Task GetPropertyMethodIdByName(int typeId, string propertyName return -1; } - public async Task CreateJArrayForProperties(int typeId, ArraySegment object_buffer, JArray attributes, bool isAutoExpandable, string objectIdStr, bool isOwn, CancellationToken token) + public async Task CreateJArrayForProperties(int typeId, ElementType elementType, ArraySegment object_buffer, JArray attributes, bool isAutoExpandable, string objectIdStr, bool isOwn, CancellationToken token) { JArray ret = new JArray(); using var retDebuggerCmdReader = await GetTypePropertiesReader(typeId, token); @@ -1606,7 +1609,7 @@ public async Task CreateJArrayForProperties(int typeId, ArraySegment GetPropertiesValuesOfValueType(int valueTypeId, Cancel } for (int i = 0 ; i < typesToGetProperties.Count; i++) { - var properties = await CreateJArrayForProperties(typesToGetProperties[i], valueType.valueTypeBuffer, valueType.valueTypeJson, valueType.valueTypeAutoExpand, $"dotnet:valuetype:{valueType.Id}", i == 0, token); + var properties = await CreateJArrayForProperties(typesToGetProperties[i], ElementType.ValueType, valueType.valueTypeBuffer, valueType.valueTypeJson, valueType.valueTypeAutoExpand, $"dotnet:valuetype:{valueType.Id}", i == 0, token); ret = new JArray(ret.Union(properties)); } @@ -2375,6 +2378,7 @@ public async Task GetObjectValues(int objectId, GetObjectCommandOptions commandParamsObjWriter.WriteObj(new DotnetObjectId("object", objectId), this); var props = await CreateJArrayForProperties( typeId, + ElementType.Class, commandParamsObjWriter.GetParameterBuffer(), new JArray(objects.Values), getCommandType.HasFlag(GetObjectCommandOptions.ForDebuggerProxyAttribute), diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 0b199cfc6183e5..c38596af1e5c69 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -1016,6 +1016,28 @@ public async Task EvaluateProtectionLevels() => await CheckInspectLocalsAtBreak Assert.Equal(internalAndProtected[1]["value"]["value"], "protected"); Assert.Equal(priv[0]["value"]["value"], "private"); }); + + [Fact] + public async Task StructureGetters() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.StructureGetters", "Evaluate", 2, "Evaluate", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.StructureGetters:Evaluate'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + var (obj, _) = await EvaluateOnCallFrame(id, "s"); + var props = await GetProperties(obj["objectId"]?.Value()); + + await CheckProps(props, new + { + Id = TGetter("Id", TNumber(123)) + }, "s#1"); + + var getter = props.FirstOrDefault(p => p["name"]?.Value() == "Id"); + Assert.NotNull(getter); + var getterId = getter["get"]["objectId"]?.Value(); + var getterProps = await GetProperties(getterId); + Assert.Equal(getterProps[0]?["value"]?["value"]?.Value(), 123); + }); } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index 1eac05cf41c1c8..aa6572af2c23ba 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -838,6 +838,19 @@ public static void Evaluate() var testClass = new TestClass(); } } + + public static class StructureGetters + { + public struct Point + { + public int Id { get { return 123; } } + } + + public static void Evaluate() + { + var s = new Point(); + } + } } namespace DebuggerTestsV2