using System; using System.Globalization; namespace AspClassic.Scripting; [Serializable] public struct SourceLocation { private readonly int _index; private readonly int _line; private readonly int _column; public static readonly SourceLocation None = new SourceLocation(0, 16707566, 0, noChecks: true); public static readonly SourceLocation Invalid = new SourceLocation(0, 0, 0, noChecks: true); public static readonly SourceLocation MinValue = new SourceLocation(0, 1, 1); public int Index => _index; public int Line => _line; public int Column => _column; public bool IsValid { get { if (_line != 0) { return _column != 0; } return false; } } public SourceLocation(int index, int line, int column) { ValidateLocation(index, line, column); _index = index; _line = line; _column = column; } private static void ValidateLocation(int index, int line, int column) { if (index < 0) { throw ErrorOutOfRange("index", 0); } if (line < 1) { throw ErrorOutOfRange("line", 1); } if (column < 1) { throw ErrorOutOfRange("column", 1); } } private static Exception ErrorOutOfRange(object p0, object p1) { return new ArgumentOutOfRangeException($"{p0} must be greater than or equal to {p1}"); } private SourceLocation(int index, int line, int column, bool noChecks) { _index = index; _line = line; _column = column; } public static bool operator ==(SourceLocation left, SourceLocation right) { if (left._index == right._index && left._line == right._line) { return left._column == right._column; } return false; } public static bool operator !=(SourceLocation left, SourceLocation right) { if (left._index == right._index && left._line == right._line) { return left._column != right._column; } return true; } public static bool operator <(SourceLocation left, SourceLocation right) { return left._index < right._index; } public static bool operator >(SourceLocation left, SourceLocation right) { return left._index > right._index; } public static bool operator <=(SourceLocation left, SourceLocation right) { return left._index <= right._index; } public static bool operator >=(SourceLocation left, SourceLocation right) { return left._index >= right._index; } public static int Compare(SourceLocation left, SourceLocation right) { if (left < right) { return -1; } if (right > left) { return 1; } return 0; } public override bool Equals(object obj) { if (!(obj is SourceLocation sourceLocation)) { return false; } if (sourceLocation._index == _index && sourceLocation._line == _line) { return sourceLocation._column == _column; } return false; } public override int GetHashCode() { return (_line << 16) ^ _column; } public override string ToString() { return "(" + _line + "," + _column + ")"; } internal string ToDebugString() { return string.Format(CultureInfo.CurrentCulture, "({0},{1},{2})", new object[3] { _index, _line, _column }); } }