Skip to content

Commit

Permalink
Fix evaluate expression of mutidimensional array. (#72964)
Browse files Browse the repository at this point in the history
  • Loading branch information
thaystg authored Jul 28, 2022
1 parent 9dfc922 commit d641668
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public SyntaxTree ReplaceVars(SyntaxTree syntaxTree, IEnumerable<JObject> ma_val
{
// Generate a random suffix
string suffix = Guid.NewGuid().ToString().Substring(0, 5);
string prefix = eaStr.Trim().Replace(".", "_").Replace("[", "_").Replace("]", "_");
string prefix = regexForReplaceVarName.Replace(eaStr, "_");
id_name = $"{prefix}_{suffix}";
elementAccessToParamName[eaStr] = id_name;
}
Expand Down
34 changes: 24 additions & 10 deletions src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
{
JObject rootObject = null;
string elementAccessStrExpression = elementAccess.Expression.ToString();
var multiDimensionalArray = false;
rootObject = await Resolve(elementAccessStrExpression, token);
if (rootObject == null)
{
Expand All @@ -370,22 +371,27 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
}
if (rootObject != null)
{
string elementIdxStr;
string elementIdxStr = null;
int elementIdx = 0;
var elementAccessStr = elementAccess.ToString();
// x[1] or x[a] or x[a.b]
if (indexObject == null)
{
if (elementAccess.ArgumentList != null)
{
foreach (var arg in elementAccess.ArgumentList.Arguments)
for (int i = 0 ; i < elementAccess.ArgumentList.Arguments.Count; i++)
{
var arg = elementAccess.ArgumentList.Arguments[i];
if (i != 0)
{
elementIdxStr += ", ";
multiDimensionalArray = true;
}
// e.g. x[1]
if (arg.Expression is LiteralExpressionSyntax)
{
var argParm = arg.Expression as LiteralExpressionSyntax;
elementIdxStr = argParm.ToString();
int.TryParse(elementIdxStr, out elementIdx);
elementIdxStr += argParm.ToString();
}

// e.g. x[a] or x[a.b]
Expand All @@ -401,10 +407,8 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
{
indexObject = await Resolve(argParm.Identifier.Text, token);
}
elementIdxStr = indexObject["value"].ToString();
int.TryParse(elementIdxStr, out elementIdx);
elementIdxStr += indexObject["value"].ToString();
}

// FixMe: indexing with expressions, e.g. x[a + 1]
}
}
Expand All @@ -413,9 +417,8 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
else
{
elementIdxStr = indexObject["value"].ToString();
int.TryParse(elementIdxStr, out elementIdx);
}
if (elementIdx >= 0)
if (elementIdxStr != null)
{
var type = rootObject?["type"]?.Value<string>();
if (!DotnetObjectId.TryParse(rootObject?["objectId"]?.Value<string>(), out DotnetObjectId objectId))
Expand All @@ -425,8 +428,19 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
{
case "array":
rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token);
return (JObject)rootObject["value"][elementIdx]["value"];
if (!multiDimensionalArray)
{
int.TryParse(elementIdxStr, out elementIdx);
return (JObject)rootObject["value"][elementIdx]["value"];
}
else
{
return (JObject)(((JArray)rootObject["value"]).FirstOrDefault(x => x["name"].Value<string>() == elementIdxStr)["value"]);
}
case "object":
if (multiDimensionalArray)
throw new InvalidOperationException($"Cannot apply indexing with [,] to an object of type '{type}'");
int.TryParse(elementIdxStr, out elementIdx);
if (type == "string")
{
// ToArray() does not exist on string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,71 @@ await EvaluateOnCallFrameAndCheck(id,

[ConditionalFact(nameof(RunningOnChrome))]
public async Task EvaluateIndexingMultidimensional() => await CheckInspectLocalsAtBreakpointSite(
"DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests.EvaluateLocals",
"window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests:EvaluateLocals'); })",
wait_for_event_fn: async (pause_location) =>
{
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();

await EvaluateOnCallFrameAndCheck(id,
("j", TNumber(1)),
("f.idx1", TNumber(1)),
("f.numArray2D[0, 0]", TNumber(1)),
("f.numArray2D[0, 1]", TNumber(2)),
("f.numArray2D[1, 0]", TNumber(3)),
("f.numArray2D[1 ,1]", TNumber(4)),
("f.numArray3D[0, 0, 0]", TNumber(1)),
("f.numArray3D[0 ,0 ,1]", TNumber(2)),
("f.numArray3D[0 ,0, 2]", TNumber(3)),
("f.numArray3D[1, 1, 0]", TNumber(10)),
("f.numArray3D[1, 1, 1]", TNumber(11)),
("f.numArray3D[1 , 1, 2]", TNumber(12)),
("f.numArray2D[0,0]", TNumber(1)),
("f.numArray2D[0,1]", TNumber(2)),
("f.numArray2D[1,0]", TNumber(3)),
("f.numArray2D[1,1]", TNumber(4)),
("f.numArray3D[0,0,0]", TNumber(1)),
("f.numArray3D[0,0,1]", TNumber(2)),
("f.numArray3D[0,0,2]", TNumber(3)),
("f.numArray3D[1,1,0]", TNumber(10)),
("f.numArray3D[1,1,1]", TNumber(11)),
("f.numArray3D[1,1,2]", TNumber(12)),
("f.textArray2D[0,0]", TString("one")),
("f.textArray2D[0,1]", TString("two")),
("f.textArray2D[1,0]", TString("three")),
("f.textArray2D[1,1]", TString("four")),
("f.numArray2D[i,i]", TNumber(1)),
("f.numArray2D[i,j]", TNumber(2)),
("f.numArray2D[j,i]", TNumber(3)),
("f.numArray2D[j,j]", TNumber(4)),
("f.numArray3D[i,i,i]", TNumber(1)),
("f.numArray3D[i,i,j]", TNumber(2)),
("f.numArray3D[i,i,2]", TNumber(3)),
("f.numArray3D[j,j,i]", TNumber(10)),
("f.numArray3D[j,j,1]", TNumber(11)),
("f.numArray3D[j,j,2]", TNumber(12)),
("f.textArray2D[i,i]", TString("one")),
("f.textArray2D[i,j]", TString("two")),
("f.textArray2D[j,i]", TString("three")),
("f.textArray2D[j,j]", TString("four")),
("f.numArray2D[f.idx0,f.idx0]", TNumber(1)),
("f.numArray2D[f.idx0,f.idx1]", TNumber(2)),
("f.numArray2D[f.idx1,f.idx0]", TNumber(3)),
("f.numArray2D[f.idx1,f.idx1]", TNumber(4)),
("f.numArray3D[f.idx0,f.idx0,f.idx0]", TNumber(1)),
("f.numArray3D[f.idx0,f.idx0,f.idx1]", TNumber(2)),
("f.numArray3D[f.idx0,f.idx0,2]", TNumber(3)),
("f.numArray3D[f.idx1,f.idx1,f.idx0]", TNumber(10)),
("f.numArray3D[f.idx1,f.idx1,f.idx1]", TNumber(11)),
("f.numArray3D[f.idx1,f.idx1,2]", TNumber(12)),
("f.textArray2D[f.idx0,f.idx0]", TString("one")),
("f.textArray2D[f.idx0,f.idx1]", TString("two")),
("f.textArray2D[f.idx1,f.idx0]", TString("three")),
("f.textArray2D[f.idx1,f.idx1]", TString("four")));
});

[ConditionalFact(nameof(RunningOnChrome))]
public async Task EvaluateIndexingJagged() => await CheckInspectLocalsAtBreakpointSite(
"DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals",
"window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })",
wait_for_event_fn: async (pause_location) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,37 @@ public static void EvaluateLocals()
}
}

public class EvaluateLocalsWithMultidimensionalIndexingTests
{
public class TestEvaluate
{
public int[,] numArray2D;
public string[,] textArray2D;
public int[,,] numArray3D;
public int idx0;
public int idx1;

public void run()
{
numArray2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
textArray2D = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
numArray3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
idx0 = 0;
idx1 = 1;
}
}

public static void EvaluateLocals()
{
int i = 0;
int j = 1;
TestEvaluate f = new TestEvaluate();
f.run();
}
}

public struct SampleStructure
{
public SampleStructure() { }
Expand Down

0 comments on commit d641668

Please sign in to comment.