mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
Redo debug symbols
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Iris.Debug.Symbols;
|
||||
|
||||
@@ -11,24 +12,96 @@ public class ApplicationDebugSymbols
|
||||
|
||||
public class FileDebugSymbols
|
||||
{
|
||||
public string SourceFileName { get; set; }
|
||||
private string[] _sourceCodeLines;
|
||||
|
||||
public string OriginalFileName { get; set; }
|
||||
|
||||
public string CompiledFileName { get; set; }
|
||||
|
||||
public Dictionary<uint, ScriptDebugSymbols> ScriptSymbols { get; set; }
|
||||
}
|
||||
|
||||
public class ScriptDebugSymbols
|
||||
{
|
||||
public string SourceCode { get; set; }
|
||||
public string SourceFileName { get; set; }
|
||||
|
||||
public Dictionary<uint, SourceSpan> SourceMap { get; set; }
|
||||
|
||||
public uint OffsetByLineAndColumn(int line, int col) => OffsetByLineAndColumn(new(line, col));
|
||||
|
||||
public uint OffsetByLineAndColumn(SourcePosition pos)
|
||||
{
|
||||
Assert.IsNotNull(_sourceCodeLines, nameof(_sourceCodeLines));
|
||||
|
||||
return SourceMap.First(kvp =>
|
||||
{
|
||||
var offset = kvp.Key;
|
||||
var span = kvp.Value;
|
||||
return span.Contains(pos);
|
||||
}).Key;
|
||||
}
|
||||
|
||||
public void SetSourceCode(string source)
|
||||
{
|
||||
_sourceCodeLines = source.Split('\n')
|
||||
.Select(s => s.TrimEnd('\r'))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerDisplay("L{Line}C{Column}")]
|
||||
public class SourcePosition : IComparable<SourcePosition>, IEquatable<SourcePosition>
|
||||
{
|
||||
public int Line { get; }
|
||||
|
||||
public int Column { get; }
|
||||
|
||||
private ulong Position => ((ulong)Line << (sizeof(uint) * 8)) | (uint)Column;
|
||||
|
||||
public SourcePosition(int line, int column)
|
||||
{
|
||||
if (line <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(line));
|
||||
|
||||
if (column <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(line));
|
||||
|
||||
Line = line;
|
||||
Column = column;
|
||||
}
|
||||
|
||||
public int CompareTo(SourcePosition other) => Position.CompareTo(other.Position);
|
||||
|
||||
public bool Equals(SourcePosition other) => Position == other.Position;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is not SourcePosition other)
|
||||
return false;
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = 533871040;
|
||||
hashCode = hashCode * -1521134295 + Line.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + Column.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + Position.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static bool operator <(SourcePosition left, SourcePosition right) => left.CompareTo(right) < 0;
|
||||
|
||||
public static bool operator >(SourcePosition left, SourcePosition right) => left.CompareTo(right) > 0;
|
||||
|
||||
public static bool operator <=(SourcePosition left, SourcePosition right) => left.CompareTo(right) <= 0;
|
||||
|
||||
public static bool operator >=(SourcePosition left, SourcePosition right) => left.CompareTo(right) >= 0;
|
||||
|
||||
public static bool operator ==(SourcePosition left, SourcePosition right) => left.Equals(right);
|
||||
|
||||
public static bool operator !=(SourcePosition left, SourcePosition right) => !(left == right);
|
||||
}
|
||||
|
||||
[DebuggerDisplay("[{Start}..{End}]")]
|
||||
public class SourceSpan
|
||||
{
|
||||
public SourceSpan(int start, int end)
|
||||
public SourceSpan(SourcePosition start, SourcePosition end)
|
||||
{
|
||||
if (start > end)
|
||||
throw new ArgumentException($"Source start index must be at or after end index.");
|
||||
@@ -37,10 +110,10 @@ public class SourceSpan
|
||||
End = end;
|
||||
}
|
||||
|
||||
public int Start { get; set; }
|
||||
public SourcePosition Start { get; }
|
||||
|
||||
public int End { get; set; }
|
||||
public SourcePosition End { get; }
|
||||
|
||||
public int GetLength() => End - Start;
|
||||
public bool Contains(SourcePosition pos) => Start >= pos && pos < End;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Iris.Debug.Symbols;
|
||||
|
||||
public static class DebugSymbolsJsonParser
|
||||
{
|
||||
private static JsonSerializerSettings _settings = new()
|
||||
private static readonly JsonSerializerSettings _settings = new()
|
||||
{
|
||||
Converters = [new SourceSpanJsonConverter()],
|
||||
};
|
||||
@@ -25,18 +27,50 @@ public static class DebugSymbolsJsonParser
|
||||
|
||||
private class SourceSpanJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(SourceSpan);
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(SourceSpan) || objectType == typeof(SourcePosition);
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var span = (SourceSpan)value;
|
||||
JArray array = [span.Start, span.End];
|
||||
if (value is SourceSpan span)
|
||||
{
|
||||
JArray array = [$"{span.Start.Line}:{span.Start.Column}", $"{span.End.Line}:{span.End.Column}"];
|
||||
array.WriteTo(writer);
|
||||
}
|
||||
else if (value is SourcePosition position)
|
||||
{
|
||||
writer.WriteValue($"{position.Line}:{position.Column}");
|
||||
}
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (objectType == typeof(SourcePosition))
|
||||
{
|
||||
if (reader.TokenType is not JsonToken.String)
|
||||
throw new JsonReaderException($"Expected {nameof(SourcePosition)} encoded as string");
|
||||
|
||||
var positionString = reader.ReadAsString();
|
||||
ParseSourcePosition(positionString);
|
||||
}
|
||||
else if (objectType == typeof(SourceSpan))
|
||||
{
|
||||
var rangeStrs = serializer.Deserialize<IEnumerable<string>>(reader);
|
||||
var range = rangeStrs.Select(ParseSourcePosition).ToArray();
|
||||
return new SourceSpan(range[0], range[1]);
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
static SourcePosition ParseSourcePosition(string positionString)
|
||||
{
|
||||
var delimiterIndex = positionString.IndexOf(':');
|
||||
if (delimiterIndex <= 0)
|
||||
throw new JsonReaderException($"Expected {nameof(SourcePosition)} formatted as line:column");
|
||||
|
||||
var line = int.Parse(positionString.Substring(0, delimiterIndex));
|
||||
var column = int.Parse(positionString.Substring(delimiterIndex + 1));
|
||||
return new SourcePosition(line, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user