[xbuild] Add support for Before/AfterTargets.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Project.cs
index f41ba855164d9df2c567a5a3404f22ba5bbbb831..533f7b4f3a550131495daf81580eab3b93442844 100644 (file)
@@ -32,6 +32,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.IO;
+using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Xml;
@@ -314,7 +315,11 @@ namespace Microsoft.Build.BuildEngine {
                                needToReevaluate = false;
                                Reevaluate ();
                        }
-                       
+
+#if NET_4_0
+                       ProcessBeforeAndAfterTargets ();
+#endif
+
                        if (targetNames == null || targetNames.Length == 0) {
                                if (defaultTargets != null && defaultTargets.Length != 0) {
                                        targetNames = defaultTargets;
@@ -388,6 +393,44 @@ namespace Microsoft.Build.BuildEngine {
                        return sb.ToString ();
                }
 
+#if NET_4_0
+               void ProcessBeforeAndAfterTargets ()
+               {
+                       var beforeTable = Targets.AsIEnumerable ()
+                                               .SelectMany (target => GetTargetNamesFromString (target.BeforeTargets),
+                                                               (target, before_target) => new {before_target, name = target.Name})
+                                               .ToLookup (x => x.before_target, x => x.name)
+                                               .ToDictionary (x => x.Key, x => x.Distinct ().ToList ());
+
+                       foreach (var pair in beforeTable) {
+                               if (targets.Exists (pair.Key))
+                                       targets [pair.Key].BeforeThisTargets = pair.Value;
+                               else
+                                       LogWarning (FullFileName, "Target '{0}', not found in the project", pair.Key);
+                       }
+
+                       var afterTable = Targets.AsIEnumerable ()
+                                               .SelectMany (target => GetTargetNamesFromString (target.AfterTargets),
+                                                               (target, after_target) => new {after_target, name = target.Name})
+                                               .ToLookup (x => x.after_target, x => x.name)
+                                               .ToDictionary (x => x.Key, x => x.Distinct ().ToList ());
+
+                       foreach (var pair in afterTable) {
+                               if (targets.Exists (pair.Key))
+                                       targets [pair.Key].AfterThisTargets = pair.Value;
+                               else
+                                       LogWarning (FullFileName, "Target '{0}', not found in the project", pair.Key);
+                       }
+               }
+
+               string[] GetTargetNamesFromString (string targets)
+               {
+                       Expression expr = new Expression ();
+                       expr.Parse (targets, ParseOptions.AllowItemsNoMetadataAndSplit);
+                       return (string []) expr.ConvertTo (this, typeof (string []));
+               }
+#endif
+
                [MonoTODO]
                public string [] GetConditionedPropertyValues (string propertyName)
                {