5 // Leszek Ciesielski (skolima@gmail.com)
6 // Rolf Bjarne Kvinge (rolf@xamarin.com)
8 // (C) 2011 Leszek Ciesielski
9 // Copyright (C) 2011 Xamarin Inc. (http://www.xamarin.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections.Generic;
33 using System.Diagnostics;
38 using Microsoft.Build.Construction;
39 using Microsoft.Build.Internal;
40 using Microsoft.Build.Execution;
41 using Microsoft.Build.Framework;
42 using Microsoft.Build.Logging;
43 using System.Collections;
45 namespace Microsoft.Build.Evaluation
47 [DebuggerDisplay ("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties="
48 + "{data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes="
49 + "{data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items="
50 + "{data.Items.Count} #Targets={data.Targets.Count}")]
53 public Project (XmlReader xml)
54 : this (ProjectRootElement.Create (xml))
58 public Project (XmlReader xml, IDictionary<string, string> globalProperties,
60 : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion)
64 public Project (XmlReader xml, IDictionary<string, string> globalProperties,
65 string toolsVersion, ProjectCollection projectCollection)
66 : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection)
70 public Project (XmlReader xml, IDictionary<string, string> globalProperties,
71 string toolsVersion, ProjectCollection projectCollection,
72 ProjectLoadSettings loadSettings)
73 : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection, loadSettings)
77 public Project (ProjectRootElement xml) : this (xml, null, null)
81 public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
83 : this (xml, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection)
87 public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
88 string toolsVersion, ProjectCollection projectCollection)
89 : this (xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
93 public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
94 string toolsVersion, ProjectCollection projectCollection,
95 ProjectLoadSettings loadSettings)
97 if (projectCollection == null)
98 throw new ArgumentNullException ("projectCollection");
100 this.GlobalProperties = globalProperties ?? new Dictionary<string, string> ();
101 this.ToolsVersion = toolsVersion;
102 this.ProjectCollection = projectCollection;
103 this.load_settings = loadSettings;
108 public Project (string projectFile)
109 : this (projectFile, null, null)
113 public Project (string projectFile, IDictionary<string, string> globalProperties,
115 : this (projectFile, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection, ProjectLoadSettings.Default)
119 public Project (string projectFile, IDictionary<string, string> globalProperties,
120 string toolsVersion, ProjectCollection projectCollection)
121 : this (projectFile, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
125 public Project (string projectFile, IDictionary<string, string> globalProperties,
126 string toolsVersion, ProjectCollection projectCollection,
127 ProjectLoadSettings loadSettings)
128 : this (ProjectRootElement.Create (projectFile), globalProperties, toolsVersion, projectCollection, loadSettings)
132 ProjectLoadSettings load_settings;
134 public IDictionary<string, string> GlobalProperties { get; private set; }
136 public ProjectCollection ProjectCollection { get; private set; }
138 public string ToolsVersion { get; private set; }
140 public ProjectRootElement Xml { get; private set; }
143 Dictionary<string, ProjectItemDefinition> item_definitions;
144 List<ResolvedImport> raw_imports;
145 List<ProjectItem> raw_items;
146 List<string> item_types;
147 List<ProjectProperty> properties;
148 Dictionary<string, ProjectTargetInstance> targets;
152 dir_path = Directory.GetCurrentDirectory ();
153 raw_imports = new List<ResolvedImport> ();
154 item_definitions = new Dictionary<string, ProjectItemDefinition> ();
155 item_types = new List<string> ();
156 properties = new List<ProjectProperty> ();
157 targets = new Dictionary<string, ProjectTargetInstance> ();
164 foreach (DictionaryEntry p in Environment.GetEnvironmentVariables ())
165 this.properties.Add (new EnvironmentProjectProperty (this, (string) p.Key, (string) p.Value));
166 foreach (var p in GlobalProperties)
167 this.properties.Add (new GlobalProjectProperty (this, p.Key, p.Value));
168 foreach (var child in Xml.Children) {
169 if (child is ProjectPropertyGroupElement)
170 foreach (var p in ((ProjectPropertyGroupElement) child).Properties)
171 this.properties.Add (new XmlProjectProperty (this, p, PropertyType.Normal));
172 else if (child is ProjectItemGroupElement)
173 foreach (var p in ((ProjectItemGroupElement) child).Items)
174 this.raw_items.Add (new ProjectItem (p));
178 public ICollection<ProjectItem> GetItemsIgnoringCondition (string itemType)
180 return new CollectionFromEnumerable<ProjectItem> (
181 new FilteredEnumerable<ProjectItemElement> (Xml.Items).
182 Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)).
183 Select (p => new ProjectItem (p)));
186 public void RemoveItems (IEnumerable<ProjectItem> items)
188 var removal = new List<ProjectItem> (items);
189 foreach (var item in removal) {
190 var parent = item.Xml.Parent;
191 parent.RemoveChild (item.Xml);
192 if (parent.Count == 0)
193 parent.Parent.RemoveChild (parent);
197 static readonly Dictionary<string, string> empty_metadata = new Dictionary<string, string> ();
199 public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude)
201 return AddItem (itemType, unevaluatedInclude, empty_metadata);
204 public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude,
205 IEnumerable<KeyValuePair<string, string>> metadata)
207 // FIXME: needs several check that AddItemFast() does not process (see MSDN for details).
209 return AddItemFast (itemType, unevaluatedInclude, metadata);
212 public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude)
214 return AddItemFast (itemType, unevaluatedInclude, empty_metadata);
217 public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude,
218 IEnumerable<KeyValuePair<string, string>> metadata)
220 throw new NotImplementedException ();
225 return Build (Xml.DefaultTargets.Split (';'));
228 public bool Build (IEnumerable<ILogger> loggers)
230 return Build (Xml.DefaultTargets.Split (';'), loggers);
233 public bool Build (string target)
235 return string.IsNullOrWhiteSpace (target) ? Build () : Build (new string [] {target});
238 public bool Build (string[] targets)
240 return Build (targets, new ILogger [0]);
243 public bool Build (ILogger logger)
245 return Build (Xml.DefaultTargets.Split (';'), new ILogger [] {logger});
248 public bool Build (string[] targets, IEnumerable<ILogger> loggers)
250 return Build (targets, loggers, new ForwardingLoggerRecord [0]);
253 public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
255 return Build (Xml.DefaultTargets.Split (';'), loggers, remoteLoggers);
258 public bool Build (string target, IEnumerable<ILogger> loggers)
260 return Build (new string [] { target }, loggers);
263 public bool Build (string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
265 // Unlike ProjectInstance.Build(), there is no place to fill outputs by targets, so ignore them
266 // (i.e. we don't use the overload with output).
268 // This does not check FullPath, so don't call GetProjectInstanceForBuild() directly.
269 return new BuildManager ().GetProjectInstanceForBuildInternal (this).Build (targets, loggers, remoteLoggers);
272 public bool Build (string target, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
274 return Build (new string [] { target }, loggers, remoteLoggers);
277 public ProjectInstance CreateProjectInstance ()
279 var ret = new ProjectInstance (Xml, GlobalProperties, ToolsVersion, ProjectCollection);
280 // FIXME: maybe fill other properties to the result.
284 public string ExpandString (string unexpandedValue)
286 throw new NotImplementedException ();
289 public static string GetEvaluatedItemIncludeEscaped (ProjectItem item)
291 throw new NotImplementedException ();
294 public static string GetEvaluatedItemIncludeEscaped (ProjectItemDefinition item)
296 throw new NotImplementedException ();
299 public ICollection<ProjectItem> GetItems (string itemType)
301 throw new NotImplementedException ();
304 public ICollection<ProjectItem> GetItemsByEvaluatedInclude (string evaluatedInclude)
306 throw new NotImplementedException ();
309 public IEnumerable<ProjectElement> GetLogicalProject ()
311 throw new NotImplementedException ();
314 public static string GetMetadataValueEscaped (ProjectMetadata metadatum)
316 throw new NotImplementedException ();
319 public static string GetMetadataValueEscaped (ProjectItem item, string name)
321 throw new NotImplementedException ();
324 public static string GetMetadataValueEscaped (ProjectItemDefinition item, string name)
326 throw new NotImplementedException ();
329 public string GetPropertyValue (string name)
331 var prop = GetProperty (name);
332 return prop != null ? prop.EvaluatedValue : string.Empty;
335 public static string GetPropertyValueEscaped (ProjectProperty property)
337 return property.EvaluatedValue;
340 public ProjectProperty GetProperty (string name)
342 throw new NotImplementedException ();
345 public void MarkDirty ()
347 throw new NotImplementedException ();
350 public void ReevaluateIfNecessary ()
352 throw new NotImplementedException ();
355 public bool RemoveGlobalProperty (string name)
357 throw new NotImplementedException ();
360 public bool RemoveItem (ProjectItem item)
362 throw new NotImplementedException ();
365 public bool RemoveProperty (ProjectProperty property)
367 var removed = properties.FirstOrDefault (p => p.Name == property.Name);
370 properties.Remove (removed);
379 public void Save (TextWriter writer)
384 public void Save (string path)
386 Save (path, Encoding.Default);
389 public void Save (Encoding encoding)
391 Save (FullPath, encoding);
394 public void Save (string path, Encoding encoding)
396 using (var writer = new StreamWriter (path, false, encoding))
400 public void SaveLogicalProject (TextWriter writer)
402 throw new NotImplementedException ();
405 public bool SetGlobalProperty (string name, string escapedValue)
407 throw new NotImplementedException ();
410 public ProjectProperty SetProperty (string name, string unevaluatedValue)
412 throw new NotImplementedException ();
415 public ICollection<ProjectMetadata> AllEvaluatedItemDefinitionMetadata { get; private set; }
417 public ICollection<ProjectItem> AllEvaluatedItems { get; private set; }
419 public ICollection<ProjectProperty> AllEvaluatedProperties { get; private set; }
421 public IDictionary<string, List<string>> ConditionedProperties {
423 // this property returns different instances every time.
424 var dic = new Dictionary<string, List<string>> ();
426 // but I dunno HOW this evaluates
428 throw new NotImplementedException ();
432 public string DirectoryPath {
433 get { return dir_path; }
436 public bool DisableMarkDirty { get; set; }
438 public int EvaluationCounter {
439 get { throw new NotImplementedException (); }
442 public string FullPath {
443 get { return Xml.FullPath; }
444 set { Xml.FullPath = value; }
447 public IList<ResolvedImport> Imports {
448 get { throw new NotImplementedException (); }
451 public IList<ResolvedImport> ImportsIncludingDuplicates {
452 get { return raw_imports; }
455 public bool IsBuildEnabled {
456 get { throw new NotImplementedException (); }
459 public bool IsDirty {
460 get { throw new NotImplementedException (); }
463 public IDictionary<string, ProjectItemDefinition> ItemDefinitions {
464 get { return item_definitions; }
467 public ICollection<ProjectItem> Items {
468 get { throw new NotImplementedException (); }
471 public ICollection<ProjectItem> ItemsIgnoringCondition {
472 get { return raw_items; }
475 public ICollection<string> ItemTypes {
476 get { return item_types; }
479 public ICollection<ProjectProperty> Properties {
480 get { return properties; }
483 public bool SkipEvaluation { get; set; }
490 IDictionary<string, ProjectTargetInstance> Targets {
491 get { return targets; }