| File: Syntax\ChildSyntaxList.Reversed.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; using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { public readonly partial struct ChildSyntaxList { public readonly partial struct Reversed : IEnumerable<SyntaxNodeOrToken>, IEquatable<Reversed> { private readonly SyntaxNode? _node; private readonly int _count; internal Reversed(SyntaxNode node, int count) { _node = node; _count = count; } public Enumerator GetEnumerator() { Debug.Assert(_node is object); return new Enumerator(_node, _count); } IEnumerator<SyntaxNodeOrToken> IEnumerable<SyntaxNodeOrToken>.GetEnumerator() { if (_node == null) { return SpecializedCollections.EmptyEnumerator<SyntaxNodeOrToken>(); } return new EnumeratorImpl(_node, _count); } IEnumerator IEnumerable.GetEnumerator() { if (_node == null) { return SpecializedCollections.EmptyEnumerator<SyntaxNodeOrToken>(); } return new EnumeratorImpl(_node, _count); } public override int GetHashCode() { return _node != null ? Hash.Combine(_node.GetHashCode(), _count) : 0; } public override bool Equals(object? obj) { return (obj is Reversed r) && Equals(r); } public bool Equals(Reversed other) { return _node == other._node && _count == other._count; } public struct Enumerator { private readonly SyntaxNode? _node; private readonly int _count; private int _childIndex; internal Enumerator(SyntaxNode node, int count) { _node = node; _count = count; _childIndex = count; } [MemberNotNullWhen(true, nameof(_node))] public bool MoveNext() { return --_childIndex >= 0; } public SyntaxNodeOrToken Current { get { Debug.Assert(_node is object); return ItemInternal(_node, _childIndex); } } public void Reset() { _childIndex = _count; } } private class EnumeratorImpl : IEnumerator<SyntaxNodeOrToken> { private Enumerator _enumerator; internal EnumeratorImpl(SyntaxNode node, int count) { _enumerator = new Enumerator(node, count); } /// <summary> /// Gets the element in the collection at the current position of the enumerator. /// </summary> /// <returns> /// The element in the collection at the current position of the enumerator. /// </returns> public SyntaxNodeOrToken Current { get { return _enumerator.Current; } } /// <summary> /// Gets the element in the collection at the current position of the enumerator. /// </summary> /// <returns> /// The element in the collection at the current position of the enumerator. /// </returns> object IEnumerator.Current { get { return _enumerator.Current; } } /// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="InvalidOperationException">The collection was modified after the enumerator was created. </exception> public bool MoveNext() { return _enumerator.MoveNext(); } /// <summary> /// Sets the enumerator to its initial position, which is before the first element in the collection. /// </summary> /// <exception cref="InvalidOperationException">The collection was modified after the enumerator was created. </exception> public void Reset() { _enumerator.Reset(); } /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { } } } } }