[xbuild]: Fix task batching for <ItemGroup> inside <Target>.
authorMartin Baulig <martin.baulig@xamarin.com>
Thu, 23 May 2013 17:02:43 +0000 (19:02 +0200)
committerMartin Baulig <martin.baulig@xamarin.com>
Thu, 23 May 2013 19:03:26 +0000 (21:03 +0200)
This fixes

<Target Name="Simple">
<ItemGroup>
<Foo Include="A;B" />
<All Include="%(Foo.Identity)" />
</ItemGroup>
<Message Text="ALL: @(All)" />
</Target>

mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItemGroup.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTaskItem.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTaskItemGroup.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Target.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/TargetTest.cs

index 034ead032b841e68c1191c27504d61bfe3a51fd4..25f2cb0d49cc40ee37752cdb331847c0c96e7d56 100644 (file)
@@ -78,7 +78,7 @@ namespace Microsoft.Build.BuildEngine {
                                        continue;
                                        
                                XmlElement xe = (XmlElement) xn;
-                               BuildItem bi = new BuildItem (xe, this);
+                               BuildItem bi = CreateItem (project, xe);
                                buildItems.Add (bi);
                                project.LastItemGroupContaining [bi.Name] = this;
                        }
@@ -87,6 +87,11 @@ namespace Microsoft.Build.BuildEngine {
                                                project != null ? project.FullFileName : null;
                }
 
+               internal virtual BuildItem CreateItem (Project project, XmlElement xe)
+               {
+                       return new BuildItem (xe, this);
+               }
+
                public BuildItem AddNewItem (string itemName,
                                             string itemInclude)
                {
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTaskItem.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTaskItem.cs
new file mode 100644 (file)
index 0000000..4b6925c
--- /dev/null
@@ -0,0 +1,64 @@
+//
+// BuildTaskItem.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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 "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Microsoft.Build.BuildEngine
+{
+       internal class BuildTaskItem : BuildItem, IBuildTask
+       {
+               Project project;
+
+               public bool ContinueOnError {
+                       get; set;
+               }
+               
+               internal BuildTaskItem (Project project, XmlElement itemElement, BuildTaskItemGroup parentItemGroup)
+                       : base (itemElement, parentItemGroup)
+               {
+                       this.project = project;
+               }
+
+               public bool Execute ()
+               {
+                       if (Condition == String.Empty)
+                               Evaluate (project, true);
+                       else {
+                               ConditionExpression ce = ConditionParser.ParseCondition (Condition);
+                               Evaluate (project, ce.BoolEvaluate (project));
+                       }
+                       return true;
+               }
+               
+               public IEnumerable<string> GetAttributes ()
+               {
+                       foreach (XmlAttribute attrib in XmlElement.Attributes)
+                               yield return attrib.Value;
+               }
+       }
+}
+
index 9449cd8a35a2ffe3531d234e95d7e4a97186b153..2e4960b9e7f294d608d5fa31ae170baab94c3b2e 100644 (file)
@@ -30,34 +30,25 @@ using System.Xml;
 
 namespace Microsoft.Build.BuildEngine {
 
-       internal class BuildTaskItemGroup : BuildItemGroup, IBuildTask {
+       internal class BuildTaskItemGroup : BuildItemGroup {
 
-               public bool ContinueOnError {
-                       get; set;
-               }
+               List<BuildTaskItem> items = new List<BuildTaskItem> ();
 
                internal BuildTaskItemGroup (XmlElement element, Target target)
                        : base (element, target.Project, null, false, true)
                {
                }
-               
-               public bool Execute ()
-               {
-                       Evaluate ();
-                       return true;
-               }
 
-               public IEnumerable<string> GetAttributes ()
+               internal override BuildItem CreateItem (Project project, XmlElement xe)
                {
-                       foreach (XmlAttribute attrib in XmlElement.Attributes)
-                               yield return attrib.Value;
-
-                       foreach (BuildItem item in this) {
-                               foreach (XmlAttribute attrib in item.XmlElement.Attributes)
-                                       yield return attrib.Value;
-                       }
+                       var item = new BuildTaskItem (project, xe, this);
+                       items.Add (item);
+                       return item;
                }
 
+               public List<BuildTaskItem> Items {
+                       get { return items; }
+               }
        }
 }
 
index 430ea1daf73cf5b5b6c86a51dca8c9e1d07a03c0..250c7942bd1abfc0d448cfca22495f57c8815092 100644 (file)
@@ -79,7 +79,8 @@ namespace Microsoft.Build.BuildEngine {
                                                        "The element <OnError> must be last under element <Target>. Found element <Error> instead.");
 #if NET_3_5
                                        else if (xe.Name == "ItemGroup") {
-                                               buildTasks.Add (new BuildTaskItemGroup (xe, this));
+                                               var group = new BuildTaskItemGroup (xe, this);
+                                               buildTasks.AddRange (group.Items);
                                                continue;
                                        } else if (xe.Name == "PropertyGroup") {
                                                buildTasks.Add (new BuildTaskPropertyGroup (xe, this));
index fa51fafd89f245d24a4b15fce24a2e21fd759cdb..9081b936b5da8b302def303583eaa962a4658bd4 100644 (file)
@@ -18,6 +18,7 @@ Microsoft.Build.BuildEngine/BuildPropertyGroupCollection.cs
 Microsoft.Build.BuildEngine/BuildPropertyGroup.cs
 Microsoft.Build.BuildEngine/BuildSettings.cs
 Microsoft.Build.BuildEngine/BuildTask.cs
+Microsoft.Build.BuildEngine/BuildTaskItem.cs
 Microsoft.Build.BuildEngine/BuildTaskItemGroup.cs
 Microsoft.Build.BuildEngine/BuildTaskPropertyGroup.cs
 Microsoft.Build.BuildEngine/BuildWhen.cs
index 03edf3db2b09f01b3164203c8a92626c59c7e731..dea87802db5f1723a4ae47db3727ba0bcee73cdd 100644 (file)
@@ -692,7 +692,21 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                </Project>", "D");
                }
 
-#endif
+               [Test]
+               public void ItemGroupInsideTarget_Batching ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                                       <Target Name='Main'>
+                                               <ItemGroup>
+                                                       <Foo Include='A;B' />
+                                                       <All Include='%(Foo.Identity)' />
+                                               </ItemGroup>
+                                               <Message Text='%(All.Identity)' />
+                                       </Target>
+                               </Project>", "A", "B");
+               }
+               #endif
 
                [Test]
                public void TestTargetOutputsIncludingMetadata ()