mirror of https://github.com/icsharpcode/ILSpy.git
47 changed files with 335 additions and 236 deletions
@ -0,0 +1,156 @@
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp |
||||
{ |
||||
/// <summary>
|
||||
/// Represents the children of an AstNode that have a specific role.
|
||||
/// </summary>
|
||||
public struct AstNodeCollection<T> : ICollection<T> where T : AstNode |
||||
{ |
||||
readonly AstNode node; |
||||
readonly Role<T> role; |
||||
|
||||
public AstNodeCollection(AstNode node, Role<T> role) |
||||
{ |
||||
if (node == null) |
||||
throw new ArgumentNullException("node"); |
||||
if (role == null) |
||||
throw new ArgumentNullException("role"); |
||||
this.node = node; |
||||
this.role = role; |
||||
} |
||||
|
||||
public int Count { |
||||
get { |
||||
var e = GetEnumerator(); |
||||
int count = 0; |
||||
while (e.MoveNext()) |
||||
count++; |
||||
return count; |
||||
} |
||||
} |
||||
|
||||
public void Add(T element) |
||||
{ |
||||
node.AddChild(element, role); |
||||
} |
||||
|
||||
public void AddRange(IEnumerable<T> nodes) |
||||
{ |
||||
// Evaluate 'nodes' first, since it might change when we add the new children
|
||||
// Example: collection.AddRange(collection);
|
||||
if (nodes != null) { |
||||
foreach (T node in nodes.ToList()) |
||||
Add(node); |
||||
} |
||||
} |
||||
|
||||
public void AddRange(T[] nodes) |
||||
{ |
||||
// Fast overload for arrays - we don't need to create a copy
|
||||
if (nodes != null) { |
||||
foreach (T node in nodes) |
||||
Add(node); |
||||
} |
||||
} |
||||
|
||||
public void ReplaceWith(IEnumerable<T> nodes) |
||||
{ |
||||
// Evaluate 'nodes' first, since it might change when we call Clear()
|
||||
// Example: collection.ReplaceWith(collection);
|
||||
if (nodes != null) |
||||
nodes = nodes.ToList(); |
||||
Clear(); |
||||
foreach (T node in nodes) |
||||
Add(node); |
||||
} |
||||
|
||||
public void MoveTo(ICollection<T> targetCollection) |
||||
{ |
||||
foreach (T node in this) { |
||||
node.Remove(); |
||||
targetCollection.Add(node); |
||||
} |
||||
} |
||||
|
||||
public bool Contains(T element) |
||||
{ |
||||
return element != null && element.Parent == node && element.Role == role; |
||||
} |
||||
|
||||
public bool Remove(T element) |
||||
{ |
||||
if (Contains(element)) { |
||||
element.Remove(); |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) |
||||
{ |
||||
foreach (T item in this) |
||||
array[arrayIndex++] = item; |
||||
} |
||||
|
||||
public void Clear() |
||||
{ |
||||
foreach (T item in this) |
||||
item.Remove(); |
||||
} |
||||
|
||||
bool ICollection<T>.IsReadOnly { |
||||
get { return false; } |
||||
} |
||||
|
||||
public IEnumerator<T> GetEnumerator() |
||||
{ |
||||
AstNode next; |
||||
for (AstNode cur = node.FirstChild; cur != null; cur = next) { |
||||
// Remember next before yielding cur.
|
||||
// This allows removing/replacing nodes while iterating through the list.
|
||||
next = cur.NextSibling; |
||||
if (cur.Role == role) |
||||
yield return (T)cur; |
||||
} |
||||
} |
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() |
||||
{ |
||||
return GetEnumerator(); |
||||
} |
||||
|
||||
#region Equals and GetHashCode implementation
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
if (obj is AstNodeCollection<T>) { |
||||
return ((AstNodeCollection<T>)obj) == this; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return node.GetHashCode() ^ role.GetHashCode(); |
||||
} |
||||
|
||||
public static bool operator ==(AstNodeCollection<T> left, AstNodeCollection<T> right) |
||||
{ |
||||
return left.role == right.role && left.node == right.node; |
||||
} |
||||
|
||||
public static bool operator !=(AstNodeCollection<T> left, AstNodeCollection<T> right) |
||||
{ |
||||
return !(left.role == right.role && left.node == right.node); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
Loading…
Reference in new issue