Skip to content

Commit ae02fc8

Browse files
[release/7.0][wasm][debugger] Indexing with expression (#75559)
* Support for simple mathematical expressions + tests. * A bit more complex expressions. * Applied @radical's suggestions. Co-authored-by: Ilona Tomkowicz <[email protected]>
1 parent bbf023d commit ae02fc8

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using Microsoft.Extensions.Logging;
99
using Newtonsoft.Json.Linq;
1010
using System.IO;
11+
using Microsoft.CodeAnalysis;
12+
using Microsoft.CodeAnalysis.CSharp;
1113
using Microsoft.CodeAnalysis.CSharp.Syntax;
1214
using System.Collections.Generic;
1315
using System.Net.WebSockets;
@@ -409,7 +411,16 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
409411
}
410412
elementIdxStr += indexObject["value"].ToString();
411413
}
412-
// FixMe: indexing with expressions, e.g. x[a + 1]
414+
// indexing with expressions, e.g. x[a + 1]
415+
else
416+
{
417+
string expression = arg.ToString();
418+
indexObject = await ExpressionEvaluator.EvaluateSimpleExpression(this, expression, expression, variableDefinitions, logger, token);
419+
string type = indexObject["type"].Value<string>();
420+
if (type != "number")
421+
throw new InvalidOperationException($"Cannot index with an object of type '{type}'");
422+
elementIdxStr += indexObject["value"].ToString();
423+
}
413424
}
414425
}
415426
}

src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,48 @@ await EvaluateOnCallFrameAndCheck(id,
627627

628628
});
629629

630+
[Fact]
631+
public async Task EvaluateIndexingByExpression() => await CheckInspectLocalsAtBreakpointSite(
632+
"DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals",
633+
"window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })",
634+
wait_for_event_fn: async (pause_location) =>
635+
{
636+
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
637+
await EvaluateOnCallFrameAndCheck(id,
638+
("f.numList[i + 1]", TNumber(2)),
639+
("f.textList[(2 * j) - 1]", TString("2")),
640+
("f.textList[j - 1]", TString("1")),
641+
("f.numArray[f.numList[j - 1]]", TNumber(2))
642+
);
643+
});
644+
645+
[Fact]
646+
public async Task EvaluateIndexingByExpressionMultidimensional() => await CheckInspectLocalsAtBreakpointSite(
647+
"DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests.EvaluateLocals",
648+
"window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithMultidimensionalIndexingTests:EvaluateLocals'); })",
649+
wait_for_event_fn: async (pause_location) =>
650+
{
651+
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
652+
await EvaluateOnCallFrameAndCheck(id,
653+
("f.numArray2D[0, j - 1]", TNumber(1)), // 0, 0
654+
("f.numArray2D[f.idx1, i + j]", TNumber(4)), // 1, 1
655+
("f.numArray2D[(f.idx1 - j) * 5, i + j]", TNumber(2)), // 0, 1
656+
("f.numArray2D[i + j, f.idx1 - 1]", TNumber(3)) // 1, 0
657+
);
658+
});
659+
660+
[ConditionalFact(nameof(RunningOnChrome))]
661+
public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLocalsAtBreakpointSite(
662+
"DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals",
663+
$"window.setTimeout(function() {{ invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); 1 }})",
664+
wait_for_event_fn: async (pause_location) =>
665+
{
666+
// indexing with expression of a wrong type
667+
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
668+
var (_, res) = await EvaluateOnCallFrame(id, "f.numList[\"a\" + 1]", expect_ok: false );
669+
Assert.Equal("Unable to evaluate element access 'f.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["message"]?.Value<string>());
670+
});
671+
630672
[Fact]
631673
public async Task EvaluateIndexingByMemberVariables() => await CheckInspectLocalsAtBreakpointSite(
632674
"DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals",

0 commit comments

Comments
 (0)