From fab24e5388c11147b2baa1bdf080e76eb1d13464 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 5 Nov 2021 11:57:05 +0100 Subject: [PATCH 01/23] Using current namespace as the default place to serach for the resolved class. --- .../debugger/BrowserDebugProxy/DebugStore.cs | 2 + .../MemberReferenceResolver.cs | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index 9fe5205394e24..4174dedc5290b 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -331,6 +331,7 @@ internal class MethodInfo public bool IsStatic() => (methodDef.Attributes & MethodAttributes.Static) != 0; public int IsAsync { get; set; } public bool IsHiddenFromDebugger { get; } + public TypeInfo TypeInfo { get; } public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, int token, SourceFile source, TypeInfo type, MetadataReader asmMetadataReader, MetadataReader pdbMetadataReader) { this.IsAsync = -1; @@ -343,6 +344,7 @@ public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, this.Name = asmMetadataReader.GetString(methodDef.Name); this.pdbMetadataReader = pdbMetadataReader; this.IsEnCMethod = false; + this.TypeInfo = type; if (!DebugInformation.SequencePointsBlob.IsNil) { var sps = DebugInformation.GetSequencePoints(); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 5c7b4d3d1405f..488b6da3175c2 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -119,12 +119,44 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } } var store = await proxy.LoadStore(sessionId, token); + + // first - check the current assembly + var currentFrame = ctx.CallStack.FirstOrDefault(); + var currentAssembly = currentFrame.Method.Info.TypeInfo.assembly; + string namespaceName = currentAssembly.Name; + + // remove .dll from the end + if (namespaceName.Length > 4) + namespaceName = currentAssembly.Name.Remove(currentAssembly.Name.Length - 4); + + // look for classes in the current namespace + var matchingType = currentAssembly.TypesByName.Keys + .Where(k => k == string.Join(".", new string[] { namespaceName, classNameToFind })) + .Select(t => currentAssembly.GetTypeByName(t)) + .FirstOrDefault(); + + // if not found, look in all namespaces in the current assembly + if (matchingType == null) + { + matchingType = currentAssembly.TypesByName.Keys + .Where(k => k == classNameToFind) + .Select(t => currentAssembly.GetTypeByName(t)) + .FirstOrDefault(); + } + if (matchingType != null) + { + typeId = await sdbHelper.GetTypeIdFromToken(sessionId, currentAssembly.DebugId, matchingType.Token, token); + continue; + } + + // if not found in the current assembly, look in the other assemblies foreach (var asm in store.assemblies) { var type = asm.GetTypeByName(classNameToFind); if (type != null) { typeId = await sdbHelper.GetTypeIdFromToken(sessionId, asm.DebugId, type.Token, token); + break; } } } @@ -201,6 +233,11 @@ public async Task Resolve(string varName, CancellationToken token) } } } + else if (rootObject == null) + { + rootObject = await TryToRunOnLoadedClasses(varName, token); + return rootObject; + } } scopeCache.MemberReferences[varName] = rootObject; return rootObject; From 66b56a792d4a60d012857c66377e5987c8721a34 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 5 Nov 2021 15:59:56 +0100 Subject: [PATCH 02/23] Add tests for static class, static fields and pausing in async method. --- .../EvaluateOnCallFrameTests.cs | 65 ++++++++++++++++++- .../debugger-test/debugger-evaluate-test.cs | 23 +++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 524ff68fb9e2d..4c0f24350e499 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -36,6 +36,11 @@ public static IEnumerable InstanceMethodForTypeMembersTestData(string } } + public static IEnumerable EvaluateStaticClassFromAsyncMethodTestData(string type_name) + { + yield return new object[] { type_name, "EvaluateAsyncMethods", "EvaluateAsyncMethods", true }; + } + [Theory] [MemberData(nameof(InstanceMethodForTypeMembersTestData), parameters: "DebuggerTests.EvaluateTestsStructWithProperties")] [MemberData(nameof(InstanceMethodForTypeMembersTestData), parameters: "DebuggerTests.EvaluateTestsClassWithProperties")] @@ -695,6 +700,62 @@ await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); + [Fact] + public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateMethodTestsClass", "EvaluateMethods", 1, "EvaluateMethods", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateMethods'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + + var frame = pause_location["callFrames"][0]; + + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + }); + + [Theory] + [MemberData(nameof(EvaluateStaticClassFromAsyncMethodTestData), parameters: "DebuggerTests.EvaluateMethodTestsClass")] + public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, string bp_function_name, bool is_async) + => await CheckInspectLocalsAtBreakpointSite( + type, method, 1, bp_function_name, + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateAsyncMethods'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + + var frame = pause_location["callFrames"][0]; + + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + }); + + [Fact] + public async Task EvaluateNonStaticClassWithStaticFields() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateMethodTestsClass/TestEvaluate", "run", 9, "run", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateMethods'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + + var frame = pause_location["callFrames"][0]; + + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); + }); + [Fact] public async Task EvaluateStaticClassInvalidField() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.EvaluateMethodTestsClass/TestEvaluate", "run", 9, "run", @@ -712,8 +773,8 @@ public async Task EvaluateStaticClassInvalidField() => await CheckInspectLocalsA AssertEqual("Failed to resolve member access for DebuggerTests.InvalidEvaluateStaticClass.StaticProperty2", res.Error["result"]?["description"]?.Value(), "wrong error message"); }); - [Fact] - public async Task AsyncLocalsInContinueWithBlock() => await CheckInspectLocalsAtBreakpointSite( + [Fact] + public async Task AsyncLocalsInContinueWithBlock() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.AsyncTests.ContinueWithTests", "ContinueWithStaticAsync", 4, "b__3_0", "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", wait_for_event_fn: async (pause_location) => 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 74153fa379376..0eb950705352b 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 @@ -405,6 +405,12 @@ public static void EvaluateMethods() f.run(100, 200, "9000", "test", 45); } + public static void EvaluateAsyncMethods() + { + var staticClass = new EvaluateNonStaticClassWithStaticFields(); + staticClass.run(); + } + } public static class EvaluateStaticClass @@ -414,6 +420,23 @@ public static class EvaluateStaticClass public static string StaticPropertyWithError => throw new Exception("not implemented"); } + public class EvaluateNonStaticClassWithStaticFields + { + public static int StaticField1 = 10; + public static string StaticProperty1 => "StaticProperty1"; + public static string StaticPropertyWithError => throw new Exception("not implemented"); + + private int HelperMethod() + { + return 5; + } + + public async void run() + { + var makeAwaitable = await Task.Run(() => HelperMethod()); + } + } + public class EvaluateLocalsWithElementAccessTests { public class TestEvaluate From 782a10748d1cc893e597faf3d71a1f0922c188f2 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 8 Nov 2021 17:08:07 +0100 Subject: [PATCH 03/23] Added tests for class evaluation. --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 4c0f24350e499..bae52df2adeff 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -692,6 +692,7 @@ public async Task EvaluateStaticClass() => await CheckInspectLocalsAtBreakpointS var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -710,6 +711,7 @@ public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLoc var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -730,6 +732,7 @@ public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -748,6 +751,7 @@ public async Task EvaluateNonStaticClassWithStaticFields() => await CheckInspect var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateNonStaticClassWithStaticFields", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, From 4119de3829ade4c8d9a296316b57ab07f4b8a3cc Mon Sep 17 00:00:00 2001 From: "DESKTOP-GEPIA6N\\Thays" Date: Mon, 8 Nov 2021 17:29:52 -0300 Subject: [PATCH 04/23] Fixing support to the current namespace and adding tests for it --- .../debugger/BrowserDebugProxy/DebugStore.cs | 16 ++++---- .../MemberReferenceResolver.cs | 37 +++---------------- .../EvaluateOnCallFrameTests.cs | 18 +++++++++ 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index 4174dedc5290b..a90722814f824 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -477,7 +477,7 @@ internal class TypeInfo private TypeDefinition type; private List methods; internal int Token { get; } - + internal string Namespace { get; } public TypeInfo(AssemblyInfo assembly, TypeDefinitionHandle typeHandle, TypeDefinition type) { this.assembly = assembly; @@ -486,21 +486,21 @@ public TypeInfo(AssemblyInfo assembly, TypeDefinitionHandle typeHandle, TypeDefi this.type = type; methods = new List(); Name = metadataReader.GetString(type.Name); - var namespaceName = ""; + Namespace = ""; if (type.IsNested) { var declaringType = metadataReader.GetTypeDefinition(type.GetDeclaringType()); Name = metadataReader.GetString(declaringType.Name) + "/" + Name; - namespaceName = metadataReader.GetString(declaringType.Namespace); + Namespace = metadataReader.GetString(declaringType.Namespace); } else { - namespaceName = metadataReader.GetString(type.Namespace); + Namespace = metadataReader.GetString(type.Namespace); } - - if (namespaceName.Length > 0) - namespaceName += "."; - FullName = namespaceName + Name; + if (Namespace.Length > 0) + FullName = Namespace + "." + Name; + else + FullName = Name; } public TypeInfo(AssemblyInfo assembly, string name) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 488b6da3175c2..1046b97afeb81 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -119,40 +119,15 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } } var store = await proxy.LoadStore(sessionId, token); - - // first - check the current assembly - var currentFrame = ctx.CallStack.FirstOrDefault(); - var currentAssembly = currentFrame.Method.Info.TypeInfo.assembly; - string namespaceName = currentAssembly.Name; - - // remove .dll from the end - if (namespaceName.Length > 4) - namespaceName = currentAssembly.Name.Remove(currentAssembly.Name.Length - 4); - - // look for classes in the current namespace - var matchingType = currentAssembly.TypesByName.Keys - .Where(k => k == string.Join(".", new string[] { namespaceName, classNameToFind })) - .Select(t => currentAssembly.GetTypeByName(t)) - .FirstOrDefault(); - - // if not found, look in all namespaces in the current assembly - if (matchingType == null) - { - matchingType = currentAssembly.TypesByName.Keys - .Where(k => k == classNameToFind) - .Select(t => currentAssembly.GetTypeByName(t)) - .FirstOrDefault(); - } - if (matchingType != null) - { - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, currentAssembly.DebugId, matchingType.Token, token); - continue; - } - - // if not found in the current assembly, look in the other assemblies foreach (var asm in store.assemblies) { var type = asm.GetTypeByName(classNameToFind); + if (type == null) //search in the current namespace + { + var namespaceName = ctx.CallStack.FirstOrDefault().Method.Info.TypeInfo.Namespace; + var classNameToFindWithNamespace = namespaceName + "." + classNameToFind; + type = asm.GetTypeByName(classNameToFindWithNamespace); + } if (type != null) { typeId = await sdbHelper.GetTypeIdFromToken(sessionId, asm.DebugId, type.Token, token); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 4c0f24350e499..b2b5618799f7f 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -710,6 +710,12 @@ public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLoc var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -730,6 +736,12 @@ public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, var frame = pause_location["callFrames"][0]; + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -754,6 +766,12 @@ await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1"))); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1"))); + await EvaluateOnCallFrameAndCheck(id, + ("EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); [Fact] From ee19014c8aec41521c2e69769fd4fc271a4dae33 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 9 Nov 2021 13:52:44 +0100 Subject: [PATCH 05/23] Assuing that we search within the current assembly first. Removed tests that fail in Consol App. --- .../MemberReferenceResolver.cs | 18 +++++++++++------- .../EvaluateOnCallFrameTests.cs | 11 +++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 1046b97afeb81..6cd8184ffcdf4 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -119,15 +119,19 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } } var store = await proxy.LoadStore(sessionId, token); + var info = ctx.CallStack.FirstOrDefault().Method.Info; + var currentAssembly = info.Assembly; + var namespaceName = info.TypeInfo.Namespace; + var classNameToFindWithNamespace = namespaceName + "." + classNameToFind; + var type = currentAssembly.GetTypeByName(classNameToFindWithNamespace); + if (type != null) + { + typeId = await sdbHelper.GetTypeIdFromToken(sessionId, currentAssembly.DebugId, type.Token, token); + continue; + } foreach (var asm in store.assemblies) { - var type = asm.GetTypeByName(classNameToFind); - if (type == null) //search in the current namespace - { - var namespaceName = ctx.CallStack.FirstOrDefault().Method.Info.TypeInfo.Namespace; - var classNameToFindWithNamespace = namespaceName + "." + classNameToFind; - type = asm.GetTypeByName(classNameToFindWithNamespace); - } + type = asm.GetTypeByName(classNameToFind); if (type != null) { typeId = await sdbHelper.GetTypeIdFromToken(sessionId, asm.DebugId, type.Token, token); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index e51acbc85426e..b6cc12cf8343b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -692,7 +692,6 @@ public async Task EvaluateStaticClass() => await CheckInspectLocalsAtBreakpointS var frame = pause_location["callFrames"][0]; - await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -711,7 +710,6 @@ public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLoc var frame = pause_location["callFrames"][0]; - await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -738,7 +736,6 @@ public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, var frame = pause_location["callFrames"][0]; - await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateStaticClass", expect_ok: true); await EvaluateOnCallFrameAndCheck(id, ("EvaluateStaticClass.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, @@ -755,15 +752,17 @@ await EvaluateOnCallFrameAndCheck(id, [Fact] public async Task EvaluateNonStaticClassWithStaticFields() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateMethodTestsClass/TestEvaluate", "run", 9, "run", - "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateMethods'); })", + "DebuggerTests.EvaluateMethodTestsClass", "EvaluateAsyncMethods", 3, "EvaluateAsyncMethods", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateAsyncMethods'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); var frame = pause_location["callFrames"][0]; - await EvaluateOnCallFrame(id, "DebuggerTests.EvaluateNonStaticClassWithStaticFields", expect_ok: true); + await EvaluateOnCallFrame(id, "staticClass", expect_ok: true); + await EvaluateOnCallFrameAndCheck(id, + ("staticClass", TObject("DebuggerTests.EvaluateNonStaticClassWithStaticFields", is_null: false))); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, From 89bdc490b858d0fda64e6278fd2159c45d381859 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 9 Nov 2021 15:00:56 +0100 Subject: [PATCH 06/23] Remove a test-duplicate that was not testing static class or static fields. --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index b6cc12cf8343b..9ca68ebfe0a45 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -760,9 +760,6 @@ public async Task EvaluateNonStaticClassWithStaticFields() => await CheckInspect var frame = pause_location["callFrames"][0]; - await EvaluateOnCallFrame(id, "staticClass", expect_ok: true); - await EvaluateOnCallFrameAndCheck(id, - ("staticClass", TObject("DebuggerTests.EvaluateNonStaticClassWithStaticFields", is_null: false))); await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); await EvaluateOnCallFrameAndCheck(id, From 5ce0f57bb5c548a3411071582095066e8b0cce07 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 9 Nov 2021 15:06:41 +0100 Subject: [PATCH 07/23] Fixing indentation. --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 4 ++-- .../debugger/tests/debugger-test/debugger-evaluate-test.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 9ca68ebfe0a45..4b92beab381ef 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -791,8 +791,8 @@ public async Task EvaluateStaticClassInvalidField() => await CheckInspectLocalsA AssertEqual("Failed to resolve member access for DebuggerTests.InvalidEvaluateStaticClass.StaticProperty2", res.Error["result"]?["description"]?.Value(), "wrong error message"); }); - [Fact] - public async Task AsyncLocalsInContinueWithBlock() => await CheckInspectLocalsAtBreakpointSite( + [Fact] + public async Task AsyncLocalsInContinueWithBlock() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.AsyncTests.ContinueWithTests", "ContinueWithStaticAsync", 4, "b__3_0", "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", wait_for_event_fn: async (pause_location) => 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 0eb950705352b..a065cc9b9a2ff 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 @@ -424,7 +424,7 @@ public class EvaluateNonStaticClassWithStaticFields { public static int StaticField1 = 10; public static string StaticProperty1 => "StaticProperty1"; - public static string StaticPropertyWithError => throw new Exception("not implemented"); + public static string StaticPropertyWithError => throw new Exception("not implemented"); private int HelperMethod() { From 62d18b692a71307c0978867cc6d450b0ad9d0bc3 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 9 Nov 2021 15:10:02 +0100 Subject: [PATCH 08/23] Refixing indentation. --- .../wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a065cc9b9a2ff..c44e5b85688fc 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 @@ -424,7 +424,7 @@ public class EvaluateNonStaticClassWithStaticFields { public static int StaticField1 = 10; public static string StaticProperty1 => "StaticProperty1"; - public static string StaticPropertyWithError => throw new Exception("not implemented"); + public static string StaticPropertyWithError => throw new Exception("not implemented"); private int HelperMethod() { From ce177fd44c33651f477d4e594edb17d97ee32f3b Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 9 Nov 2021 15:24:29 +0100 Subject: [PATCH 09/23] Refix indentations again. --- .../debugger/tests/debugger-test/debugger-evaluate-test.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 c44e5b85688fc..a00b131060478 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 @@ -427,9 +427,9 @@ public class EvaluateNonStaticClassWithStaticFields public static string StaticPropertyWithError => throw new Exception("not implemented"); private int HelperMethod() - { - return 5; - } + { + return 5; + } public async void run() { From cb324022860c70e22e71f69422121fd3534594d3 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Wed, 10 Nov 2021 14:33:21 +0100 Subject: [PATCH 10/23] Applied the advice about adding new blank lines. --- src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index a90722814f824..6ca97d9c4785f 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -332,6 +332,7 @@ internal class MethodInfo public int IsAsync { get; set; } public bool IsHiddenFromDebugger { get; } public TypeInfo TypeInfo { get; } + public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, int token, SourceFile source, TypeInfo type, MetadataReader asmMetadataReader, MetadataReader pdbMetadataReader) { this.IsAsync = -1; @@ -478,6 +479,7 @@ internal class TypeInfo private List methods; internal int Token { get; } internal string Namespace { get; } + public TypeInfo(AssemblyInfo assembly, TypeDefinitionHandle typeHandle, TypeDefinition type) { this.assembly = assembly; @@ -486,7 +488,6 @@ public TypeInfo(AssemblyInfo assembly, TypeDefinitionHandle typeHandle, TypeDefi this.type = type; methods = new List(); Name = metadataReader.GetString(type.Name); - Namespace = ""; if (type.IsNested) { var declaringType = metadataReader.GetTypeDefinition(type.GetDeclaringType()); From ed2577eab1da2c87a867bc52a260adf99b9903ad Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Wed, 10 Nov 2021 16:34:18 +0100 Subject: [PATCH 11/23] Changed the current assembly check. --- .../BrowserDebugProxy/MemberReferenceResolver.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 6cd8184ffcdf4..4d1a702546d58 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -120,21 +120,20 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } var store = await proxy.LoadStore(sessionId, token); var info = ctx.CallStack.FirstOrDefault().Method.Info; - var currentAssembly = info.Assembly; - var namespaceName = info.TypeInfo.Namespace; - var classNameToFindWithNamespace = namespaceName + "." + classNameToFind; - var type = currentAssembly.GetTypeByName(classNameToFindWithNamespace); + var namespaceName = string.IsNullOrEmpty(info.TypeInfo.Namespace) ? classNameToFind : info.TypeInfo.Namespace + "." + classNameToFind; + var type = info.Assembly.GetTypeByName(namespaceName); if (type != null) { - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, currentAssembly.DebugId, type.Token, token); + typeId = await sdbHelper.GetTypeIdFromToken(sessionId, info.Assembly.DebugId, type.Token, token); continue; } + foreach (var asm in store.assemblies) { type = asm.GetTypeByName(classNameToFind); if (type != null) { - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, asm.DebugId, type.Token, token); + typeId = await sdbHelper.GetTypeIdFromToken(sessionId, info.Assembly.DebugId, type.Token, token); break; } } From 01f46d5b7aa7b7b2e9dc721d26d0fd815ff5d110 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Wed, 10 Nov 2021 17:02:54 +0100 Subject: [PATCH 12/23] Extracting the check from the loop. One time check is enough. --- .../BrowserDebugProxy/MemberReferenceResolver.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 4d1a702546d58..64a1bdf386fb3 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -211,11 +211,11 @@ public async Task Resolve(string varName, CancellationToken token) } } } - else if (rootObject == null) - { - rootObject = await TryToRunOnLoadedClasses(varName, token); - return rootObject; - } + } + if (rootObject == null) + { + rootObject = await TryToRunOnLoadedClasses(varName, token); + return rootObject; } scopeCache.MemberReferences[varName] = rootObject; return rootObject; From d14367d206d6ea14ffa9ff5794bdd10836784358 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Wed, 10 Nov 2021 17:03:28 +0100 Subject: [PATCH 13/23] Simplifying multiple test cases into one call. --- .../EvaluateOnCallFrameTests.cs | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 4b92beab381ef..fa2fa1c28b3f2 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -711,16 +711,10 @@ public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLoc var frame = pause_location["callFrames"][0]; await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented")), + ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10)), + ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); @@ -737,16 +731,11 @@ public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, var frame = pause_location["callFrames"][0]; await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticField1", TNumber(10)), + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented")), + ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10)), + ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); @@ -761,16 +750,11 @@ public async Task EvaluateNonStaticClassWithStaticFields() => await CheckInspect var frame = pause_location["callFrames"][0]; await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, - ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10))); - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1"))); - await EvaluateOnCallFrameAndCheck(id, + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10)), + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1")), + ("DebuggerTests.EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented")), + ("EvaluateNonStaticClassWithStaticFields.StaticField1", TNumber(10)), + ("EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1")), ("EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); From 8a823808b901a1d57038ef555f2d811d60b242ea Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Thu, 11 Nov 2021 10:05:30 +0100 Subject: [PATCH 14/23] Using local function as per review suggestion. --- .../MemberReferenceResolver.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 64a1bdf386fb3..406a9246696b1 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -120,22 +120,24 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } var store = await proxy.LoadStore(sessionId, token); var info = ctx.CallStack.FirstOrDefault().Method.Info; - var namespaceName = string.IsNullOrEmpty(info.TypeInfo.Namespace) ? classNameToFind : info.TypeInfo.Namespace + "." + classNameToFind; - var type = info.Assembly.GetTypeByName(namespaceName); - if (type != null) - { - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, info.Assembly.DebugId, type.Token, token); + var classNameToFindWithNamespace = string.IsNullOrEmpty(info.TypeInfo.Namespace) ? classNameToFind : info.TypeInfo.Namespace + "." + classNameToFind; + if (await TryGetTypeIdFromName(classNameToFindWithNamespace, info.Assembly)) continue; - } foreach (var asm in store.assemblies) { - type = asm.GetTypeByName(classNameToFind); - if (type != null) - { - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, info.Assembly.DebugId, type.Token, token); + if (await TryGetTypeIdFromName(classNameToFind, asm)) break; - } + } + + async Task TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) + { + var type = assembly.GetTypeByName(typeName); + if (type == null) + return false; + + typeId = await sdbHelper.GetTypeIdFromToken(sessionId, assembly.DebugId, type.Token, token); + return true; } } return null; From 7f24d478be8128e523b11fad642cb1458b3abc1c Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Thu, 11 Nov 2021 10:13:42 +0100 Subject: [PATCH 15/23] Added test that was skipped by mistake. --- .../wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index fa2fa1c28b3f2..d13cff819953c 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -711,6 +711,7 @@ public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLoc var frame = pause_location["callFrames"][0]; await EvaluateOnCallFrameAndCheck(id, + ("EvaluateStaticClass.StaticField1", TNumber(10)), ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented")), ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10)), From 367c4312fb06b1c62d0fe02b09ed6d584e864f09 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Thu, 11 Nov 2021 10:15:59 +0100 Subject: [PATCH 16/23] Added looking for the namespace in all assemblies because there is a chance it will be located out of the current assembly. --- .../debugger/BrowserDebugProxy/MemberReferenceResolver.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 406a9246696b1..df7520cfec2fd 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -121,13 +121,13 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT var store = await proxy.LoadStore(sessionId, token); var info = ctx.CallStack.FirstOrDefault().Method.Info; var classNameToFindWithNamespace = string.IsNullOrEmpty(info.TypeInfo.Namespace) ? classNameToFind : info.TypeInfo.Namespace + "." + classNameToFind; - if (await TryGetTypeIdFromName(classNameToFindWithNamespace, info.Assembly)) - continue; foreach (var asm in store.assemblies) { if (await TryGetTypeIdFromName(classNameToFind, asm)) break; + if (await TryGetTypeIdFromName(classNameToFindWithNamespace, asm)) + break; } async Task TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) From 55479c8e3a8a3739baef104f99705b506b07de97 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Thu, 11 Nov 2021 11:17:37 +0100 Subject: [PATCH 17/23] Extracting value based on the current frame, not the top of stack location. --- .../BrowserDebugProxy/MemberReferenceResolver.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index df7520cfec2fd..beb2903c360d8 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -119,15 +119,18 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } } var store = await proxy.LoadStore(sessionId, token); - var info = ctx.CallStack.FirstOrDefault().Method.Info; - var classNameToFindWithNamespace = string.IsNullOrEmpty(info.TypeInfo.Namespace) ? classNameToFind : info.TypeInfo.Namespace + "." + classNameToFind; + var info = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId).Method.Info; + var classNameToFindWithNamespace = + string.IsNullOrEmpty(info.TypeInfo.Namespace) ? + classNameToFind : + info.TypeInfo.Namespace + "." + classNameToFind; foreach (var asm in store.assemblies) { - if (await TryGetTypeIdFromName(classNameToFind, asm)) - break; if (await TryGetTypeIdFromName(classNameToFindWithNamespace, asm)) break; + if (await TryGetTypeIdFromName(classNameToFind, asm)) + break; } async Task TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) From 5f5cdf627da6eeaa173a68541c402dec53049ff2 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Thu, 11 Nov 2021 12:57:01 +0100 Subject: [PATCH 18/23] Test for classes evaluated from different frames. --- .../EvaluateOnCallFrameTests.cs | 24 ++++++++++++++++++- .../debugger-test/debugger-evaluate-test.cs | 17 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index d13cff819953c..e7da3d4bfa59c 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -758,7 +758,29 @@ await EvaluateOnCallFrameAndCheck(id, ("EvaluateNonStaticClassWithStaticFields.StaticProperty1", TString("StaticProperty1")), ("EvaluateNonStaticClassWithStaticFields.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); - + + [Fact] + public async Task EvaluateStaticClassesFromDifferentNamespaceInDifferentFrames() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTestsV2.EvaluateStaticClass", "Run", 1, "Run", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateMethods'); })", + wait_for_event_fn: async (pause_location) => + { + var id_top = pause_location["callFrames"][0]["callFrameId"].Value(); + var frame = pause_location["callFrames"][0]; + + await EvaluateOnCallFrameAndCheck(id_top, + ("EvaluateStaticClass.StaticField1", TNumber(20)), + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty2")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + + var id_second = pause_location["callFrames"][1]["callFrameId"].Value(); + + await EvaluateOnCallFrameAndCheck(id_second, + ("EvaluateStaticClass.StaticField1", TNumber(10)), + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + }); + [Fact] public async Task EvaluateStaticClassInvalidField() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.EvaluateMethodTestsClass/TestEvaluate", "run", 9, "run", 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 a00b131060478..0d8cd9ada9046 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 @@ -403,6 +403,8 @@ public static void EvaluateMethods() { TestEvaluate f = new TestEvaluate(); f.run(100, 200, "9000", "test", 45); + DebuggerTestsV2.EvaluateStaticClass.Run(); + var a = 0; } public static void EvaluateAsyncMethods() @@ -477,3 +479,18 @@ public static void EvaluateLocals() } } + +namespace DebuggerTestsV2 +{ + public static class EvaluateStaticClass + { + public static int StaticField1 = 20; + public static string StaticProperty1 => "StaticProperty2"; + public static string StaticPropertyWithError => throw new Exception("not implemented"); + + public static void Run() + { + var a = 0; + } + } +} \ No newline at end of file From 7151177ee97803b4fa0967f462e8736a2a16dff7 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 15 Nov 2021 09:06:05 +0100 Subject: [PATCH 19/23] Fixing indentation and spaces. --- .../DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 12 ++++++------ .../tests/debugger-test/debugger-evaluate-test.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index e7da3d4bfa59c..1c19de9d993fa 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -769,16 +769,16 @@ public async Task EvaluateStaticClassesFromDifferentNamespaceInDifferentFrames() var frame = pause_location["callFrames"][0]; await EvaluateOnCallFrameAndCheck(id_top, - ("EvaluateStaticClass.StaticField1", TNumber(20)), - ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty2")), - ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + ("EvaluateStaticClass.StaticField1", TNumber(20)), + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty2")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); var id_second = pause_location["callFrames"][1]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id_second, - ("EvaluateStaticClass.StaticField1", TNumber(10)), - ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), - ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); + ("EvaluateStaticClass.StaticField1", TNumber(10)), + ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), + ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); [Fact] 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 0d8cd9ada9046..8cafcdbbdf844 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 @@ -486,7 +486,7 @@ public static class EvaluateStaticClass { public static int StaticField1 = 20; public static string StaticProperty1 => "StaticProperty2"; - public static string StaticPropertyWithError => throw new Exception("not implemented"); + public static string StaticPropertyWithError => throw new Exception("not implemented"); public static void Run() { From 5fc759e6f40d58ee53db216fe04dd8ac976ea45d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 15 Nov 2021 09:49:43 +0100 Subject: [PATCH 20/23] Applied review comments for values evaluation. --- .../MemberReferenceResolver.cs | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index beb2903c360d8..7ebc4e9ebbf3b 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -119,28 +119,38 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT } } var store = await proxy.LoadStore(sessionId, token); - var info = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId).Method.Info; + var methodInfo = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId)?.Method?.Info; var classNameToFindWithNamespace = - string.IsNullOrEmpty(info.TypeInfo.Namespace) ? + string.IsNullOrEmpty(methodInfo?.TypeInfo?.Namespace) ? classNameToFind : - info.TypeInfo.Namespace + "." + classNameToFind; + methodInfo.TypeInfo.Namespace + "." + classNameToFind; - foreach (var asm in store.assemblies) - { - if (await TryGetTypeIdFromName(classNameToFindWithNamespace, asm)) - break; - if (await TryGetTypeIdFromName(classNameToFind, asm)) - break; - } + var searchResult = await TryFindNameInAssembly(store.assemblies, classNameToFindWithNamespace); + if (searchResult == null) + searchResult = await TryFindNameInAssembly(store.assemblies, classNameToFind); + if (searchResult != null) + typeId = (int)searchResult; - async Task TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) + async Task> TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) { + int typeId; var type = assembly.GetTypeByName(typeName); if (type == null) - return false; + return new Tuple(false, null); typeId = await sdbHelper.GetTypeIdFromToken(sessionId, assembly.DebugId, type.Token, token); - return true; + return new Tuple(true, typeId); ; + } + + async Task TryFindNameInAssembly(List assemblies, string name) + { + foreach (var asm in assemblies) + { + var searchResult = await TryGetTypeIdFromName(name, asm); + if (searchResult.Item1) + return searchResult.Item2; + } + return null; } } return null; @@ -211,17 +221,13 @@ public async Task Resolve(string varName, CancellationToken token) } else { - rootObject = await TryToRunOnLoadedClasses(varName, token); - return rootObject; + break; } } } } if (rootObject == null) - { rootObject = await TryToRunOnLoadedClasses(varName, token); - return rootObject; - } scopeCache.MemberReferences[varName] = rootObject; return rootObject; } From 3661c0edade9fea05c5e2e4ccda6ccfe05d4939d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 15 Nov 2021 10:03:16 +0100 Subject: [PATCH 21/23] Compressed two tests into one with MemberData. --- .../EvaluateOnCallFrameTests.cs | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 1c19de9d993fa..9a57005772a16 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -36,9 +36,10 @@ public static IEnumerable InstanceMethodForTypeMembersTestData(string } } - public static IEnumerable EvaluateStaticClassFromAsyncMethodTestData(string type_name) + public static IEnumerable EvaluateStaticClassFromStaticMethodTestData(string type_name) { yield return new object[] { type_name, "EvaluateAsyncMethods", "EvaluateAsyncMethods", true }; + yield return new object[] { type_name, "EvaluateMethods", "EvaluateMethods", false }; } [Theory] @@ -700,31 +701,12 @@ await EvaluateOnCallFrameAndCheck(id, ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); }); - [Fact] - public async Task EvaluateStaticClassFromStaticMethod() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateMethodTestsClass", "EvaluateMethods", 1, "EvaluateMethods", - "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateMethods'); })", - wait_for_event_fn: async (pause_location) => - { - var id = pause_location["callFrames"][0]["callFrameId"].Value(); - - var frame = pause_location["callFrames"][0]; - - await EvaluateOnCallFrameAndCheck(id, - ("EvaluateStaticClass.StaticField1", TNumber(10)), - ("EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), - ("EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented")), - ("DebuggerTests.EvaluateStaticClass.StaticField1", TNumber(10)), - ("DebuggerTests.EvaluateStaticClass.StaticProperty1", TString("StaticProperty1")), - ("DebuggerTests.EvaluateStaticClass.StaticPropertyWithError", TString("System.Exception: not implemented"))); - }); - [Theory] - [MemberData(nameof(EvaluateStaticClassFromAsyncMethodTestData), parameters: "DebuggerTests.EvaluateMethodTestsClass")] - public async Task EvaluateStaticClassFromAsyncMethod(string type, string method, string bp_function_name, bool is_async) + [MemberData(nameof(EvaluateStaticClassFromStaticMethodTestData), parameters: "DebuggerTests.EvaluateMethodTestsClass")] + public async Task EvaluateStaticClassFromStaticMethod(string type, string method, string bp_function_name, bool is_async) => await CheckInspectLocalsAtBreakpointSite( type, method, 1, bp_function_name, - "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateMethodTestsClass:EvaluateAsyncMethods'); })", + $"window.setTimeout(function() {{ invoke_static_method ('[debugger-test] {type}:{method}'); }})", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); From 66ed5c2ff1418a2b03f2500ea82a346b1b3ba0f6 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 15 Nov 2021 10:11:28 +0100 Subject: [PATCH 22/23] Added test case of type without namespace (failing). --- .../wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 9a57005772a16..d07912f8b589e 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -703,6 +703,7 @@ await EvaluateOnCallFrameAndCheck(id, [Theory] [MemberData(nameof(EvaluateStaticClassFromStaticMethodTestData), parameters: "DebuggerTests.EvaluateMethodTestsClass")] + [MemberData(nameof(EvaluateStaticClassFromStaticMethodTestData), parameters: "EvaluateMethodTestsClass")] public async Task EvaluateStaticClassFromStaticMethod(string type, string method, string bp_function_name, bool is_async) => await CheckInspectLocalsAtBreakpointSite( type, method, 1, bp_function_name, From 136f69a75c6b91cfe689288d4d7b74168e730738 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 16 Nov 2021 09:28:32 +0100 Subject: [PATCH 23/23] Addressed Ankit advices from the review. --- .../BrowserDebugProxy/MemberReferenceResolver.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 7ebc4e9ebbf3b..97f8767f6e235 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -131,24 +131,21 @@ public async Task TryToRunOnLoadedClasses(string varName, CancellationT if (searchResult != null) typeId = (int)searchResult; - async Task> TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) + async Task TryGetTypeIdFromName(string typeName, AssemblyInfo assembly) { - int typeId; var type = assembly.GetTypeByName(typeName); if (type == null) - return new Tuple(false, null); - - typeId = await sdbHelper.GetTypeIdFromToken(sessionId, assembly.DebugId, type.Token, token); - return new Tuple(true, typeId); ; + return null; + return await sdbHelper.GetTypeIdFromToken(sessionId, assembly.DebugId, type.Token, token); } async Task TryFindNameInAssembly(List assemblies, string name) { foreach (var asm in assemblies) { - var searchResult = await TryGetTypeIdFromName(name, asm); - if (searchResult.Item1) - return searchResult.Item2; + var typeId = await TryGetTypeIdFromName(name, asm); + if (typeId != null) + return typeId; } return null; }