| File: Text\TextLineCollection.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// 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; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.Text { /// <summary> /// Abstract base class for <see cref="TextLine"/> collections. /// </summary> public abstract class TextLineCollection : IReadOnlyList<TextLine> { /// <summary> /// The count of <see cref="TextLine"/> items in the collection /// </summary> public abstract int Count { get; } /// <summary> /// Gets the <see cref="TextLine"/> item at the specified index. /// </summary> public abstract TextLine this[int index] { get; } /// <summary> /// The index of the TextLine that encompasses the character position. /// </summary> public abstract int IndexOf(int position); /// <summary> /// Gets a <see cref="TextLine"/> that encompasses the character position. /// </summary> /// <param name="position"></param> /// <returns></returns> public virtual TextLine GetLineFromPosition(int position) { return this[this.IndexOf(position)]; } /// <summary> /// Gets a <see cref="LinePosition"/> corresponding to a character position. /// </summary> public virtual LinePosition GetLinePosition(int position) { var line = GetLineFromPosition(position); return new LinePosition(line.LineNumber, position - line.Start); } /// <summary> /// Convert a <see cref="TextSpan"/> to a <see cref="LinePositionSpan"/>. /// </summary> public LinePositionSpan GetLinePositionSpan(TextSpan span) { return new LinePositionSpan(GetLinePosition(span.Start), GetLinePosition(span.End)); } /// <summary> /// Convert a <see cref="LinePosition"/> to a position. /// </summary> public int GetPosition(LinePosition position) { if (position.Line >= this.Count) { throw new ArgumentOutOfRangeException(nameof(position.Line), string.Format(CodeAnalysisResources.LineCannotBeGreaterThanEnd, position.Line, this.Count)); } return this[position.Line].Start + position.Character; } /// <summary> /// Convert a <see cref="LinePositionSpan"/> to <see cref="TextSpan"/>. /// </summary> public TextSpan GetTextSpan(LinePositionSpan span) { return TextSpan.FromBounds(GetPosition(span.Start), GetPosition(span.End)); } public Enumerator GetEnumerator() { return new Enumerator(this); } IEnumerator<TextLine> IEnumerable<TextLine>.GetEnumerator() { return this.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } [SuppressMessage("Performance", "CA1067", Justification = "Equality not actually implemented")] public struct Enumerator : IEnumerator<TextLine>, IEnumerator { private readonly TextLineCollection _lines; private int _index; internal Enumerator(TextLineCollection lines, int index = -1) { _lines = lines; _index = index; } public TextLine Current { get { var ndx = _index; if (ndx >= 0 && ndx < _lines.Count) { return _lines[ndx]; } else { return default(TextLine); } } } public bool MoveNext() { if (_index < _lines.Count - 1) { _index = _index + 1; return true; } return false; } object IEnumerator.Current { get { return this.Current; } } bool IEnumerator.MoveNext() { return this.MoveNext(); } void IEnumerator.Reset() { } void IDisposable.Dispose() { } public override bool Equals(object? obj) { throw new NotSupportedException(); } public override int GetHashCode() { throw new NotSupportedException(); } } } }