2007-01-14 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / GroupingCollection.cs
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
29 #if NET_2_0
30
31 using System.Collections;
32 using System.Collections.Generic;
33
34 namespace Microsoft.Build.BuildEngine {
35         internal class GroupingCollection : IEnumerable {
36                 
37                 int     imports;
38                 int     itemGroups;
39                 Project project;
40                 int     propertyGroups;
41                 int     chooses;
42
43                 LinkedList <object>     list;
44                 LinkedListNode <object> add_iterator;
45         
46                 public GroupingCollection (Project project)
47                 {
48                         list = new LinkedList <object> ();
49                         add_iterator = null;
50                         this.project = project;
51                 }
52
53                 public IEnumerator GetChooseEnumerator ()
54                 {
55                         foreach (object o in list)
56                                 if (o is BuildChoose)
57                                         yield return o;
58                 }
59
60                 public IEnumerator GetEnumerator ()
61                 {
62                         return list.GetEnumerator ();
63                 }
64
65                 public IEnumerator GetImportEnumerator ()
66                 {
67                         foreach (object o in list)
68                                 if (o is Import)
69                                         yield return o;
70                 }
71
72                 public IEnumerator GetItemGroupAndChooseEnumerator ()
73                 {
74                         foreach (object o in list)
75                                 if (o is BuildItemGroup || o is BuildPropertyGroup)
76                                         yield return o;
77                 }
78
79                 public IEnumerator GetItemGroupEnumerator ()
80                 {
81                         foreach (object o in list)
82                                 if (o is BuildItemGroup)
83                                         yield return o;
84                 }
85
86                 public IEnumerator GetPropertyGroupAndChooseEnumerator ()
87                 {
88                         foreach (object o in list)
89                                 if (o is BuildPropertyGroup || o is BuildChoose)
90                                         yield return o;
91                 }
92
93                 public IEnumerator GetPropertyGroupEnumerator ()
94                 {
95                         foreach (object o in list)
96                                 if (o is BuildPropertyGroup)
97                                         yield return o;
98                 }
99                 
100                 internal void Add (BuildPropertyGroup bpg)
101                 {
102                         bpg.GroupingCollection = this;
103                         propertyGroups++;
104                         if (add_iterator == null)
105                                 list.AddLast (bpg);
106                         else {
107                                 list.AddAfter (add_iterator, bpg);
108                                 add_iterator = add_iterator.Next;
109                         }
110                 }
111                 
112                 internal void Add (BuildItemGroup big)
113                 {
114                         itemGroups++;
115                         if (add_iterator == null)
116                                 list.AddLast (big);
117                         else {
118                                 list.AddAfter (add_iterator, big);
119                                 add_iterator = add_iterator.Next;
120                         }
121                 }
122                 
123                 internal void Add (BuildChoose bc)
124                 {
125                         chooses++;
126                         if (add_iterator == null)
127                                 list.AddLast (bc);
128                         else {
129                                 list.AddAfter (add_iterator, bc);
130                                 add_iterator = add_iterator.Next;
131                         }
132                 }
133
134                 internal void Add (Import import)
135                 {
136                         imports++;
137                         if (add_iterator == null)
138                                 list.AddLast (import);
139                         else {
140                                 list.AddAfter (add_iterator, import);
141                                 add_iterator = add_iterator.Next;
142                         }
143                 }
144
145                 internal void Remove (BuildItemGroup big)
146                 {
147                         big.Detach ();
148                         list.Remove (big);
149                 }
150
151                 internal void Remove (BuildPropertyGroup bpg)
152                 {
153                         // FIXME: add bpg.Detach ();
154                         bpg.XmlElement.ParentNode.RemoveChild (bpg.XmlElement);
155                         list.Remove (bpg);
156                 }
157
158                 internal void Evaluate ()
159                 {
160                         Evaluate (EvaluationType.Property);
161                         Evaluate (EvaluationType.Item);
162                 }
163
164                 void Evaluate (EvaluationType type)
165                 {
166                         BuildItemGroup big;
167                         BuildPropertyGroup bpg;
168                         Import import;
169                         LinkedListNode <object> evaluate_iterator;
170
171                         if (type == EvaluationType.Property) {
172                                 evaluate_iterator = list.First;
173                                 add_iterator = list.First;
174
175                                 while (evaluate_iterator != null) {
176                                         if (evaluate_iterator.Value is BuildPropertyGroup) {
177                                                 bpg = (BuildPropertyGroup) evaluate_iterator.Value;
178                                                 if (ConditionParser.ParseAndEvaluate (bpg.Condition, project))
179                                                         bpg.Evaluate ();
180                                         } else if (evaluate_iterator.Value is Import) {
181                                                 import = (Import) evaluate_iterator.Value;
182                                                 if (ConditionParser.ParseAndEvaluate (import.Condition, project))
183                                                         import.Evaluate ();
184                                         }
185
186                                         // if it wasn't moved by adding anything because of evaluating a Import shift it
187                                         if (add_iterator == evaluate_iterator)
188                                                 add_iterator = add_iterator.Next;
189
190                                         evaluate_iterator = evaluate_iterator.Next;
191                                 }
192                         } else {
193                                 evaluate_iterator = list.First;
194                                 add_iterator = list.First;
195
196                                 while (evaluate_iterator != null) {
197                                         if (evaluate_iterator.Value is BuildItemGroup) {
198                                                 big = (BuildItemGroup) evaluate_iterator.Value;
199                                                 if (ConditionParser.ParseAndEvaluate (big.Condition, project))
200                                                         big.Evaluate ();
201                                         }
202
203                                         evaluate_iterator = evaluate_iterator.Next;
204                                 }
205                         }
206
207                         add_iterator = null;
208                 }
209
210                 internal int Imports {
211                         get { return this.imports; }
212                 }
213                 
214                 internal int ItemGroups {
215                         get { return this.itemGroups; }
216                 }
217                 
218                 internal int PropertyGroups {
219                         get { return this.propertyGroups; }
220                 }
221                 
222                 internal int Chooses {
223                         get { return this.chooses; }
224                 } 
225         }
226
227         enum EvaluationType {
228                 Property,
229                 Item
230         }
231 }
232
233 #endif