2007-02-03 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildItemGroup.cs
index 0cb747825ac0a998715d2db143754002ed29fa49..2e39a9dcd466ea7311a376e66715ff76dedf14f2 100644 (file)
@@ -38,23 +38,25 @@ using Microsoft.Build.Utilities;
 namespace Microsoft.Build.BuildEngine {
        public class BuildItemGroup : IEnumerable {
        
-               bool                    isImported;
                List <BuildItem>        buildItems;
+               ImportedProject         importedProject;
+               XmlElement              itemGroupElement;
                GroupingCollection      parentCollection;
                Project                 parentProject;
-               XmlElement              itemGroupElement;
+               bool                    read_only;
 
                public BuildItemGroup ()
-                       : this (null, null)
+                       : this (null, null, null, false)
                {
                }
                
-               internal BuildItemGroup (XmlElement xmlElement, Project project)
+               internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
                {
-                       this.itemGroupElement = xmlElement;
                        this.buildItems = new List <BuildItem> ();
-                       this.isImported = false;
+                       this.importedProject = importedProject;
+                       this.itemGroupElement = xmlElement;
                        this.parentProject = project;
+                       this.read_only = readOnly;
                        
                        if (!FromXml)
                                return;
@@ -66,18 +68,7 @@ namespace Microsoft.Build.BuildEngine {
                                XmlElement xe = (XmlElement) xn;
                                BuildItem bi = new BuildItem (xe, this);
                                buildItems.Add (bi);
-                       }
-               }
-
-               internal void Evaluate ()
-               {
-                       foreach (BuildItem bi in buildItems) {
-                               if (bi.Condition == String.Empty)
-                                       bi.Evaluate (true);
-                               else {
-                                       ConditionExpression ce = ConditionParser.ParseCondition (bi.Condition);
-                                       bi.Evaluate (ce.BoolEvaluate (parentProject));
-                               }
+                               project.LastItemGroupContaining [bi.Name] = this;
                        }
                }
 
@@ -92,34 +83,60 @@ namespace Microsoft.Build.BuildEngine {
                                             string itemInclude,
                                             bool treatItemIncludeAsLiteral)
                {
-                       BuildItem bi = new BuildItem (itemName, itemInclude);
-                       buildItems.Add (bi);
-                       return bi;
-               }
-               
-               internal void AddItem (BuildItem buildItem)
-               {
-                       buildItems.Add (buildItem);
+                       BuildItem item;
+
+                       if (treatItemIncludeAsLiteral)
+                               itemInclude = Utilities.Escape (itemInclude);
+
+                       if (FromXml) {
+                               XmlElement element = itemGroupElement.OwnerDocument.CreateElement (itemName, Project.XmlNamespace);
+                               itemGroupElement.AppendChild (element);
+                               element.SetAttribute ("Include", itemInclude);
+                               item = new BuildItem (element, this);
+                       } else {
+                               item = new BuildItem (itemName, itemInclude);
+                       }
+
+                       item.Evaluate (null, true);
+
+                       if (!read_only)
+                               buildItems.Add (item);
+
+                       if (parentProject != null) {
+                               parentProject.MarkProjectAsDirty ();
+                               parentProject.NeedToReevaluate ();
+                       }
+
+                       return item;
                }
                
-               internal void AddItem (string name, ITaskItem taskItem)
-               {
-                       BuildItem buildItem;
-                       buildItem = new BuildItem (name, taskItem);
-                       buildItems.Add (buildItem);
-               }
-
                public void Clear ()
                {
+                       if (FromXml)
+                               itemGroupElement.RemoveAll ();
+                       
                        buildItems = new List <BuildItem> ();
+
+                       if (parentProject != null) {
+                               parentProject.MarkProjectAsDirty ();
+                               parentProject.NeedToReevaluate ();
+                       }
                }
 
                [MonoTODO]
                public BuildItemGroup Clone (bool deepClone)
                {
-                       BuildItemGroup big = new BuildItemGroup ();
-                       // FIXME: add copying of items
-                       return big;
+                       if (deepClone) {
+                               if (FromXml)
+                                       throw new NotImplementedException ();
+                               else
+                                       throw new NotImplementedException ();
+                       } else {
+                               if (FromXml)
+                                       throw new InvalidOperationException ("A shallow clone of this object cannot be created.");
+                               else
+                                       throw new NotImplementedException ();
+                       }
                }
 
                public IEnumerator GetEnumerator ()
@@ -129,28 +146,47 @@ namespace Microsoft.Build.BuildEngine {
 
                public void RemoveItem (BuildItem itemToRemove)
                {
+                       if (itemToRemove == null)
+                               return;
+
+                       itemToRemove.Detach ();
+
                        buildItems.Remove (itemToRemove);
                }
 
                public void RemoveItemAt (int index)
                {
-                       buildItems.RemoveAt (index);
+                       BuildItem item = buildItems [index];
+
+                       RemoveItem (item);
                }
 
                public BuildItem[] ToArray ()
                {
                        return buildItems.ToArray ();
                }
-               
-               internal string ConvertToString (OldExpression transform,
-                                                OldExpression separator)
+
+               internal void AddItem (BuildItem buildItem)
+               {
+                       buildItems.Add (buildItem);
+               }
+
+               internal void AddItem (string name, ITaskItem taskItem)
+               {
+                       BuildItem buildItem;
+                       buildItem = new BuildItem (name, taskItem);
+                       buildItems.Add (buildItem);
+               }
+
+               internal string ConvertToString (Expression transform,
+                                                Expression separator)
                {
                        string separatorString;
                        
                        if (separator == null)
                                separatorString = ";";
                        else
-                               separatorString = (string) separator.ConvertTo (typeof (string));
+                               separatorString = (string) separator.ConvertTo (parentProject, typeof (string));
                
                        string[] items = new string [buildItems.Count];
                        int i = 0;
@@ -158,8 +194,8 @@ namespace Microsoft.Build.BuildEngine {
                                items [i++] = bi.ConvertToString (transform);
                        return String.Join (separatorString, items);
                }
-               
-               internal ITaskItem[] ConvertToITaskItemArray (OldExpression transform)
+
+               internal ITaskItem[] ConvertToITaskItemArray (Expression transform)
                {
                        ITaskItem[] array = new ITaskItem [buildItems.Count];
                        int i = 0;
@@ -168,8 +204,33 @@ namespace Microsoft.Build.BuildEngine {
                        return array;
                }
 
-               [MonoTODO]
-               // FIXME: whether we can invoke get_Condition on BuildItemGroup not based on XML
+               internal void Detach ()
+               {
+                       if (!FromXml)
+                               throw new InvalidOperationException ();
+
+                       itemGroupElement.ParentNode.RemoveChild (itemGroupElement);
+               }
+
+               internal void Evaluate ()
+               {
+                       foreach (BuildItem bi in buildItems) {
+                               if (bi.Condition == String.Empty)
+                                       bi.Evaluate (parentProject, true);
+                               else {
+                                       ConditionExpression ce = ConditionParser.ParseCondition (bi.Condition);
+                                       bi.Evaluate (parentProject, ce.BoolEvaluate (parentProject));
+                               }
+                       }
+               }               
+
+               internal void ReplaceWith (BuildItem item, List <BuildItem> list)
+               {
+                       int index = buildItems.IndexOf (item);
+                       buildItems.RemoveAt (index);
+                       buildItems.InsertRange (index, list);
+               }
+               
                public string Condition {
                        get {
                                if (FromXml)
@@ -180,6 +241,8 @@ namespace Microsoft.Build.BuildEngine {
                        set {
                                if (FromXml)
                                        itemGroupElement.SetAttribute ("Condition", value);
+                               else
+                                       throw new InvalidOperationException ("Cannot set a condition on an object not represented by an XML element in the project file.");
                        }
                }
 
@@ -188,7 +251,7 @@ namespace Microsoft.Build.BuildEngine {
                }
 
                public bool IsImported {
-                       get { return isImported; }
+                       get { return importedProject != null; }
                }
 
                
@@ -204,7 +267,7 @@ namespace Microsoft.Build.BuildEngine {
                        set { parentCollection = value; }
                }
                
-               internal Project Project {
+               internal Project ParentProject {
                        get { return parentProject; }
                }
 
@@ -213,6 +276,12 @@ namespace Microsoft.Build.BuildEngine {
                                return itemGroupElement != null;
                        }
                }
+
+               internal XmlElement XmlElement {
+                       get {
+                               return itemGroupElement;
+                       }       
+               }
        }
 }