|
// 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()
{ }
}
}
}
}
|