PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Boo.Lang.Compiler/Ast/NodeCollection.cs

https://github.com/boo/boo-lang
C# | 348 lines | 271 code | 45 blank | 32 comment | 31 complexity | fca4ee07a99e872573d367ca69f0b232 MD5 | raw file
Possible License(s): GPL-2.0
  1. #region license
  2. // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without modification,
  6. // are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Rodrigo B. de Oliveira nor the names of its
  14. // contributors may be used to endorse or promote products derived from this
  15. // software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  21. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #endregion
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using Boo.Lang;
  32. namespace Boo.Lang.Compiler.Ast
  33. {
  34. /// <summary>
  35. /// Node collection base class.
  36. /// </summary>
  37. public class NodeCollection<T> : ICollection, ICloneable, IEnumerable<T>
  38. where T : Node
  39. {
  40. protected Node _parent;
  41. protected List<T> _list;
  42. protected NodeCollection()
  43. {
  44. _list = new List<T>();
  45. }
  46. protected NodeCollection(Node parent)
  47. {
  48. _parent = parent;
  49. _list = new List<T>();
  50. }
  51. protected NodeCollection(Node parent, IEnumerable<T> list)
  52. {
  53. if (null == list) throw new ArgumentNullException("list");
  54. _parent = parent;
  55. _list = new List<T>(list);
  56. }
  57. public T this[int index]
  58. {
  59. get { return (T)_list[index]; }
  60. set { _list[index] = value; }
  61. }
  62. public IEnumerator<T> GetEnumerator()
  63. {
  64. foreach (T item in _list) yield return item;
  65. }
  66. public int Count
  67. {
  68. get { return _list.Count; }
  69. }
  70. public bool IsSynchronized
  71. {
  72. get { return false; }
  73. }
  74. public object SyncRoot
  75. {
  76. get { return this; }
  77. }
  78. public void CopyTo(Array array, int index)
  79. {
  80. ((ICollection)_list).CopyTo(array, index);
  81. }
  82. IEnumerator IEnumerable.GetEnumerator()
  83. {
  84. return _list.GetEnumerator();
  85. }
  86. public void Clear()
  87. {
  88. _list.Clear();
  89. }
  90. public T[] ToArray()
  91. {
  92. return (T[])_list.ToArray(new T[_list.Count]);
  93. }
  94. public T[] ToReverseArray()
  95. {
  96. T[] array = ToArray();
  97. Array.Reverse(array);
  98. return array;
  99. }
  100. public T[] Select(NodeType type)
  101. {
  102. List result = new List();
  103. foreach (Node node in _list)
  104. {
  105. if (node.NodeType == type)
  106. {
  107. result.Add(node);
  108. }
  109. }
  110. return (T[])result.ToArray(new T[result.Count]);
  111. }
  112. protected IEnumerable InternalPopRange(int begin)
  113. {
  114. return _list.PopRange(begin);
  115. }
  116. public bool ContainsNode(T node)
  117. {
  118. foreach (T n in _list)
  119. {
  120. if (n == node) return true;
  121. }
  122. return false;
  123. }
  124. public bool Contains(System.Predicate<T> condition)
  125. {
  126. return _list.Contains(condition);
  127. }
  128. public bool ContainsEntity(Boo.Lang.Compiler.TypeSystem.IEntity entity)
  129. {
  130. foreach (T node in _list)
  131. {
  132. if (entity == node.Entity)
  133. {
  134. return true;
  135. }
  136. }
  137. return false;
  138. }
  139. public Node RemoveByEntity(Boo.Lang.Compiler.TypeSystem.IEntity entity)
  140. {
  141. if (null == entity)
  142. {
  143. throw new ArgumentNullException("entity");
  144. }
  145. for (int i = 0; i < _list.Count; ++i)
  146. {
  147. Node node = (Node)_list[i];
  148. if (entity == node.Entity)
  149. {
  150. _list.RemoveAt(i);
  151. return node;
  152. }
  153. }
  154. return null;
  155. }
  156. public object Clone()
  157. {
  158. NodeCollection<T> clone = (NodeCollection<T>)Activator.CreateInstance(GetType());
  159. List<T> cloneList = clone._list;
  160. foreach (T node in _list)
  161. {
  162. cloneList.Add((T)node.CloneNode());
  163. }
  164. return clone;
  165. }
  166. public void ClearTypeSystemBindings()
  167. {
  168. foreach (T node in _list)
  169. {
  170. node.ClearTypeSystemBindings();
  171. }
  172. }
  173. protected List<T> InnerList
  174. {
  175. get
  176. {
  177. return _list;
  178. }
  179. }
  180. internal void InitializeParent(Node parent)
  181. {
  182. _parent = parent;
  183. foreach (T node in _list)
  184. {
  185. node.InitializeParent(_parent);
  186. }
  187. }
  188. public void Reject(System.Predicate<T> condition)
  189. {
  190. if (null == condition)
  191. {
  192. throw new ArgumentNullException("condition");
  193. }
  194. int index = 0;
  195. foreach (T node in ToArray())
  196. {
  197. if (condition(node))
  198. {
  199. RemoveAt(index);
  200. }
  201. else
  202. {
  203. ++index;
  204. }
  205. }
  206. }
  207. public void RemoveAt(int index)
  208. {
  209. //Node existing = (Node)InnerList[index];
  210. //existing.InitializeParent(null);
  211. InnerList.RemoveAt(index);
  212. }
  213. public void ExtendWithClones(IEnumerable<T> items)
  214. {
  215. foreach (T item in items)
  216. {
  217. InnerList.Add((T)item.CloneNode());
  218. }
  219. }
  220. public void ReplaceAt(int i, T newItem)
  221. {
  222. //Node existing = (Node)InnerList[i];
  223. //existing.InitializeParent(null);
  224. _list[i] = newItem;
  225. Initialize(newItem);
  226. }
  227. public void Add(T item)
  228. {
  229. Initialize(item);
  230. _list.Add(item);
  231. }
  232. public void Extend(IEnumerable<T> items)
  233. {
  234. AssertNotNull("items", items);
  235. foreach (T item in items)
  236. {
  237. Add(item);
  238. }
  239. }
  240. public bool Replace(T existing, T newItem)
  241. {
  242. AssertNotNull("existing", existing);
  243. for (int i = 0; i < _list.Count; ++i)
  244. {
  245. if (this[i] == existing)
  246. {
  247. if (null == newItem)
  248. {
  249. RemoveAt(i);
  250. }
  251. else
  252. {
  253. ReplaceAt(i, newItem);
  254. }
  255. return true;
  256. }
  257. }
  258. return false;
  259. }
  260. public void Insert(int index, T item)
  261. {
  262. Initialize(item);
  263. InnerList.Insert(index, item);
  264. }
  265. public void Remove(T item)
  266. {
  267. InnerList.Remove(item);
  268. }
  269. override public int GetHashCode()
  270. {
  271. return base.GetHashCode();
  272. }
  273. override public bool Equals(object rhs)
  274. {
  275. NodeCollection<T> other = rhs as NodeCollection<T>;
  276. if (null == other) return false;
  277. if (InnerList.Count != other.Count) return false;
  278. IEnumerator<T> enumerator = other.GetEnumerator();
  279. foreach (T mine in this)
  280. {
  281. if (!enumerator.MoveNext()) return false;
  282. if (!mine.Equals(enumerator.Current)) return false;
  283. }
  284. return true;
  285. }
  286. void Initialize(Node item)
  287. {
  288. AssertNotNull("item", item);
  289. if (null != _parent)
  290. {
  291. item.InitializeParent(_parent);
  292. }
  293. }
  294. private void AssertNotNull(string descrip, object o)
  295. {
  296. if (o == null)
  297. {
  298. throw new ArgumentException(
  299. String.Format("null reference for: {0}", descrip));
  300. }
  301. }
  302. }
  303. }