| File: Language\Syntax\SyntaxTokenList.Reversed.cs | Web Access |
| Project: src\roslyn\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace Microsoft.AspNetCore.Razor.Language.Syntax; internal readonly partial struct SyntaxTokenList { public readonly struct Reversed(SyntaxTokenList list) : IEnumerable<SyntaxToken>, IEquatable<Reversed> { private readonly SyntaxTokenList _list = list; public Enumerator GetEnumerator() => new(in _list); IEnumerator<SyntaxToken> IEnumerable<SyntaxToken>.GetEnumerator() => _list.Count == 0 ? SpecializedCollections.EmptyEnumerator<SyntaxToken>() : new EnumeratorImpl(in _list); IEnumerator IEnumerable.GetEnumerator() => _list.Count == 0 ? SpecializedCollections.EmptyEnumerator<SyntaxToken>() : (IEnumerator)new EnumeratorImpl(in _list); public override bool Equals(object? obj) => obj is Reversed reversed && Equals(reversed); public bool Equals(Reversed other) => _list.Equals(other._list); public override int GetHashCode() => _list.GetHashCode(); public struct Enumerator { private readonly SyntaxNode? _parent; private readonly GreenNode? _singleNodeOrList; private readonly int _baseIndex; private readonly int _count; private int _index; private GreenNode? _current; private int _position; internal Enumerator(in SyntaxTokenList list) : this() { if (list.Any()) { _parent = list._parent; _singleNodeOrList = list.Node; _baseIndex = list._index; _count = list.Count; _index = _count; _current = null; var last = list.Last(); _position = last.Position + last.Width; } } public bool MoveNext() { if (_count == 0 || _index <= 0) { _current = null; return false; } _index--; Debug.Assert(_singleNodeOrList != null); _current = GetGreenNodeAt(_singleNodeOrList, _index); Debug.Assert(_current != null); _position -= _current.Width; return true; } public readonly SyntaxToken Current { get { if (_current == null) { throw new InvalidOperationException(); } return new SyntaxToken(_parent, _current, _position, _baseIndex + _index); } } public override readonly bool Equals(object? obj) => throw new NotSupportedException(); public override readonly int GetHashCode() => throw new NotSupportedException(); } private sealed class EnumeratorImpl : IEnumerator<SyntaxToken> { private Enumerator _enumerator; internal EnumeratorImpl(in SyntaxTokenList list) { _enumerator = new Enumerator(in list); } public SyntaxToken Current => _enumerator.Current; object IEnumerator.Current => _enumerator.Current; public bool MoveNext() => _enumerator.MoveNext(); public void Reset() => throw new NotSupportedException(); public void Dispose() { } } } }