* Makefile ($(build_lib)): Make CYCLIC_DEP_FILES depend on this.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildItemGroup.cs
1 //
2 // BuildItemGroup.cs: Represents a group of build items.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2005 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 #if NET_2_0
29
30 using System;
31 using System.Reflection;
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.Xml;
35 using Microsoft.Build.Framework;
36 using Microsoft.Build.Utilities;
37
38 namespace Microsoft.Build.BuildEngine {
39         public class BuildItemGroup : IEnumerable {
40         
41                 List <BuildItem>        buildItems;
42                 ImportedProject         importedProject;
43                 XmlElement              itemGroupElement;
44                 GroupingCollection      parentCollection;
45                 Project                 parentProject;
46                 bool                    read_only;
47
48                 public BuildItemGroup ()
49                         : this (null, null, null, false)
50                 {
51                 }
52
53                 internal BuildItemGroup (Project project)
54                         : this (null, project, null, false)
55                 {
56                 }
57
58                 internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
59                 {
60                         this.buildItems = new List <BuildItem> ();
61                         this.importedProject = importedProject;
62                         this.itemGroupElement = xmlElement;
63                         this.parentProject = project;
64                         this.read_only = readOnly;
65                         
66                         if (!FromXml)
67                                 return;
68
69                         foreach (XmlNode xn in xmlElement.ChildNodes) {
70                                 if (!(xn is XmlElement))
71                                         continue;
72                                         
73                                 XmlElement xe = (XmlElement) xn;
74                                 BuildItem bi = new BuildItem (xe, this);
75                                 buildItems.Add (bi);
76                                 project.LastItemGroupContaining [bi.Name] = this;
77                         }
78                 }
79
80                 public BuildItem AddNewItem (string itemName,
81                                              string itemInclude)
82                 {
83                         return AddNewItem (itemName, itemInclude, false);
84                 }
85                 
86                 [MonoTODO]
87                 public BuildItem AddNewItem (string itemName,
88                                              string itemInclude,
89                                              bool treatItemIncludeAsLiteral)
90                 {
91                         BuildItem item;
92
93                         if (treatItemIncludeAsLiteral)
94                                 itemInclude = Utilities.Escape (itemInclude);
95
96                         if (FromXml) {
97                                 XmlElement element = itemGroupElement.OwnerDocument.CreateElement (itemName, Project.XmlNamespace);
98                                 itemGroupElement.AppendChild (element);
99                                 element.SetAttribute ("Include", itemInclude);
100                                 item = new BuildItem (element, this);
101                         } else {
102                                 item = new BuildItem (itemName, itemInclude);
103                                 item.ParentItemGroup = this;
104                         }
105
106                         item.Evaluate (null, true);
107
108                         if (!read_only)
109                                 buildItems.Add (item);
110
111                         if (parentProject != null) {
112                                 parentProject.MarkProjectAsDirty ();
113                                 parentProject.NeedToReevaluate ();
114                         }
115
116                         return item;
117                 }
118                 
119                 public void Clear ()
120                 {
121                         if (FromXml)
122                                 itemGroupElement.RemoveAll ();
123                         
124                         buildItems = new List <BuildItem> ();
125
126                         if (parentProject != null) {
127                                 parentProject.MarkProjectAsDirty ();
128                                 parentProject.NeedToReevaluate ();
129                         }
130                 }
131
132                 [MonoTODO]
133                 public BuildItemGroup Clone (bool deepClone)
134                 {
135                         if (deepClone) {
136                                 if (FromXml)
137                                         throw new NotImplementedException ();
138                                 else
139                                         throw new NotImplementedException ();
140                         } else {
141                                 if (FromXml)
142                                         throw new InvalidOperationException ("A shallow clone of this object cannot be created.");
143                                 else
144                                         throw new NotImplementedException ();
145                         }
146                 }
147
148                 public IEnumerator GetEnumerator ()
149                 {
150                         return buildItems.GetEnumerator ();
151                 }
152
153                 public void RemoveItem (BuildItem itemToRemove)
154                 {
155                         if (itemToRemove == null)
156                                 return;
157
158                         itemToRemove.Detach ();
159
160                         buildItems.Remove (itemToRemove);
161                 }
162
163                 public void RemoveItemAt (int index)
164                 {
165                         BuildItem item = buildItems [index];
166
167                         RemoveItem (item);
168                 }
169
170                 public BuildItem[] ToArray ()
171                 {
172                         return buildItems.ToArray ();
173                 }
174
175                 internal void AddItem (BuildItem buildItem)
176                 {
177                         buildItems.Add (buildItem);
178                 }
179
180                 internal void AddItem (string name, ITaskItem taskItem)
181                 {
182                         BuildItem buildItem;
183                         buildItem = new BuildItem (name, taskItem);
184                         buildItem.ParentItemGroup = this;
185                         buildItems.Add (buildItem);
186                 }
187
188                 internal string ConvertToString (Expression transform,
189                                                  Expression separator)
190                 {
191                         string separatorString;
192                         
193                         if (separator == null)
194                                 separatorString = ";";
195                         else
196                                 separatorString = (string) separator.ConvertTo (parentProject, typeof (string));
197                 
198                         string[] items = new string [buildItems.Count];
199                         int i = 0;
200                         foreach (BuildItem bi in  buildItems)
201                                 items [i++] = bi.ConvertToString (transform);
202                         return String.Join (separatorString, items);
203                 }
204
205                 internal ITaskItem[] ConvertToITaskItemArray (Expression transform)
206                 {
207                         ITaskItem[] array = new ITaskItem [buildItems.Count];
208                         int i = 0;
209                         foreach (BuildItem item in buildItems)
210                                 array [i++] = item.ConvertToITaskItem (transform);
211                         return array;
212                 }
213
214                 internal void Detach ()
215                 {
216                         if (!FromXml)
217                                 throw new InvalidOperationException ();
218
219                         itemGroupElement.ParentNode.RemoveChild (itemGroupElement);
220                 }
221
222                 internal void Evaluate ()
223                 {
224                         foreach (BuildItem bi in buildItems) {
225                                 if (bi.Condition == String.Empty)
226                                         bi.Evaluate (parentProject, true);
227                                 else {
228                                         ConditionExpression ce = ConditionParser.ParseCondition (bi.Condition);
229                                         bi.Evaluate (parentProject, ce.BoolEvaluate (parentProject));
230                                 }
231                         }
232                 }               
233
234                 internal void ReplaceWith (BuildItem item, List <BuildItem> list)
235                 {
236                         int index = buildItems.IndexOf (item);
237                         buildItems.RemoveAt (index);
238                         buildItems.InsertRange (index, list);
239                 }
240                 
241                 public string Condition {
242                         get {
243                                 if (FromXml)
244                                         return itemGroupElement.GetAttribute ("Condition");
245                                 else
246                                         return String.Empty;
247                         }
248                         set {
249                                 if (FromXml)
250                                         itemGroupElement.SetAttribute ("Condition", value);
251                                 else
252                                         throw new InvalidOperationException ("Cannot set a condition on an object not represented by an XML element in the project file.");
253                         }
254                 }
255
256                 public int Count {
257                         get { return buildItems.Count; }
258                 }
259
260                 public bool IsImported {
261                         get { return importedProject != null; }
262                 }
263
264                 
265                 [MonoTODO]
266                 public BuildItem this [int index] {
267                         get {
268                                 return buildItems [index];
269                         }
270                 }
271                 
272                 internal GroupingCollection GroupingCollection {
273                         get { return parentCollection; }
274                         set { parentCollection = value; }
275                 }
276                 
277                 internal Project ParentProject {
278                         get { return parentProject; }
279                         set {
280                                 if (parentProject != null)
281                                         throw new InvalidOperationException ("parentProject is already set");
282                                 parentProject = value;
283                         }
284                 }
285
286                 internal bool FromXml {
287                         get {
288                                 return itemGroupElement != null;
289                         }
290                 }
291
292                 internal XmlElement XmlElement {
293                         get {
294                                 return itemGroupElement;
295                         }       
296                 }
297         }
298 }
299
300 #endif