PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/GroupingCollection.cs

https://bitbucket.org/danipen/mono
C# | 269 lines | 205 code | 35 blank | 29 comment | 47 complexity | 83317b71a6d5d0330a6b4553657a0b3e MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // GroupingCollection.cs: Represents group of BuildItemGroup,
  3. // BuildPropertyGroup and BuildChoose.
  4. //
  5. // Author:
  6. // Marek Sieradzki (marek.sieradzki@gmail.com)
  7. //
  8. // (C) 2005 Marek Sieradzki
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. namespace Microsoft.Build.BuildEngine {
  32. internal class GroupingCollection : IEnumerable {
  33. int imports;
  34. int itemGroups;
  35. Project project;
  36. int propertyGroups;
  37. int chooses;
  38. LinkedList <object> list;
  39. LinkedListNode <object> add_iterator;
  40. public GroupingCollection (Project project)
  41. {
  42. list = new LinkedList <object> ();
  43. add_iterator = null;
  44. this.project = project;
  45. }
  46. public IEnumerator GetChooseEnumerator ()
  47. {
  48. foreach (object o in list)
  49. if (o is BuildChoose)
  50. yield return o;
  51. }
  52. public IEnumerator GetEnumerator ()
  53. {
  54. return list.GetEnumerator ();
  55. }
  56. public IEnumerator GetImportEnumerator ()
  57. {
  58. foreach (object o in list)
  59. if (o is Import)
  60. yield return o;
  61. }
  62. public IEnumerator GetItemGroupAndChooseEnumerator ()
  63. {
  64. foreach (object o in list)
  65. if (o is BuildItemGroup || o is BuildPropertyGroup)
  66. yield return o;
  67. }
  68. public IEnumerator GetItemGroupEnumerator ()
  69. {
  70. foreach (object o in list)
  71. if (o is BuildItemGroup)
  72. yield return o;
  73. }
  74. public IEnumerator GetPropertyGroupAndChooseEnumerator ()
  75. {
  76. foreach (object o in list)
  77. if (o is BuildPropertyGroup || o is BuildChoose)
  78. yield return o;
  79. }
  80. public IEnumerator GetPropertyGroupEnumerator ()
  81. {
  82. foreach (object o in list)
  83. if (o is BuildPropertyGroup)
  84. yield return o;
  85. }
  86. internal void Add (BuildPropertyGroup bpg)
  87. {
  88. bpg.GroupingCollection = this;
  89. propertyGroups++;
  90. if (add_iterator == null)
  91. list.AddLast (bpg);
  92. else {
  93. list.AddAfter (add_iterator, bpg);
  94. add_iterator = add_iterator.Next;
  95. }
  96. }
  97. internal void Add (BuildItemGroup big)
  98. {
  99. itemGroups++;
  100. if (add_iterator == null)
  101. list.AddLast (big);
  102. else {
  103. list.AddAfter (add_iterator, big);
  104. add_iterator = add_iterator.Next;
  105. }
  106. }
  107. internal void Add (BuildChoose bc)
  108. {
  109. chooses++;
  110. if (add_iterator == null)
  111. list.AddLast (bc);
  112. else {
  113. list.AddAfter (add_iterator, bc);
  114. add_iterator = add_iterator.Next;
  115. }
  116. }
  117. internal void Add (Import import)
  118. {
  119. imports++;
  120. if (add_iterator == null)
  121. list.AddLast (import);
  122. else {
  123. list.AddAfter (add_iterator, import);
  124. add_iterator = add_iterator.Next;
  125. }
  126. }
  127. internal void Remove (BuildItemGroup big)
  128. {
  129. if (big.ParentProject != project)
  130. throw new InvalidOperationException (
  131. "The \"BuildItemGroup\" object specified does not belong to the correct \"Project\" object.");
  132. big.Detach ();
  133. list.Remove (big);
  134. }
  135. internal void Remove (BuildPropertyGroup bpg)
  136. {
  137. // FIXME: add bpg.Detach ();
  138. bpg.XmlElement.ParentNode.RemoveChild (bpg.XmlElement);
  139. list.Remove (bpg);
  140. }
  141. internal void Evaluate ()
  142. {
  143. Evaluate (EvaluationType.Property);
  144. Evaluate (EvaluationType.Item);
  145. Evaluate (EvaluationType.Choose);
  146. }
  147. internal void Evaluate (EvaluationType type)
  148. {
  149. BuildItemGroup big;
  150. BuildPropertyGroup bpg;
  151. LinkedListNode <object> evaluate_iterator;
  152. if (type == EvaluationType.Property) {
  153. evaluate_iterator = list.First;
  154. add_iterator = list.First;
  155. while (evaluate_iterator != null) {
  156. if (evaluate_iterator.Value is BuildPropertyGroup) {
  157. bpg = (BuildPropertyGroup) evaluate_iterator.Value;
  158. project.PushThisFileProperty (bpg.DefinedInFileName);
  159. try {
  160. if (ConditionParser.ParseAndEvaluate (bpg.Condition, project))
  161. bpg.Evaluate ();
  162. } finally {
  163. project.PopThisFileProperty ();
  164. }
  165. }
  166. // if it wasn't moved by adding anything because of evaluating a Import shift it
  167. if (add_iterator == evaluate_iterator)
  168. add_iterator = add_iterator.Next;
  169. evaluate_iterator = evaluate_iterator.Next;
  170. }
  171. } else if (type == EvaluationType.Item) {
  172. evaluate_iterator = list.First;
  173. add_iterator = list.First;
  174. while (evaluate_iterator != null) {
  175. if (evaluate_iterator.Value is BuildItemGroup) {
  176. big = (BuildItemGroup) evaluate_iterator.Value;
  177. project.PushThisFileProperty (big.DefinedInFileName);
  178. try {
  179. if (ConditionParser.ParseAndEvaluate (big.Condition, project))
  180. big.Evaluate ();
  181. } finally {
  182. project.PopThisFileProperty ();
  183. }
  184. }
  185. evaluate_iterator = evaluate_iterator.Next;
  186. }
  187. } else if (type == EvaluationType.Choose) {
  188. evaluate_iterator = list.First;
  189. add_iterator = list.First;
  190. while (evaluate_iterator != null) {
  191. if (evaluate_iterator.Value is BuildChoose) {
  192. BuildChoose bc = (BuildChoose)evaluate_iterator.Value;
  193. project.PushThisFileProperty (bc.DefinedInFileName);
  194. try {
  195. bool whenUsed = false;
  196. foreach (BuildWhen bw in bc.Whens) {
  197. if (ConditionParser.ParseAndEvaluate (bw.Condition, project)) {
  198. bw.Evaluate ();
  199. whenUsed = true;
  200. break;
  201. }
  202. }
  203. if (!whenUsed && bc.Otherwise != null &&
  204. ConditionParser.ParseAndEvaluate (bc.Otherwise.Condition, project)) {
  205. bc.Otherwise.Evaluate ();
  206. }
  207. } finally {
  208. project.PopThisFileProperty ();
  209. }
  210. }
  211. evaluate_iterator = evaluate_iterator.Next;
  212. }
  213. }
  214. add_iterator = null;
  215. }
  216. internal int Imports {
  217. get { return this.imports; }
  218. }
  219. internal int ItemGroups {
  220. get { return this.itemGroups; }
  221. }
  222. internal int PropertyGroups {
  223. get { return this.propertyGroups; }
  224. }
  225. internal int Chooses {
  226. get { return this.chooses; }
  227. }
  228. }
  229. enum EvaluationType {
  230. Property,
  231. Item,
  232. Choose
  233. }
  234. }