// 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);
}
}
}