98 lines
3.0 KiB
C#
98 lines
3.0 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace StellaOps.PolicyDsl;
|
|
|
|
/// <summary>
|
|
/// Represents a precise source location within a policy DSL document.
|
|
/// </summary>
|
|
public readonly struct SourceLocation : IEquatable<SourceLocation>, IComparable<SourceLocation>
|
|
{
|
|
public SourceLocation(int offset, int line, int column)
|
|
{
|
|
if (offset < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(offset));
|
|
}
|
|
|
|
if (line < 1)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(line));
|
|
}
|
|
|
|
if (column < 1)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(column));
|
|
}
|
|
|
|
Offset = offset;
|
|
Line = line;
|
|
Column = column;
|
|
}
|
|
|
|
public int Offset { get; }
|
|
|
|
public int Line { get; }
|
|
|
|
public int Column { get; }
|
|
|
|
public override string ToString() => $"(L{Line}, C{Column})";
|
|
|
|
public bool Equals(SourceLocation other) =>
|
|
Offset == other.Offset && Line == other.Line && Column == other.Column;
|
|
|
|
public override bool Equals([NotNullWhen(true)] object? obj) =>
|
|
obj is SourceLocation other && Equals(other);
|
|
|
|
public override int GetHashCode() => HashCode.Combine(Offset, Line, Column);
|
|
|
|
public int CompareTo(SourceLocation other) => Offset.CompareTo(other.Offset);
|
|
|
|
public static bool operator ==(SourceLocation left, SourceLocation right) => left.Equals(right);
|
|
|
|
public static bool operator !=(SourceLocation left, SourceLocation right) => !left.Equals(right);
|
|
|
|
public static bool operator <(SourceLocation left, SourceLocation right) => left.CompareTo(right) < 0;
|
|
|
|
public static bool operator <=(SourceLocation left, SourceLocation right) => left.CompareTo(right) <= 0;
|
|
|
|
public static bool operator >(SourceLocation left, SourceLocation right) => left.CompareTo(right) > 0;
|
|
|
|
public static bool operator >=(SourceLocation left, SourceLocation right) => left.CompareTo(right) >= 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a start/end location pair within a policy DSL source document.
|
|
/// </summary>
|
|
public readonly struct SourceSpan : IEquatable<SourceSpan>
|
|
{
|
|
public SourceSpan(SourceLocation start, SourceLocation end)
|
|
{
|
|
if (start.Offset > end.Offset)
|
|
{
|
|
throw new ArgumentException("Start must not be after end.", nameof(start));
|
|
}
|
|
|
|
Start = start;
|
|
End = end;
|
|
}
|
|
|
|
public SourceLocation Start { get; }
|
|
|
|
public SourceLocation End { get; }
|
|
|
|
public override string ToString() => $"{Start}->{End}";
|
|
|
|
public bool Equals(SourceSpan other) => Start.Equals(other.Start) && End.Equals(other.End);
|
|
|
|
public override bool Equals([NotNullWhen(true)] object? obj) => obj is SourceSpan other && Equals(other);
|
|
|
|
public override int GetHashCode() => HashCode.Combine(Start, End);
|
|
|
|
public static SourceSpan Combine(SourceSpan first, SourceSpan second)
|
|
{
|
|
var start = first.Start <= second.Start ? first.Start : second.Start;
|
|
var end = first.End >= second.End ? first.End : second.End;
|
|
return new SourceSpan(start, end);
|
|
}
|
|
}
|