File: Syntax\ChildSyntaxList.Reversed.cs
Web Access
Project: src\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 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()
                { }
            }
        }
    }
}