implement Project.RemoveProperty() and ProjectProperty.Predecessor (i.e. property...
[mono.git] / mcs / class / Microsoft.Build / Microsoft.Build.Evaluation / Project.cs
index f3c0de2033af1a4641ee34db7e538c47b8689b18..6e4bf58c3452d3924317120f98d56a8d71b8f631 100644 (file)
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Leszek Ciesielski (skolima@gmail.com)
+//   Rolf Bjarne Kvinge (rolf@xamarin.com)
 //
 // (C) 2011 Leszek Ciesielski
+// Copyright (C) 2011 Xamarin Inc. (http://www.xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.IO;
 using System.Linq;
+using System.Text;
+using System.Xml;
 using Microsoft.Build.Construction;
 using Microsoft.Build.Internal;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Logging;
+using System.Collections;
 
 namespace Microsoft.Build.Evaluation
 {
-        [DebuggerDisplay("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties="
-                         +"{data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes="
-                         +"{data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items="
-                         +"{data.Items.Count} #Targets={data.Targets.Count}")]
-        public class Project
-        {
-                public Project (ProjectRootElement xml) : this(xml, null, null)
-                {
-                }
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion)
-                        : this(xml, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection)
-                {
-                }
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection)
-                        : this(xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
-                {
-                }
-
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection,
-                                ProjectLoadSettings loadSettings)
-                {
-                        ProjectCollection = projectCollection;
-                        Xml = xml;
-                        GlobalProperties = globalProperties;
-                        ToolsVersion = toolsVersion;
-                }
-
-                public IDictionary<string, string> GlobalProperties { get; private set; }
-                public ProjectCollection ProjectCollection { get; private set; }
-                public string ToolsVersion { get; private set; }
-                public ProjectRootElement Xml { get; private set; }
-
-                public ICollection<ProjectItem> GetItemsIgnoringCondition (string itemType)
-                {
-                        return new CollectionFromEnumerable<ProjectItem> (
-                                new FilteredEnumerable<ProjectItemElement> (Xml.Items).
+       [DebuggerDisplay ("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties="
+       + "{data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes="
+       + "{data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items="
+       + "{data.Items.Count} #Targets={data.Targets.Count}")]
+       public class Project
+       {
+               public Project (XmlReader xml)
+                       : this (ProjectRootElement.Create (xml))
+               {
+               }
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion)
+                       : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion)
+               {
+               }
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection)
+                       : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection)
+               {
+               }
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection,
+                                             ProjectLoadSettings loadSettings)
+                       : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection, loadSettings)
+               {
+               }
+
+               public Project (ProjectRootElement xml) : this (xml, null, null)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion)
+                        : this (xml, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection)
+                        : this (xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection,
+                                             ProjectLoadSettings loadSettings)
+               {
+                       if (projectCollection == null)
+                               throw new ArgumentNullException ("projectCollection");
+                       this.Xml = xml;
+                       this.GlobalProperties = globalProperties ?? new Dictionary<string, string> ();
+                       this.ToolsVersion = toolsVersion;
+                       this.ProjectCollection = projectCollection;
+                       this.load_settings = loadSettings;
+
+                       Initialize ();
+               }
+
+               public Project (string projectFile)
+                       : this (projectFile, null, null)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion)
+               : this (projectFile, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion, ProjectCollection projectCollection)
+               : this (projectFile, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion, ProjectCollection projectCollection,
+                               ProjectLoadSettings loadSettings)
+                       : this (ProjectRootElement.Create (projectFile), globalProperties, toolsVersion, projectCollection, loadSettings)
+               {
+               }
+
+               ProjectLoadSettings load_settings;
+
+               public IDictionary<string, string> GlobalProperties { get; private set; }
+
+               public ProjectCollection ProjectCollection { get; private set; }
+
+               public string ToolsVersion { get; private set; }
+
+               public ProjectRootElement Xml { get; private set; }
+
+               string dir_path;
+               Dictionary<string, ProjectItemDefinition> item_definitions;
+               List<ResolvedImport> raw_imports;
+               List<ProjectItem> raw_items;
+               List<string> item_types;
+               List<ProjectProperty> properties;
+               Dictionary<string, ProjectTargetInstance> targets;
+
+               void Initialize ()
+               {
+                       dir_path = Directory.GetCurrentDirectory ();
+                       raw_imports = new List<ResolvedImport> ();
+                       item_definitions = new Dictionary<string, ProjectItemDefinition> ();
+                       item_types = new List<string> ();
+                       properties = new List<ProjectProperty> ();
+                       targets = new Dictionary<string, ProjectTargetInstance> ();
+                       
+                       ProcessXml ();
+               }
+               
+               void ProcessXml ()
+               {
+                       foreach (DictionaryEntry p in Environment.GetEnvironmentVariables ())
+                               this.properties.Add (new EnvironmentProjectProperty (this, (string) p.Key, (string) p.Value));
+                       foreach (var p in GlobalProperties)
+                               this.properties.Add (new GlobalProjectProperty (this, p.Key, p.Value));
+                       foreach (var child in Xml.Children) {
+                               if (child is ProjectPropertyGroupElement)
+                                       foreach (var p in ((ProjectPropertyGroupElement) child).Properties)
+                                               this.properties.Add (new XmlProjectProperty (this, p, PropertyType.Normal));
+                               else if (child is ProjectItemGroupElement)
+                                       foreach (var p in ((ProjectItemGroupElement) child).Items)
+                                               this.raw_items.Add (new ProjectItem (p));
+                       }
+               }
+
+               public ICollection<ProjectItem> GetItemsIgnoringCondition (string itemType)
+               {
+                       return new CollectionFromEnumerable<ProjectItem> (
+                               new FilteredEnumerable<ProjectItemElement> (Xml.Items).
                                 Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)).
