// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Globalization; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Razor.Evolution { /// /// A location in a Razor file. /// public struct SourceLocation : IEquatable { /// /// An undefined . /// public static readonly SourceLocation Undefined = new SourceLocation(absoluteIndex: -1, lineIndex: -1, characterIndex: -1); /// /// A with , , and /// initialized to 0. /// public static readonly SourceLocation Zero = new SourceLocation(absoluteIndex: 0, lineIndex: 0, characterIndex: 0); /// /// Initializes a new instance of . /// /// The absolute index. /// The line index. /// The character index. public SourceLocation(int absoluteIndex, int lineIndex, int characterIndex) : this(filePath: null, absoluteIndex: absoluteIndex, lineIndex: lineIndex, characterIndex: characterIndex) { } /// /// Initializes a new instance of . /// /// The file path. /// The absolute index. /// The line index. /// The character index. public SourceLocation(string filePath, int absoluteIndex, int lineIndex, int characterIndex) { FilePath = filePath; AbsoluteIndex = absoluteIndex; LineIndex = lineIndex; CharacterIndex = characterIndex; } /// /// Path of the file. /// /// /// /// When null, the parser assumes the location is in the file currently being processed. /// /// Set property is only accessible for deserialization purposes. /// public string FilePath { get; set; } /// Set property is only accessible for deserialization purposes. public int AbsoluteIndex { get; set; } /// Set property is only accessible for deserialization purposes. public int LineIndex { get; set; } /// Set property is only accessible for deserialization purposes. public int CharacterIndex { get; set; } /// public override string ToString() { return string.Format( CultureInfo.CurrentCulture, "({0}:{1},{2})", AbsoluteIndex, LineIndex, CharacterIndex); } /// public override bool Equals(object obj) { return obj is SourceLocation && Equals((SourceLocation)obj); } /// public override int GetHashCode() { var hashCodeCombiner = HashCodeCombiner.Start(); hashCodeCombiner.Add(FilePath, StringComparer.Ordinal); hashCodeCombiner.Add(AbsoluteIndex); return hashCodeCombiner; } /// public bool Equals(SourceLocation other) { // LineIndex and CharacterIndex can be calculated from AbsoluteIndex and the document content. return string.Equals(FilePath, other.FilePath, StringComparison.Ordinal) && AbsoluteIndex == other.AbsoluteIndex; } public static bool operator==(SourceLocation left, SourceLocation right) { return left.Equals(right); } public static bool operator !=(SourceLocation left, SourceLocation right) { return !left.Equals(right); } } }