57 lines
1.6 KiB
C#
57 lines
1.6 KiB
C#
namespace NubLang.Code;
|
|
|
|
public readonly struct SourceSpan : IEquatable<SourceSpan>
|
|
{
|
|
public static SourceSpan Zero => new(SourceLocation.Zero, SourceLocation.Zero);
|
|
|
|
public static SourceSpan Merge(params IEnumerable<SourceSpan> spans)
|
|
{
|
|
var spanArray = spans as SourceSpan[] ?? spans.ToArray();
|
|
|
|
if (spanArray.Length == 0)
|
|
{
|
|
return Zero;
|
|
}
|
|
|
|
var minStart = spanArray.Min(s => s.Start);
|
|
var maxEnd = spanArray.Max(s => s.End);
|
|
|
|
return new SourceSpan(minStart, maxEnd);
|
|
}
|
|
|
|
public SourceSpan(SourceLocation start, SourceLocation end)
|
|
{
|
|
if (start > end)
|
|
{
|
|
throw new ArgumentException("Start location cannot be after end location");
|
|
}
|
|
|
|
Start = start;
|
|
End = end;
|
|
}
|
|
|
|
public SourceLocation Start { get; }
|
|
public SourceLocation End { get; }
|
|
|
|
public override string ToString()
|
|
{
|
|
if (Start == End)
|
|
{
|
|
return $"{Start}";
|
|
}
|
|
|
|
if (Start.Line == End.Line)
|
|
{
|
|
return Start.Column == End.Column ? $"{Start}" : $"{Start.Line}:{Start.Column}-{End.Column}";
|
|
}
|
|
|
|
return $"{Start}-{End}";
|
|
}
|
|
|
|
public bool Equals(SourceSpan other) => Start == other.Start && End == other.End;
|
|
public override bool Equals(object? obj) => obj is SourceSpan other && Equals(other);
|
|
public override int GetHashCode() => HashCode.Combine(typeof(SourceSpan), Start, End);
|
|
|
|
public static bool operator ==(SourceSpan left, SourceSpan right) => Equals(left, right);
|
|
public static bool operator !=(SourceSpan left, SourceSpan right) => !Equals(left, right);
|
|
} |