-                                Select (p => new ProjectItem(p)));
-                }
-                public void RemoveItems (IEnumerable<ProjectItem> items)
-                {
-                        var removal = new List<ProjectItem> (items);
-                        foreach (var item in removal) {
-                                var parent = item.Xml.Parent;
-                                parent.RemoveChild (item.Xml);
-                                if (parent.Count == 0)
-                                        parent.Parent.RemoveChild (parent);
-                        }
-                }
-        }
+                                Select (p => new ProjectItem (p)));
+               }
+
+               public void RemoveItems (IEnumerable<ProjectItem> items)
+               {
+                       var removal = new List<ProjectItem> (items);
+                       foreach (var item in removal) {
+                               var parent = item.Xml.Parent;
+                               parent.RemoveChild (item.Xml);
+                               if (parent.Count == 0)
+                                       parent.Parent.RemoveChild (parent);
+                       }
+               }
+
+               static readonly Dictionary<string, string> empty_metadata = new Dictionary<string, string> ();
+
+               public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude)
+               {
+                       return AddItem (itemType, unevaluatedInclude, empty_metadata);
+               }
+
+               public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude,
+                               IEnumerable<KeyValuePair<string, string>> metadata)
+               {
+                       // FIXME: needs several check that AddItemFast() does not process (see MSDN for details).
+
+                       return AddItemFast (itemType, unevaluatedInclude, metadata);
+               }
+
+               public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude)
+               {
+                       return AddItemFast (itemType, unevaluatedInclude, empty_metadata);
+               }
+
+               public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude,
+                                                                    IEnumerable<KeyValuePair<string, string>> metadata)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool Build ()
+               {
+                       return Build (Xml.DefaultTargets.Split (';'));
+               }
+
+               public bool Build (IEnumerable<ILogger> loggers)
+               {
+                       return Build (Xml.DefaultTargets.Split (';'), loggers);
+               }
+
+               public bool Build (string target)
+               {
+                       return string.IsNullOrWhiteSpace (target) ? Build () : Build (new string [] {target});
+               }
+
+               public bool Build (string[] targets)
+               {
+                       return Build (targets, new ILogger [0]);
+               }
+
+               public bool Build (ILogger logger)
+               {
+                       return Build (Xml.DefaultTargets.Split (';'), new ILogger [] {logger});
+               }
+
+               public bool Build (string[] targets, IEnumerable<ILogger> loggers)
+               {
+                       return Build (targets, loggers, new ForwardingLoggerRecord [0]);
+               }
+
+               public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       return Build (Xml.DefaultTargets.Split (';'), loggers, remoteLoggers);
+               }
+
+               public bool Build (string target, IEnumerable<ILogger> loggers)
+               {
+                       return Build (new string [] { target }, loggers);
+               }
+
+               public bool Build (string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       // Unlike ProjectInstance.Build(), there is no place to fill outputs by targets, so ignore them
+                       // (i.e. we don't use the overload with output).
+                       //
+                       // This does not check FullPath, so don't call GetProjectInstanceForBuild() directly.
+                       return new BuildManager ().GetProjectInstanceForBuildInternal (this).Build (targets, loggers, remoteLoggers);
+               }
+
+               public bool Build (string target, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       return Build (new string [] { target }, loggers, remoteLoggers);
+               }
+
+               public ProjectInstance CreateProjectInstance ()
+               {
+                       var ret = new ProjectInstance (Xml, GlobalProperties, ToolsVersion, ProjectCollection);
+                       // FIXME: maybe fill other properties to the result.
+                       return ret;
+               }
+
+               public string ExpandString (string unexpandedValue)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetEvaluatedItemIncludeEscaped (ProjectItem item)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetEvaluatedItemIncludeEscaped (ProjectItemDefinition item)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ICollection<ProjectItem> GetItems (string itemType)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ICollection<ProjectItem> GetItemsByEvaluatedInclude (string evaluatedInclude)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public IEnumerable<ProjectElement> GetLogicalProject ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetMetadataValueEscaped (ProjectMetadata metadatum)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetMetadataValueEscaped (ProjectItem item, string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetMetadataValueEscaped (ProjectItemDefinition item, string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string GetPropertyValue (string name)
+               {
+                       var prop = GetProperty (name);
+                       return prop != null ? prop.EvaluatedValue : string.Empty;
+               }
+
+               public static string GetPropertyValueEscaped (ProjectProperty property)
+               {
+                       return property.EvaluatedValue;
+               }
+
+               public ProjectProperty GetProperty (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void MarkDirty ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void ReevaluateIfNecessary ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveGlobalProperty (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveItem (ProjectItem item)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveProperty (ProjectProperty property)
+               {
+                       var removed = properties.FirstOrDefault (p => p.Name == property.Name);
+                       if (removed == null)
+                               return false;
+                       properties.Remove (removed);
+                       return true;
+               }
+
+               public void Save ()
+               {
+                       Xml.Save ();
+               }
+
+               public void Save (TextWriter writer)
+               {
+                       Xml.Save (writer);
+               }
+
+               public void Save (string path)
+               {
+                       Save (path, Encoding.Default);
+               }
+
+               public void Save (Encoding encoding)
+               {
+                       Save (FullPath, encoding);
+               }
+
+               public void Save (string path, Encoding encoding)
+               {
+                       using (var writer = new StreamWriter (path, false, encoding))
+                               Save (writer);
+               }
+
+               public void SaveLogicalProject (TextWriter writer)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool SetGlobalProperty (string name, string escapedValue)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ProjectProperty SetProperty (string name, string unevaluatedValue)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ICollection<ProjectMetadata> AllEvaluatedItemDefinitionMetadata { get; private set; }
+
+               public ICollection<ProjectItem> AllEvaluatedItems { get; private set; }
+
+               public ICollection<ProjectProperty> AllEvaluatedProperties { get; private set; }
+
+               public IDictionary<string, List<string>> ConditionedProperties {
+                       get {
+                               // this property returns different instances every time.
+                               var dic = new Dictionary<string, List<string>> ();
+                               
+                               // but I dunno HOW this evaluates
+                               
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public string DirectoryPath {
+                       get { return dir_path; }
+               }
+
+               public bool DisableMarkDirty { get; set; }
+
+               public int EvaluationCounter {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public string FullPath {
+                       get { return Xml.FullPath; }
+                       set { Xml.FullPath = value; }
+               }
+
+               public IList<ResolvedImport> Imports {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public IList<ResolvedImport> ImportsIncludingDuplicates {
+                       get { return raw_imports; }
+               }
+
+               public bool IsBuildEnabled {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public bool IsDirty {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public IDictionary<string, ProjectItemDefinition> ItemDefinitions {
+                       get { return item_definitions; }
+               }
+
+               public ICollection<ProjectItem> Items {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public ICollection<ProjectItem> ItemsIgnoringCondition {
+                       get { return raw_items; }
+               }
+
+               public ICollection<string> ItemTypes {
+                       get { return item_types; }
+               }
+
+               public ICollection<ProjectProperty> Properties {
+                       get { return properties; }
+               }
+
+               public bool SkipEvaluation { get; set; }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               IDictionary<string, ProjectTargetInstance> Targets {
+                       get { return targets; }
+               }
+       }
 }