File: Shared\Utilities\VirtualTreePoint.cs
Web Access
Project: ..\..\..\src\EditorFeatures\Core\Microsoft.CodeAnalysis.EditorFeatures.csproj (Microsoft.CodeAnalysis.EditorFeatures)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.Editor.Shared.Utilities
{
    internal readonly struct VirtualTreePoint : IComparable<VirtualTreePoint>, IEquatable<VirtualTreePoint>
    {
        private readonly SyntaxTree _tree;
        private readonly SourceText _text;
        private readonly int _position;
        private readonly int _virtualSpaces;
 
        public VirtualTreePoint(SyntaxTree tree, SourceText text, int position, int virtualSpaces = 0)
        {
            Contract.ThrowIfNull(tree);
            Contract.ThrowIfFalse(position >= 0 && position <= tree.Length);
            Contract.ThrowIfFalse(virtualSpaces >= 0);
 
            _tree = tree;
            _text = text;
            _position = position;
            _virtualSpaces = virtualSpaces;
        }
 
        public static bool operator !=(VirtualTreePoint left, VirtualTreePoint right)
            => !(left == right);
 
        public static bool operator <(VirtualTreePoint left, VirtualTreePoint right)
            => left.CompareTo(right) < 0;
 
        public static bool operator <=(VirtualTreePoint left, VirtualTreePoint right)
            => left.CompareTo(right) <= 0;
 
        public static bool operator ==(VirtualTreePoint left, VirtualTreePoint right)
            => object.Equals(left, right);
 
        public static bool operator >(VirtualTreePoint left, VirtualTreePoint right)
            => left.CompareTo(right) > 0;
 
        public static bool operator >=(VirtualTreePoint left, VirtualTreePoint right)
            => left.CompareTo(right) >= 0;
 
        public bool IsInVirtualSpace
        {
            get { return _virtualSpaces != 0; }
        }
 
        public int Position => _position;
 
        public int VirtualSpaces => _virtualSpaces;
 
        public SourceText Text => _text;
 
        public SyntaxTree Tree => _tree;
 
        public int CompareTo(VirtualTreePoint other)
        {
            if (Text != other.Text)
            {
                throw new InvalidOperationException(EditorFeaturesResources.Can_t_compare_positions_from_different_text_snapshots);
            }
 
            return ComparerWithState.CompareTo(this, other, s_comparers);
        }
 
        private static readonly ImmutableArray<Func<VirtualTreePoint, IComparable>> s_comparers =
            ImmutableArray.Create<Func<VirtualTreePoint, IComparable>>(p => p.Position, prop => prop.VirtualSpaces);
 
        public bool Equals(VirtualTreePoint other)
            => CompareTo(other) == 0;
 
        public override bool Equals(object? obj)
            => (obj is VirtualTreePoint) && Equals((VirtualTreePoint)obj);
 
        public override int GetHashCode()
            => Text.GetHashCode() ^ Position.GetHashCode() ^ VirtualSpaces.GetHashCode();
 
        public override string ToString()
            => $"VirtualTreePoint {{ Tree: '{Tree}', Text: '{Text}', Position: '{Position}', VirtualSpaces '{VirtualSpaces}' }}";
 
        public TextLine GetContainingLine()
            => Text.Lines.GetLineFromPosition(Position);
    }
}