未验证 提交 b11689b6 编写于 作者: I Ilona Tomkowicz 提交者: GitHub

[wasm][debugger] Support "on frame evaluation" of functions returning char (#65842)

* Optional parameter fix.

* Working version of optional parameter support, requires refactoring.

* Refactored.

* Fixed failing tests.

* Add support to functions returning char, add test to an existing case.

* Simplified tests.

* Merged with optional params, uncommented char test

* Remove spaces.

* Applied @radical's suggestions.

* Removed indentation.

* Another indentation.

* Removed comment.

* Reverted type=char, as @radical suggested.

* Applied @radical's suggestions. No need for escaping + reverting original name.
上级 093bdc46
......@@ -231,6 +231,12 @@ private string ConvertJSToCSharpLocalVariableAssignment(string idName, JToken va
typeRet = "string";
break;
}
case "symbol":
{
valueRet = $"'{value?.Value<char>()}'";
typeRet = "char";
break;
}
case "number":
//casting to double and back to string would loose precision; so casting straight to string
valueRet = value?.Value<string>();
......@@ -424,6 +430,8 @@ private static object ConvertCSharpToJSType(object v, Type type)
return new { type = "object", subtype = "null", className = type?.ToString(), description = type?.ToString() };
if (v is string s)
return new { type = "string", value = s, description = s };
if (v is char c)
return new { type = "symbol", value = c, description = $"{(int)c} '{c}'" };
if (NumericTypes.Contains(v.GetType()))
return new { type = "number", value = v, description = Convert.ToDouble(v).ToString(CultureInfo.InvariantCulture) };
if (v is JObject)
......
......@@ -1765,8 +1765,9 @@ public JObject CreateJObjectForNumber<T>(T value)
public JObject CreateJObjectForChar(int value)
{
var description = $"{value.ToString()} '{Convert.ToChar(value)}'";
return CreateJObject<string>(description, "symbol", description, true);
char charValue = Convert.ToChar(value);
var description = $"{value} '{charValue}'";
return CreateJObject<char>(charValue, "symbol", description, true);
}
public async Task<JObject> CreateJObjectForPtr(ElementType etype, MonoBinaryReader retDebuggerCmdReader, string name, CancellationToken token)
......
......@@ -16,7 +16,7 @@ public class AssignmentTests : DebuggerTestBase
{ "MONO_TYPE_OBJECT", TObject("object", is_null: true), TObject("object") },
{ "MONO_TYPE_CLASS", TObject("DebuggerTests.MONO_TYPE_CLASS", is_null: true), TObject("DebuggerTests.MONO_TYPE_CLASS") },
{ "MONO_TYPE_BOOLEAN", TBool(default), TBool(true) },
{ "MONO_TYPE_CHAR", TSymbol("0 '\u0000'"), TSymbol("97 'a'") },
{ "MONO_TYPE_CHAR", TChar('\u0000'), TChar('a') },
{ "MONO_TYPE_STRING", TString(default), TString("hello") },
{ "MONO_TYPE_ENUM", TEnum("DebuggerTests.RGB", "Red"), TEnum("DebuggerTests.RGB", "Blue") },
{ "MONO_TYPE_ARRAY", TObject("byte[]", is_null: true), TArray("byte[]", "byte[2]") },
......
......@@ -323,10 +323,10 @@ internal async Task CheckString(JToken locals, string name, string value)
await CheckValue(l["value"], TString(value), name);
}
internal async Task<JToken> CheckSymbol(JToken locals, string name, string value)
internal async Task<JToken> CheckSymbol(JToken locals, string name, char value)
{
var l = GetAndAssertObjectWithName(locals, name);
await CheckValue(l["value"], TSymbol(value), name);
await CheckValue(l["value"], TChar(value), name);
return l;
}
......@@ -1171,6 +1171,8 @@ internal void AssertEqual(object expected, object actual, string label)
internal static JObject TBool(bool value) => JObject.FromObject(new { type = "boolean", value = @value, description = @value ? "true" : "false" });
internal static JObject TSymbol(string value) => JObject.FromObject(new { type = "symbol", value = @value, description = @value });
internal static JObject TChar(char value) => JObject.FromObject(new { type = "symbol", value = @value, description = $"{(int)value} '{@value}'" });
/*
For target names with generated method names like
......
......@@ -528,11 +528,12 @@ async Task EvaluateOnCallFrameFail(string call_frame_id, params (string expressi
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
await EvaluateOnCallFrameAndCheck(id,
("this.CallMethod()", TNumber(1)),
("this.CallMethod()", TNumber(1)),
("this.ParmToTestObj.MyMethod()", TString("methodOK")),
("this.ParmToTestObj.ToString()", TString("DebuggerTests.EvaluateMethodTestsClass+ParmToTest")),
("this.objToTest.MyMethod()", TString("methodOK")));
("this.CallMethod()", TNumber(1)),
("this.CallMethod()", TNumber(1)),
("this.CallMethodReturningChar()", TChar('A')),
("this.ParmToTestObj.MyMethod()", TString("methodOK")),
("this.ParmToTestObj.ToString()", TString("DebuggerTests.EvaluateMethodTestsClass+ParmToTest")),
("this.objToTest.MyMethod()", TString("methodOK")));
});
......@@ -1069,9 +1070,10 @@ public async Task EvaluateLocalObjectFromAssemblyNotRelatedButLoaded()
("test.GetInt64Nullable()", TNumber(1)),
("test.GetUInt64Nullable()", TNumber(1)),
// ("test.GetChar()", TString("T")), //fails, Evaluate of this datatype symbol not implemented yet (for non optional parameters either)
// ("test.GetCharNullable()", TString("T")),
// ("test.GetUnicodeChar()", TString("ą")),
("test.GetChar()", TChar('T')),
("test.GetCharNullable()", TChar('T')),
("test.GetUnicodeChar()", TChar('ą')),
("test.GetString()", TString("1.23")),
("test.GetUnicodeString()", TString("żółć")),
("test.GetString(null)", TObject("string", is_null: true)),
......
......@@ -84,8 +84,8 @@ public async Task ExceptionThrownInJSOutOfBand()
"window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:PrimitiveTypesTest'); }, 1);",
test_fn: async (locals) =>
{
await CheckSymbol(locals, "c0", "8364 '€'");
await CheckSymbol(locals, "c1", "65 'A'");
await CheckSymbol(locals, "c0", '€');
await CheckSymbol(locals, "c1", 'A');
await Task.CompletedTask;
}
);
......
......@@ -40,7 +40,7 @@ public class PointerTests : DebuggerTestBase
ipp = TPointer("int**"),
ipp_null = TPointer("int**"),
cvalue0 = TSymbol("113 'q'"),
cvalue0 = TChar('q'),
cp = TPointer("char*"),
vp = TPointer("void*"),
......@@ -65,7 +65,7 @@ public class PointerTests : DebuggerTestBase
// *cp
props = await GetObjectOnLocals(locals, "cp");
await CheckPointerValue(props, "*cp", TSymbol("113 'q'"));
await CheckPointerValue(props, "*cp", TChar('q'));
});
[Theory]
......
......@@ -366,6 +366,11 @@ public int CallMethod()
return a;
}
public char CallMethodReturningChar()
{
return 'A';
}
public int CallMethodWithParm(int parm)
{
return a + parm;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册