In class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine:
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildPropertyGroup.cs
index 86620a3d32e38643ef4c76f79648ecdef7e1f466..56dc782c48ad44b75bd536f53f4fbe0114c05c4e 100644 (file)
@@ -37,30 +37,31 @@ using System.Xml;
 namespace Microsoft.Build.BuildEngine {
        public class BuildPropertyGroup : IEnumerable {
        
+               bool                    read_only;
+               ImportedProject         importedProject;
                XmlElement              propertyGroup;
-               bool                    isImported;
                GroupingCollection      parentCollection;
                Project                 parentProject;
                List <BuildProperty>    properties;
                Dictionary <string, BuildProperty>      propertiesByName;
 
                public BuildPropertyGroup ()
-                       : this (null, null)
+                       : this (null, null, null, false)
                {
                }
 
-               internal BuildPropertyGroup (XmlElement xmlElement, Project project)
+               internal BuildPropertyGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
                {
-                       this.isImported = false;
+                       this.importedProject = importedProject;
                        this.parentCollection = null;
                        this.parentProject = project;
-                       this.isImported = false;
                        this.propertyGroup = xmlElement;
+                       this.read_only = readOnly;
 
                        if (FromXml) {
                                this.properties = new List <BuildProperty> ();
                                foreach (XmlNode xn in propertyGroup.ChildNodes) {
-                                       if (xn is XmlElement == false)
+                                       if (!(xn is XmlElement))
                                                continue;
                                        
                                        XmlElement xe = (XmlElement) xn;
@@ -81,48 +82,48 @@ namespace Microsoft.Build.BuildEngine {
                                                     string propertyValue,
                                                     bool treatPropertyValueAsLiteral)
                {
-                       BuildProperty prop;
+                       if (!FromXml)
+                               throw new InvalidOperationException ("This method is only valid for persisted property groups.");
 
-                       if (FromXml) {
-                               XmlElement xe;
-                               
-                               xe = propertyGroup.OwnerDocument.CreateElement (propertyName);
-                               propertyGroup.AppendChild (xe);
-                               
-                               if (treatPropertyValueAsLiteral)
-                                       xe.InnerText = Utilities.Escape (propertyValue);
-                               else
-                                       xe.InnerText = propertyValue;
-                               
-                               prop = new BuildProperty (parentProject, xe);
-                       } else {
-                               prop = new BuildProperty (propertyName, propertyValue);
-                       }
-                       AddProperty (prop);
-                       return prop;
+                       if (treatPropertyValueAsLiteral)
+                               propertyValue = Utilities.Escape (propertyValue);
+
+                       XmlElement element = propertyGroup.OwnerDocument.CreateElement (propertyName, Project.XmlNamespace);
+                       propertyGroup.AppendChild (element);
+
+                       BuildProperty property = new BuildProperty (parentProject, element);
+                       property.Value = propertyValue;
+                       AddProperty (property);
+
+                       parentProject.MarkProjectAsDirty ();
+                       parentProject.NeedToReevaluate ();
+
+                       return property;
                }
 
                internal void AddProperty (BuildProperty property)
                {
-                       if (FromXml) {
+                       if (FromXml)
                                properties.Add (property);
-                       else {
+                       else {
                                if (propertiesByName.ContainsKey (property.Name)) {
                                        BuildProperty existing = propertiesByName [property.Name];
                                        if (property.PropertyType <= existing.PropertyType) {
                                                propertiesByName.Remove (property.Name);
                                                propertiesByName.Add (property.Name, property);
                                        }
-                               } else {
+                               } else
                                        propertiesByName.Add (property.Name, property);
-                               }
                        }
                }
                
-               [MonoTODO]
                public void Clear ()
                {
-                       throw new NotImplementedException ();
+                       if (FromXml) {
+                               propertyGroup.RemoveAll ();
+                               properties = new List <BuildProperty> ();
+                       } else
+                               propertiesByName = new Dictionary <string, BuildProperty> ();
                }
 
                [MonoTODO]
@@ -133,28 +134,39 @@ namespace Microsoft.Build.BuildEngine {
 
                public IEnumerator GetEnumerator ()
                {
-                       if (properties != null) {
+                       if (FromXml)
                                foreach (BuildProperty bp in properties)
                                        yield return bp;
-                       } else if (propertiesByName != null) {
+                       else 
                                foreach (KeyValuePair <string, BuildProperty> kvp in propertiesByName)
                                        yield return kvp.Value;
-                       } else
-                               throw new Exception ("PropertyGroup is not initialized.");
                }
 
                public void RemoveProperty (BuildProperty propertyToRemove)
                {
-                       if (properties == null)
-                               throw new Exception ("PropertyGroup is not initialized.");
-                       properties.Remove (propertyToRemove);
+                       if (propertyToRemove == null)
+                               throw new ArgumentNullException ("propertyToRemove");
+
+                       if (FromXml) {
+                               if (!propertyToRemove.FromXml)
+                                       throw new InvalidOperationException ("The specified property does not belong to the current property group.");
+
+                               propertyToRemove.XmlElement.ParentNode.RemoveChild (propertyToRemove.XmlElement);
+                               properties.Remove (propertyToRemove);
+                       } else
+                               propertiesByName.Remove (propertyToRemove.Name);
                }
 
                public void RemoveProperty (string propertyName)
                {
-                       if (propertiesByName == null)
-                               throw new Exception ("PropertyGroup is not initialized.");
-                       propertiesByName.Remove (propertyName);
+                       if (FromXml) {
+                               foreach (BuildProperty bp in properties)
+                                       if (bp.Name == propertyName) {
+                                               RemoveProperty (bp);
+                                               break;
+                                       }
+                       } else
+                               propertiesByName.Remove (propertyName);
                }
 
                public void SetProperty (string propertyName,
@@ -163,32 +175,38 @@ namespace Microsoft.Build.BuildEngine {
                        SetProperty (propertyName, propertyValue, false);
                }
                
-               // FIXME: use treatPropertyValueAsLiteral
-               [MonoTODO]
                public void SetProperty (string propertyName,
                                         string propertyValue,
                                         bool treatPropertyValueAsLiteral)
                {
-                       if (!propertiesByName.ContainsKey (propertyName)) {
-                               AddNewProperty (propertyName, propertyValue);
-                       }
-                       propertiesByName [propertyName].Value = propertyValue;
+                       if (read_only)
+                               return;
+                       if (FromXml)
+                               throw new InvalidOperationException (
+                                       "This method is only valid for virtual property groups, not <PropertyGroup> elements.");
+
+                       if (treatPropertyValueAsLiteral)
+                               propertyValue = Utilities.Escape (propertyValue);
+
+                       if (propertiesByName.ContainsKey (propertyName))
+                               propertiesByName.Remove (propertyName);
+
+                       BuildProperty bp = new BuildProperty (propertyName, propertyValue);
+                       if (Char.IsDigit (propertyName [0]))
+                               throw new ArgumentException (String.Format (
+                                       "The name \"{0}\" contains an invalid character \"{1}\".", propertyName, propertyName [0]));
+
+                       AddProperty (bp);
+
+                       if (IsGlobal)
+                               parentProject.NeedToReevaluate ();
                }
                
                internal void Evaluate ()
                {
-                       if (!FromXml) {
-                               throw new InvalidOperationException ();
-                       }
-                       foreach (BuildProperty bp in properties) {
-                               if (bp.Condition == String.Empty)
+                       foreach (BuildProperty bp in properties)
+                               if (ConditionParser.ParseAndEvaluate (bp.Condition, parentProject))
                                        bp.Evaluate ();
-                               else {
-                                       ConditionExpression ce = ConditionParser.ParseCondition (bp.Condition);
-                                       if (ce.BoolEvaluate (parentProject))
-                                               bp.Evaluate ();
-                               }
-                       }
                }
                
                public string Condition {
@@ -207,18 +225,16 @@ namespace Microsoft.Build.BuildEngine {
 
                public int Count {
                        get {
-                               if (properties != null)
+                               if (FromXml)
                                        return properties.Count;
-                               else if (propertiesByName != null)
-                                       return propertiesByName.Count;
                                else
-                                       throw new Exception ("PropertyGroup is not initialized.");
+                                       return propertiesByName.Count;
                        }
                }
 
                public bool IsImported {
                        get {
-                               return isImported;
+                               return importedProject != null;
                        }
                }
 
@@ -228,16 +244,21 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
 
+               bool IsGlobal {
+                       get {
+                               return parentProject != null && propertyGroup == null;
+                       }
+               }
+
                public BuildProperty this [string propertyName] {
                        get {
                                if (FromXml)
                                        throw new InvalidOperationException ("Properties in persisted property groups cannot be accessed by name.");
                                
-                               if (propertiesByName.ContainsKey (propertyName)) {
+                               if (propertiesByName.ContainsKey (propertyName))
                                        return propertiesByName [propertyName];
-                               } else {
+                               else
                                        return null;
-                               }
                        }
                        set {
                                propertiesByName [propertyName] = value;
@@ -248,6 +269,10 @@ namespace Microsoft.Build.BuildEngine {
                        get { return parentCollection; }
                        set { parentCollection = value; }
                }
+
+               internal XmlElement XmlElement {
+                       get { return propertyGroup; }
+               }
        }
 }