First pass at debug adapter support

This commit is contained in:
Joshua "Yoshi" Askharoun
2025-11-30 13:37:34 -06:00
parent 61ff45aee5
commit 1ab545d4e2
6 changed files with 50 additions and 12 deletions
@@ -0,0 +1,8 @@
using System.Collections.Generic;
using System.Collections.Specialized;
namespace Microsoft.Iris.Debug.Data;
public interface IObservableCollection<T> : ICollection<T>, INotifyCollectionChanged
{
}
@@ -10,9 +10,6 @@ namespace Microsoft.Iris.Debug;
/// </summary> /// </summary>
public static class DebugRemoting public static class DebugRemoting
{ {
public const string DEFAULT_TCP_CLIENT_URI = ">tcp://127.0.0.1:5555,@tcp://127.0.0.1:5556";
public const string DEFAULT_TCP_SERVER_URI = "@tcp://127.0.0.1:5555,>tcp://127.0.0.1:5556";
public static readonly Uri DEFAULT_TCP_URI = new("tcp://127.0.0.1:5555"); public static readonly Uri DEFAULT_TCP_URI = new("tcp://127.0.0.1:5555");
internal static IFormatter CreateBsonFormatter() => new BsonFormatter(new StreamingContext(StreamingContextStates.Remoting)); internal static IFormatter CreateBsonFormatter() => new BsonFormatter(new StreamingContext(StreamingContextStates.Remoting));
+3 -1
View File
@@ -8,6 +8,8 @@ public interface IDebuggerState
void Start(); void Start();
InterpreterCommand DebuggerCommand { get; set; } InterpreterCommand DebuggerCommand { get; set; }
//IObservableCollection<Breakpoint> Breakpoints { get; }
} }
public interface IRemoteDebuggerState : IDebuggerState public interface IRemoteDebuggerState : IDebuggerState
@@ -15,7 +17,7 @@ public interface IRemoteDebuggerState : IDebuggerState
/// <summary> /// <summary>
/// The URI the client is connected to. /// The URI the client is connected to.
/// </summary> /// </summary>
public Uri ConnectionUri { get; } public string ConnectionString { get; }
/// <summary> /// <summary>
/// Fired when a connection is established. /// Fired when a connection is established.
@@ -10,6 +10,16 @@ namespace Microsoft.Iris.Debug.Symbols;
public class ApplicationDebugSymbols public class ApplicationDebugSymbols
{ {
public List<FileDebugSymbols> Files { get; set; } public List<FileDebugSymbols> Files { get; set; }
public FileDebugSymbols GetForFile(string filename)
{
return Files.FirstOrDefault(f =>
PathEquals(f.OriginalFileName)
|| PathEquals(f.CompiledFileName)
|| PathEquals(f.SourceFileName));
bool PathEquals(string otherPath) => filename.Equals(otherPath, StringComparison.InvariantCultureIgnoreCase);
}
} }
[CLSCompliant(false)] [CLSCompliant(false)]
@@ -23,7 +33,7 @@ public class FileDebugSymbols
public string SourceFileName { get; set; } public string SourceFileName { get; set; }
public SourceMap SourceMap { get; } = new(); public SourceMap SourceMap { get; } = [];
public string GetSourceSubstring(SourceSpan span) public string GetSourceSubstring(SourceSpan span)
{ {
@@ -68,12 +78,20 @@ public class SourceMap : Dictionary<uint, SourceSpan>
public Entry GetLocationFromPosition(SourcePosition pos) public Entry GetLocationFromPosition(SourcePosition pos)
{ {
var foundLocation = this var foundLocation = this
.Where(kvp => .Where(kvp => kvp.Value.Contains(pos))
{ .OrderBy(kvp => kvp.Value.Size)
var offset = kvp.Key; .FirstOrDefault();
var span = kvp.Value;
return span.Contains(pos); if (foundLocation.Equals(default(KeyValuePair<uint, SourceSpan>)))
}) return null;
return new Entry(foundLocation.Key, foundLocation.Value);
}
public Entry GetLocationFromLine(int line)
{
var foundLocation = this
.Where(kvp => kvp.Value.ContainsLine(line))
.OrderBy(kvp => kvp.Value.Size) .OrderBy(kvp => kvp.Value.Size)
.FirstOrDefault(); .FirstOrDefault();
@@ -172,6 +190,14 @@ public class SourceSpan
public bool Contains(SourcePosition pos) => Start <= pos && pos < End; public bool Contains(SourcePosition pos) => Start <= pos && pos < End;
public bool ContainsLine(int line)
{
return Start.Line <= line &&
(End.Column > 1
? line <= End.Line
: line < End.Line);
}
public void AsZeroIndexed(out int startLine, out int startColumn, out int endLine, out int endColumn) public void AsZeroIndexed(out int startLine, out int startColumn, out int endLine, out int endColumn)
{ {
Start.AsZeroIndexed(out startLine, out startColumn); Start.AsZeroIndexed(out startLine, out startColumn);
@@ -18,6 +18,8 @@ public class NetDebuggerClient : IDebuggerClient, IRemoteDebuggerState, IDisposa
private InterpreterCommand _uibCommand; private InterpreterCommand _uibCommand;
private long _nextFreeTransactionId = 1; private long _nextFreeTransactionId = 1;
public string ConnectionString => ConnectionUri.ToString();
public Uri ConnectionUri { get; } public Uri ConnectionUri { get; }
public InterpreterCommand DebuggerCommand public InterpreterCommand DebuggerCommand
@@ -39,6 +41,7 @@ public class NetDebuggerClient : IDebuggerClient, IRemoteDebuggerState, IDisposa
public NetDebuggerClient(Uri connectionUri = null) public NetDebuggerClient(Uri connectionUri = null)
{ {
ConnectionUri = connectionUri ?? DebugRemoting.DEFAULT_TCP_URI; ConnectionUri = connectionUri ?? DebugRemoting.DEFAULT_TCP_URI;
_socket = new(SocketType.Stream, ProtocolType.Tcp); _socket = new(SocketType.Stream, ProtocolType.Tcp);
_formatter = DebugRemoting.CreateBsonFormatter(); _formatter = DebugRemoting.CreateBsonFormatter();
} }
@@ -20,6 +20,8 @@ public class NetDebuggerServer : IDebuggerServer, IRemoteDebuggerState, IDisposa
public event Action<IDebuggerState, object> Connected; public event Action<IDebuggerState, object> Connected;
public string ConnectionString => ConnectionUri.ToString();
public Uri ConnectionUri { get; } public Uri ConnectionUri { get; }
public InterpreterCommand DebuggerCommand public InterpreterCommand DebuggerCommand
@@ -35,7 +37,7 @@ public class NetDebuggerServer : IDebuggerServer, IRemoteDebuggerState, IDisposa
public NetDebuggerServer(Uri connectionUri = null) public NetDebuggerServer(Uri connectionUri = null)
{ {
ConnectionUri = connectionUri ?? DebugRemoting.DEFAULT_TCP_URI; ConnectionUri = connectionUri ?? DebugRemoting.DEFAULT_TCP_URI;
_listener = TcpListener.Create(ConnectionUri.Port); _listener = TcpListener.Create(ConnectionUri.Port);
_listener.Start(); _listener.Start();