2 // Project.cs: Project class
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
7 // (C) 2005 Marek Sieradzki
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.Collections.Specialized;
37 using System.Xml.Schema;
38 using Microsoft.Build.Framework;
39 using Mono.XBuild.Framework;
41 namespace Microsoft.Build.BuildEngine {
42 public class Project {
45 Dictionary <string, List <string>> conditionedProperties;
46 string[] defaultTargets;
48 BuildItemGroup evaluatedItems;
49 BuildItemGroup evaluatedItemsIgnoringCondition;
50 Dictionary <string, BuildItemGroup> evaluatedItemsByName;
51 Dictionary <string, BuildItemGroup> evaluatedItemsByNameIgnoringCondition;
52 BuildPropertyGroup evaluatedProperties;
53 string firstTargetName;
55 BuildPropertyGroup globalProperties;
56 GroupingCollection groupingCollection;
59 BuildItemGroupCollection itemGroups;
60 ImportCollection imports;
61 string initialTargets;
62 Dictionary <string, BuildItemGroup> last_item_group_containing;
63 bool needToReevaluate;
65 BuildPropertyGroupCollection propertyGroups;
67 TaskDatabase taskDatabase;
68 TargetCollection targets;
69 DateTime timeOfLastDirty;
70 UsingTaskCollection usingTasks;
71 XmlDocument xmlDocument;
74 static XmlNamespaceManager manager;
75 static string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
78 : this (Engine.GlobalEngine)
82 public Project (Engine engine)
84 parentEngine = engine;
86 buildEnabled = ParentEngine.BuildEnabled;
87 xmlDocument = new XmlDocument ();
88 xmlDocument.PreserveWhitespace = false;
89 xmlDocument.AppendChild (xmlDocument.CreateElement ("Project", XmlNamespace));
90 xmlDocument.DocumentElement.SetAttribute ("xmlns", ns);
92 fullFileName = String.Empty;
94 globalProperties = new BuildPropertyGroup (null, this, null, false);
95 foreach (BuildProperty bp in parentEngine.GlobalProperties)
96 GlobalProperties.AddProperty (bp.Clone (true));
101 [MonoTODO ("Not tested")]
102 public void AddNewImport (string importLocation,
103 string importCondition)
105 if (importLocation == null)
106 throw new ArgumentNullException ("importLocation");
108 XmlElement importElement = xmlDocument.CreateElement ("Import", XmlNamespace);
109 xmlDocument.DocumentElement.AppendChild (importElement);
110 importElement.SetAttribute ("Project", importLocation);
111 if (!String.IsNullOrEmpty (importCondition))
112 importElement.SetAttribute ("Condition", importCondition);
114 Import import = new Import (importElement, this, null);
115 imports.Add (import);
116 MarkProjectAsDirty ();
120 public BuildItem AddNewItem (string itemName,
123 return AddNewItem (itemName, itemInclude, false);
126 [MonoTODO ("Adds item not in the same place as MS")]
127 public BuildItem AddNewItem (string itemName,
129 bool treatItemIncludeAsLiteral)
133 if (itemGroups.Count == 0)
134 big = AddNewItemGroup ();
136 if (last_item_group_containing.ContainsKey (itemName)) {
137 big = last_item_group_containing [itemName];
140 BuildItemGroup [] groups = new BuildItemGroup [itemGroups.Count];
141 itemGroups.CopyTo (groups, 0);
146 BuildItem item = big.AddNewItem (itemName, itemInclude, treatItemIncludeAsLiteral);
148 MarkProjectAsDirty ();
154 [MonoTODO ("Not tested")]
155 public BuildItemGroup AddNewItemGroup ()
157 XmlElement element = xmlDocument.CreateElement ("ItemGroup", XmlNamespace);
158 xmlDocument.DocumentElement.AppendChild (element);
160 BuildItemGroup big = new BuildItemGroup (element, this, null, false);
161 itemGroups.Add (big);
162 MarkProjectAsDirty ();
168 [MonoTODO ("Ignores insertAtEndOfProject")]
169 public BuildPropertyGroup AddNewPropertyGroup (bool insertAtEndOfProject)
171 XmlElement element = xmlDocument.CreateElement ("PropertyGroup", XmlNamespace);
172 xmlDocument.DocumentElement.AppendChild (element);
174 BuildPropertyGroup bpg = new BuildPropertyGroup (element, this, null, false);
175 propertyGroups.Add (bpg);
176 MarkProjectAsDirty ();
182 [MonoTODO ("Not tested, isn't added to TaskDatabase (no reevaluation)")]
183 public void AddNewUsingTaskFromAssemblyFile (string taskName,
186 if (taskName == null)
187 throw new ArgumentNullException ("taskName");
188 if (assemblyFile == null)
189 throw new ArgumentNullException ("assemblyFile");
191 XmlElement element = xmlDocument.CreateElement ("UsingTask", XmlNamespace);
192 xmlDocument.DocumentElement.AppendChild (element);
193 element.SetAttribute ("TaskName", taskName);
194 element.SetAttribute ("AssemblyFile", assemblyFile);
196 UsingTask ut = new UsingTask (element, this, null);
198 MarkProjectAsDirty ();
201 [MonoTODO ("Not tested, isn't added to TaskDatabase (no reevaluation)")]
202 public void AddNewUsingTaskFromAssemblyName (string taskName,
205 if (taskName == null)
206 throw new ArgumentNullException ("taskName");
207 if (assemblyName == null)
208 throw new ArgumentNullException ("assemblyName");
210 XmlElement element = xmlDocument.CreateElement ("UsingTask", XmlNamespace);
211 xmlDocument.DocumentElement.AppendChild (element);
212 element.SetAttribute ("TaskName", taskName);
213 element.SetAttribute ("AssemblyName", assemblyName);
215 UsingTask ut = new UsingTask (element, this, null);
217 MarkProjectAsDirty ();
220 [MonoTODO ("Not tested")]
223 return Build (new string [0]);
226 [MonoTODO ("Not tested")]
227 public bool Build (string targetName)
229 if (targetName == null)
231 return Build (new string [1] { targetName });
234 [MonoTODO ("Not tested")]
235 public bool Build (string [] targetNames)
237 return Build (targetNames, null);
240 [MonoTODO ("Not tested")]
241 public bool Build (string [] targetNames,
242 IDictionary targetOutputs)
244 return Build (targetNames, targetOutputs, BuildSettings.None);
247 [MonoTODO ("Not tested")]
248 public bool Build (string [] targetNames,
249 IDictionary targetOutputs,
250 BuildSettings buildFlags)
253 if (targetNames == null)
257 ParentEngine.StartBuild ();
260 if (targetNames.Length == 0) {
261 if (defaultTargets != null && defaultTargets.Length != 0)
262 targetNames = defaultTargets;
263 else if (firstTargetName != null)
264 targetNames = new string [1] { firstTargetName};
269 foreach (string target in targetNames) {
271 throw new ArgumentException ("targetNames cannot contain null strings");
273 if (!targets.Exists (target))
274 // FIXME: test if it's logged
277 if (!targets [target].Build ())
280 if (targetOutputs != null)
281 targetOutputs.Add (target, targets [target].Outputs);
288 public string [] GetConditionedPropertyValues (string propertyName)
290 if (conditionedProperties.ContainsKey (propertyName))
291 return conditionedProperties [propertyName].ToArray ();
293 return new string [0];
296 public BuildItemGroup GetEvaluatedItemsByName (string itemName)
298 if (needToReevaluate) {
299 needToReevaluate = false;
303 if (evaluatedItemsByName.ContainsKey (itemName))
304 return evaluatedItemsByName [itemName];
306 return new BuildItemGroup ();
309 public BuildItemGroup GetEvaluatedItemsByNameIgnoringCondition (string itemName)
311 if (needToReevaluate) {
312 needToReevaluate = false;
316 if (evaluatedItemsByNameIgnoringCondition.ContainsKey (itemName))
317 return evaluatedItemsByNameIgnoringCondition [itemName];
319 return new BuildItemGroup ();
322 public string GetEvaluatedProperty (string propertyName)
324 if (needToReevaluate) {
325 needToReevaluate = false;
329 if (propertyName == null)
330 throw new ArgumentNullException ("propertyName");
332 BuildProperty bp = evaluatedProperties [propertyName];
334 return bp == null ? null : (string) bp;
337 [MonoTODO ("We should remember that node and not use XPath to get it")]
338 public string GetProjectExtensions (string id)
340 if (id == null || id == String.Empty)
343 XmlNode node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
348 return node.InnerXml;
352 public void Load (string projectFileName)
354 this.fullFileName = Path.GetFullPath (projectFileName);
355 DoLoad (new StreamReader (projectFileName));
358 [MonoTODO ("Not tested")]
359 public void Load (TextReader textReader)
361 fullFileName = String.Empty;
365 public void LoadXml (string projectXml)
367 fullFileName = String.Empty;
368 DoLoad (new StringReader (projectXml));
369 MarkProjectAsDirty ();
373 public void MarkProjectAsDirty ()
376 timeOfLastDirty = DateTime.Now;
379 [MonoTODO ("Not tested")]
380 public void RemoveAllItemGroups ()
382 int length = ItemGroups.Count;
383 BuildItemGroup [] groups = new BuildItemGroup [length];
384 ItemGroups.CopyTo (groups, 0);
386 for (int i = 0; i < length; i++)
387 RemoveItemGroup (groups [i]);
389 MarkProjectAsDirty ();
393 [MonoTODO ("Not tested")]
394 public void RemoveAllPropertyGroups ()
396 int length = PropertyGroups.Count;
397 BuildPropertyGroup [] groups = new BuildPropertyGroup [length];
398 PropertyGroups.CopyTo (groups, 0);
400 for (int i = 0; i < length; i++)
401 RemovePropertyGroup (groups [i]);
403 MarkProjectAsDirty ();
408 public void RemoveItem (BuildItem itemToRemove)
410 if (itemToRemove == null)
411 throw new ArgumentNullException ("itemToRemove");
413 if (!itemToRemove.FromXml && !itemToRemove.HasParent)
414 throw new InvalidOperationException ("The object passed in is not part of the project.");
416 BuildItemGroup big = itemToRemove.ParentItemGroup;
418 if (big.Count == 1) {
419 // ParentItemGroup for items from xml and that have parent is the same
420 groupingCollection.Remove (big);
422 if (big.ParentProject != this)
423 throw new InvalidOperationException ("The object passed in is not part of the project.");
425 if (itemToRemove.FromXml)
426 big.RemoveItem (itemToRemove);
428 big.RemoveItem (itemToRemove.ParentItem);
431 MarkProjectAsDirty ();
435 [MonoTODO ("Not tested")]
436 public void RemoveItemGroup (BuildItemGroup itemGroupToRemove)
438 if (itemGroupToRemove == null)
439 throw new ArgumentNullException ("itemGroupToRemove");
441 groupingCollection.Remove (itemGroupToRemove);
442 MarkProjectAsDirty ();
446 // NOTE: does not modify imported projects
447 public void RemoveItemGroupsWithMatchingCondition (string matchingCondition)
449 throw new NotImplementedException ();
453 public void RemoveItemsByName (string itemName)
455 if (itemName == null)
456 throw new ArgumentNullException ("itemName");
458 throw new NotImplementedException ();
461 [MonoTODO ("Not tested")]
462 public void RemovePropertyGroup (BuildPropertyGroup propertyGroupToRemove)
464 if (propertyGroupToRemove == null)
465 throw new ArgumentNullException ("propertyGroupToRemove");
467 groupingCollection.Remove (propertyGroupToRemove);
468 MarkProjectAsDirty ();
472 // NOTE: does not modify imported projects
473 public void RemovePropertyGroupsWithMatchingCondition (string matchCondition)
475 throw new NotImplementedException ();
479 public void ResetBuildStatus ()
481 throw new NotImplementedException ();
484 public void Save (string projectFileName)
486 Save (projectFileName, Encoding.Default);
490 [MonoTODO ("Ignores encoding")]
491 public void Save (string projectFileName, Encoding encoding)
493 xmlDocument.Save (projectFileName);
497 public void Save (TextWriter outTextWriter)
499 xmlDocument.Save (outTextWriter);
503 public void SetImportedProperty (string propertyName,
504 string propertyValue,
506 Project importProject)
508 SetImportedProperty (propertyName, propertyValue, condition, importProject,
509 PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup);
512 public void SetImportedProperty (string propertyName,
513 string propertyValue,
515 Project importedProject,
516 PropertyPosition position)
518 SetImportedProperty (propertyName, propertyValue, condition, importedProject,
519 PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
523 public void SetImportedProperty (string propertyName,
524 string propertyValue,
526 Project importedProject,
527 PropertyPosition position,
528 bool treatPropertyValueAsLiteral)
530 throw new NotImplementedException ();
533 public void SetProjectExtensions (string id, string xmlText)
536 throw new ArgumentNullException ("id");
538 throw new ArgumentNullException ("xmlText");
540 XmlNode projectExtensions, node;
542 projectExtensions = xmlDocument.SelectSingleNode ("/tns:Project/tns:ProjectExtensions", XmlNamespaceManager);
544 if (projectExtensions == null) {
545 projectExtensions = xmlDocument.CreateElement ("ProjectExtensions", XmlNamespace);
546 xmlDocument.DocumentElement.AppendChild (projectExtensions);
548 node = xmlDocument.CreateElement (id, XmlNamespace);
549 node.InnerXml = xmlText;
550 projectExtensions.AppendChild (node);
552 node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
555 node = xmlDocument.CreateElement (id, XmlNamespace);
556 projectExtensions.AppendChild (node);
559 node.InnerXml = xmlText;
563 MarkProjectAsDirty ();
566 public void SetProperty (string propertyName,
567 string propertyValue)
569 SetProperty (propertyName, propertyValue, "true",
570 PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
573 public void SetProperty (string propertyName,
574 string propertyValue,
577 SetProperty (propertyName, propertyValue, condition,
578 PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup);
581 public void SetProperty (string propertyName,
582 string propertyValue,
584 PropertyPosition position)
586 SetProperty (propertyName, propertyValue, condition,
587 PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
591 public void SetProperty (string propertyName,
592 string propertyValue,
594 PropertyPosition position,
595 bool treatPropertyValueAsLiteral)
597 throw new NotImplementedException ();
600 internal void Unload ()
605 internal void CheckUnloaded ()
608 throw new InvalidOperationException ("This project object has been unloaded from the MSBuild engine and is no longer valid.");
611 internal void NeedToReevaluate ()
613 needToReevaluate = true;
616 // Does the actual loading.
617 void DoLoad (TextReader textReader)
620 ParentEngine.RemoveLoadedProject (this);
622 XmlReaderSettings settings = new XmlReaderSettings ();
624 if (SchemaFile != null) {
625 settings.Schemas.Add (null, SchemaFile);
626 settings.ValidationType = ValidationType.Schema;
627 settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
630 XmlReader xmlReader = XmlReader.Create (textReader, settings);
631 xmlDocument.Load (xmlReader);
633 if (xmlDocument.DocumentElement.Name != "Project") {
634 throw new InvalidProjectFileException (String.Format (
635 "The element <{0}> is unrecognized, or not supported in this context.", xmlDocument.DocumentElement.Name));
638 if (xmlDocument.DocumentElement.GetAttribute ("xmlns") != ns) {
639 throw new InvalidProjectFileException (
640 @"The default XML namespace of the project must be the MSBuild XML namespace." +
641 " If the project is authored in the MSBuild 2003 format, please add " +
642 "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
643 "If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. ");
646 ParentEngine.AddLoadedProject (this);
647 } catch (Exception e) {
648 throw new InvalidProjectFileException (e.Message, e);
661 groupingCollection = new GroupingCollection (this);
662 imports = new ImportCollection (groupingCollection);
663 usingTasks = new UsingTaskCollection (this);
664 itemGroups = new BuildItemGroupCollection (groupingCollection);
665 propertyGroups = new BuildPropertyGroupCollection (groupingCollection);
666 targets = new TargetCollection (this);
667 last_item_group_containing = new Dictionary <string, BuildItemGroup> ();
669 taskDatabase = new TaskDatabase ();
670 if (ParentEngine.DefaultTasksRegistered)
671 taskDatabase.CopyTasks (ParentEngine.DefaultTasks);
673 if (xmlDocument.DocumentElement.GetAttributeNode ("DefaultTargets") != null)
674 defaultTargets = xmlDocument.DocumentElement.GetAttribute ("DefaultTargets").Split (';');
676 defaultTargets = new string [0];
678 ProcessElements (xmlDocument.DocumentElement, null);
684 internal void ProcessElements (XmlElement rootElement, ImportedProject ip)
686 foreach (XmlNode xn in rootElement.ChildNodes) {
687 if (xn is XmlElement) {
688 XmlElement xe = (XmlElement) xn;
690 case "ProjectExtensions":
691 AddProjectExtensions (xe);
702 AddUsingTask (xe, ip);
708 AddItemGroup (xe, ip);
710 case "PropertyGroup":
711 AddPropertyGroup (xe, ip);
717 throw new InvalidProjectFileException ("Invalid element in project file.");
725 evaluatedItems = new BuildItemGroup (null, this, null, true);
726 evaluatedItemsIgnoringCondition = new BuildItemGroup (null, this, null, true);
727 evaluatedItemsByName = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
728 evaluatedItemsByNameIgnoringCondition = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
729 evaluatedProperties = new BuildPropertyGroup (null, null, null, true);
731 InitializeProperties ();
733 groupingCollection.Evaluate ();
735 //FIXME: UsingTasks aren't really evaluated. (shouldn't use expressions or anything)
736 foreach (UsingTask usingTask in UsingTasks)
737 usingTask.Evaluate ();
740 void InitializeProperties ()
744 foreach (BuildProperty gp in GlobalProperties) {
745 bp = new BuildProperty (gp.Name, gp.Value, PropertyType.Global);
746 EvaluatedProperties.AddProperty (bp);
749 foreach (DictionaryEntry de in Environment.GetEnvironmentVariables ()) {
750 bp = new BuildProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
751 EvaluatedProperties.AddProperty (bp);
754 EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved));
756 // FIXME: make some internal method that will work like GetDirectoryName but output String.Empty on null/String.Empty
758 if (FullFileName == String.Empty)
759 projectDir = Environment.CurrentDirectory;
761 projectDir = Path.GetDirectoryName (FullFileName);
763 EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectDirectory", projectDir, PropertyType.Reserved));
766 void AddProjectExtensions (XmlElement xmlElement)
770 void AddMessage (XmlElement xmlElement)
774 void AddTarget (XmlElement xmlElement, ImportedProject importedProject)
776 Target target = new Target (xmlElement, this, importedProject);
777 targets.AddTarget (target);
779 if (firstTargetName == null)
780 firstTargetName = target.Name;
783 void AddUsingTask (XmlElement xmlElement, ImportedProject importedProject)
787 usingTask = new UsingTask (xmlElement, this, importedProject);
788 UsingTasks.Add (usingTask);
791 void AddImport (XmlElement xmlElement, ImportedProject importingProject)
795 import = new Import (xmlElement, this, importingProject);
796 Imports.Add (import);
799 void AddItemGroup (XmlElement xmlElement, ImportedProject importedProject)
801 BuildItemGroup big = new BuildItemGroup (xmlElement, this, importedProject, false);
802 ItemGroups.Add (big);
805 void AddPropertyGroup (XmlElement xmlElement, ImportedProject importedProject)
807 BuildPropertyGroup bpg = new BuildPropertyGroup (xmlElement, this, importedProject, false);
808 PropertyGroups.Add (bpg);
811 void AddChoose (XmlElement xmlElement)
813 BuildChoose bc = new BuildChoose (xmlElement, this);
814 groupingCollection.Add (bc);
817 static void ValidationCallBack (object sender, ValidationEventArgs e)
819 Console.WriteLine ("Validation Error: {0}", e.Message);
822 public bool BuildEnabled {
827 buildEnabled = value;
832 public Encoding Encoding {
833 get { return encoding; }
836 public string DefaultTargets {
838 return xmlDocument.DocumentElement.GetAttribute ("DefaultTargets");
841 xmlDocument.DocumentElement.SetAttribute ("DefaultTargets", value);
842 defaultTargets = value.Split (';');
846 public BuildItemGroup EvaluatedItems {
848 if (needToReevaluate) {
849 needToReevaluate = false;
852 return evaluatedItems;
856 public BuildItemGroup EvaluatedItemsIgnoringCondition {
858 if (needToReevaluate) {
859 needToReevaluate = false;
862 return evaluatedItemsIgnoringCondition;
866 internal IDictionary <string, BuildItemGroup> EvaluatedItemsByName {
868 // FIXME: do we need to do this here?
869 if (needToReevaluate) {
870 needToReevaluate = false;
873 return evaluatedItemsByName;
877 internal IDictionary <string, BuildItemGroup> EvaluatedItemsByNameIgnoringCondition {
879 // FIXME: do we need to do this here?
880 if (needToReevaluate) {
881 needToReevaluate = false;
884 return evaluatedItemsByNameIgnoringCondition;
888 // For batching implementation
889 Dictionary<string, BuildItemGroup> perBatchItemsByName;
890 Dictionary<string, BuildItemGroup> commonItemsByName;
892 internal void SetBatchedItems (Dictionary<string, BuildItemGroup> perBatchItemsByName, Dictionary<string, BuildItemGroup> commonItemsByName)
894 this.perBatchItemsByName = perBatchItemsByName;
895 this.commonItemsByName = commonItemsByName;
899 internal bool TryGetEvaluatedItemByNameBatched (string itemName, out BuildItemGroup group)
901 if (perBatchItemsByName == null && commonItemsByName == null)
902 return EvaluatedItemsByName.TryGetValue (itemName, out group);
904 if (perBatchItemsByName != null)
905 return perBatchItemsByName.TryGetValue (itemName, out group);
907 if (commonItemsByName != null)
908 return commonItemsByName.TryGetValue (itemName, out group);
914 internal string GetMetadataBatched (string itemName, string metadataName)
916 BuildItemGroup group = null;
917 if (itemName == null) {
918 //unqualified, all items in a batch(bucket) have the
919 //same metadata values
920 group = GetFirst<BuildItemGroup> (perBatchItemsByName.Values);
922 group = GetFirst<BuildItemGroup> (commonItemsByName.Values);
925 TryGetEvaluatedItemByNameBatched (itemName, out group);
929 foreach (BuildItem item in group) {
930 if (item.HasMetadata (metadataName))
931 return item.GetMetadata (metadataName);
937 internal IEnumerable<BuildItemGroup> GetAllItemGroups ()
939 if (perBatchItemsByName == null && commonItemsByName == null)
940 foreach (BuildItemGroup group in EvaluatedItemsByName.Values)
943 if (perBatchItemsByName != null)
944 foreach (BuildItemGroup group in perBatchItemsByName.Values)
947 if (commonItemsByName != null)
948 foreach (BuildItemGroup group in commonItemsByName.Values)
952 T GetFirst<T> (ICollection<T> list)
957 foreach (T t in list)
963 public BuildPropertyGroup EvaluatedProperties {
965 if (needToReevaluate) {
966 needToReevaluate = false;
969 return evaluatedProperties;
973 public string FullFileName {
974 get { return fullFileName; }
975 set { fullFileName = value; }
978 public BuildPropertyGroup GlobalProperties {
979 get { return globalProperties; }
982 throw new ArgumentNullException ("value");
985 throw new InvalidOperationException ("GlobalProperties can not be set to persisted property group.");
987 globalProperties = value;
992 public bool IsDirty {
993 get { return isDirty; }
996 public bool IsValidated {
997 get { return isValidated; }
998 set { isValidated = value; }
1001 public BuildItemGroupCollection ItemGroups {
1002 get { return itemGroups; }
1005 public ImportCollection Imports {
1006 get { return imports; }
1009 public string InitialTargets {
1010 get { return initialTargets; }
1011 set { initialTargets = value; }
1014 public Engine ParentEngine {
1015 get { return parentEngine; }
1018 public BuildPropertyGroupCollection PropertyGroups {
1019 get { return propertyGroups; }
1022 public string SchemaFile {
1023 get { return schemaFile; }
1024 set { schemaFile = value; }
1027 public TargetCollection Targets {
1028 get { return targets; }
1031 public DateTime TimeOfLastDirty {
1032 get { return timeOfLastDirty; }
1035 public UsingTaskCollection UsingTasks {
1036 get { return usingTasks; }
1041 get { return xmlDocument.InnerXml; }
1044 internal Dictionary <string, BuildItemGroup> LastItemGroupContaining {
1045 get { return last_item_group_containing; }
1048 internal static XmlNamespaceManager XmlNamespaceManager {
1050 if (manager == null) {
1051 manager = new XmlNamespaceManager (new NameTable ());
1052 manager.AddNamespace ("tns", ns);
1059 internal TaskDatabase TaskDatabase {
1060 get { return taskDatabase; }
1063 internal XmlDocument XmlDocument {
1064 get { return xmlDocument; }
1067 internal static string XmlNamespace {