2025-11-30 13:37:33 -06:00
|
|
|
using Microsoft.Iris.Debug.Symbols;
|
|
|
|
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
|
2025-12-03 20:42:58 -06:00
|
|
|
using System;
|
2025-11-30 13:37:33 -06:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
using DapBreakpoint = OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint;
|
|
|
|
|
using IrisBreakpoint = Microsoft.Iris.Debug.Data.Breakpoint;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.Iris.DebugAdapter.Server.Handlers;
|
|
|
|
|
|
|
|
|
|
internal class BreakpointHandler(DebugSymbolResolver symbolResolver)
|
2025-12-06 01:49:18 -06:00
|
|
|
: ISetInstructionBreakpointsHandler, ISetBreakpointsHandler, ISetExceptionBreakpointsHandler, ISetDataBreakpointsHandler,
|
|
|
|
|
ISetFunctionBreakpointsHandler
|
2025-11-30 13:37:33 -06:00
|
|
|
{
|
|
|
|
|
public Task<SetInstructionBreakpointsResponse> Handle(SetInstructionBreakpointsArguments request, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
List<DapBreakpoint> dapBreakpoints = [];
|
|
|
|
|
|
|
|
|
|
foreach (var requestedBreakpoint in request.Breakpoints)
|
|
|
|
|
{
|
2025-12-03 20:42:58 -06:00
|
|
|
var parts = requestedBreakpoint.InstructionReference.Split(['@'], 2);
|
|
|
|
|
var loadUri = parts[0];
|
|
|
|
|
var offset = Convert.ToUInt32(parts[1], 16);
|
|
|
|
|
|
|
|
|
|
IrisBreakpoint irisBreakpoint = new(loadUri, offset);
|
|
|
|
|
Application.DebugSettings.Breakpoints.Add(irisBreakpoint);
|
|
|
|
|
|
|
|
|
|
DapBreakpoint dapBreakpoint = new()
|
|
|
|
|
{
|
|
|
|
|
Id = irisBreakpoint.GetHashCode(),
|
|
|
|
|
InstructionReference = requestedBreakpoint.InstructionReference,
|
|
|
|
|
};
|
|
|
|
|
dapBreakpoints.Add(dapBreakpoint);
|
2025-11-30 13:37:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetInstructionBreakpointsResponse response = new()
|
|
|
|
|
{
|
|
|
|
|
Breakpoints = dapBreakpoints
|
|
|
|
|
};
|
|
|
|
|
return Task.FromResult(response);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<SetBreakpointsResponse> Handle(SetBreakpointsArguments request, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
// Debug symbols are required for setting source (line:column) breakpoints
|
|
|
|
|
var fsym = symbolResolver?.GetForFile(request.Source.Path);
|
|
|
|
|
if (fsym is null)
|
|
|
|
|
return Task.FromResult(new SetBreakpointsResponse());
|
|
|
|
|
|
|
|
|
|
List<DapBreakpoint> dapBreakpoints = [];
|
|
|
|
|
|
|
|
|
|
// TODO: Clear existing breakpoints for file
|
|
|
|
|
|
|
|
|
|
foreach (var requestedBreakpoint in request.Breakpoints ?? [])
|
|
|
|
|
{
|
|
|
|
|
SourceMap.Entry location;
|
|
|
|
|
|
|
|
|
|
if (requestedBreakpoint.Column is not null)
|
|
|
|
|
{
|
|
|
|
|
SourcePosition position = new(requestedBreakpoint.Line, requestedBreakpoint.Column.Value);
|
|
|
|
|
location = fsym.SourceMap.GetLocationFromPosition(position);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Get first location that contains this line
|
|
|
|
|
location = fsym.SourceMap.GetLocationFromLine(requestedBreakpoint.Line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IrisBreakpoint irisBreakpoint = new(fsym.CompiledFileName, location.Offset);
|
|
|
|
|
Application.DebugSettings.Breakpoints.Add(irisBreakpoint);
|
|
|
|
|
|
|
|
|
|
DapBreakpoint dapBreakpoint = new()
|
|
|
|
|
{
|
|
|
|
|
Line = location.Span.Start.Line,
|
|
|
|
|
Column = location.Span.Start.Column,
|
|
|
|
|
EndLine = location.Span.End.Line,
|
|
|
|
|
EndColumn = location.Span.End.Column,
|
|
|
|
|
};
|
|
|
|
|
dapBreakpoints.Add(dapBreakpoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetBreakpointsResponse response = new()
|
|
|
|
|
{
|
|
|
|
|
Breakpoints = dapBreakpoints
|
|
|
|
|
};
|
|
|
|
|
return Task.FromResult(response);
|
|
|
|
|
}
|
2025-12-06 01:49:18 -06:00
|
|
|
|
|
|
|
|
public Task<SetExceptionBreakpointsResponse> Handle(SetExceptionBreakpointsArguments request, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(new SetExceptionBreakpointsResponse());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<SetDataBreakpointsResponse> Handle(SetDataBreakpointsArguments request, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(new SetDataBreakpointsResponse());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<SetFunctionBreakpointsResponse> Handle(SetFunctionBreakpointsArguments request, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(new SetFunctionBreakpointsResponse());
|
|
|
|
|
}
|
2025-11-30 13:37:33 -06:00
|
|
|
}
|