#if NET_2_0
using System;
+using System.Collections.Generic;
+using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Microsoft.Build.BuildEngine {
- internal class MetadataReference {
+ internal class MetadataReference : IReference {
string itemName;
string metadataName;
- Expression parent;
+ int start;
+ int length;
- public MetadataReference (Expression parent)
+ public MetadataReference (string itemName, string metadataName, int start, int length)
{
- this.itemName = null;
- this.metadataName = null;
- this.parent = parent;
- }
-
- public MetadataReference (Expression parent, string source)
- {
- this.parent = parent;
- ParseSource (source);
- }
-
- public MetadataReference (Expression parent, string itemName, string metadataName)
- {
- this.parent = parent;
this.itemName = itemName;
this.metadataName = metadataName;
- }
-
- public void ParseSource (string source)
- {
- string sourceWithoutParens;
- int dot;
-
- if (source.Length < 4)
- throw new ArgumentException ("source is too short.");
-
- sourceWithoutParens = source.Substring (2, source.Length - 3);
- dot = sourceWithoutParens.IndexOf ('.');
-
- if (dot != -1) {
- itemName = sourceWithoutParens.Substring (0, dot);
- metadataName = sourceWithoutParens.Substring (dot + 1, sourceWithoutParens.Length - dot - 1);
- } else {
- metadataName = sourceWithoutParens;
- }
+ this.start = start;
+ this.length = length;
}
public string ItemName {
public bool IsQualified {
get { return (itemName == null) ? false : true; }
}
+
+ public int Start {
+ get { return start; }
+ }
+
+ public int End {
+ get { return start + length - 1; }
+ }
+
+ public string ConvertToString (Project project)
+ {
+ return project.GetMetadataBatched (itemName, metadataName);
+ }
+
+ public ITaskItem [] ConvertToITaskItemArray (Project project)
+ {
+ List<ITaskItem> items = new List<ITaskItem> ();
+ if (IsQualified) {
+ // Bucket would have item lists with same metadata values,
+ // so just get the value from the first item
+ BuildItemGroup group;
+ if (project.TryGetEvaluatedItemByNameBatched (itemName, out group))
+ BuildItemGroupToITaskItems (group, items, true);
+ } else {
+ // Get unique metadata values from _all_ item lists
+ foreach (BuildItemGroup group in project.GetAllItemGroups ())
+ BuildItemGroupToITaskItems (group, items, false);
+ }
+
+ return items.Count == 0 ? null : items.ToArray ();
+ }
+
+ // Gets metadata values from build item @group and adds as ITaskItem
+ // objects to @items
+ // @only_one: Batched case, all item lists would have same metadata values,
+ // just return first one
+ void BuildItemGroupToITaskItems (BuildItemGroup group, List<ITaskItem> items, bool only_one)
+ {
+ foreach (BuildItem item in group) {
+ if (!item.HasMetadata (metadataName))
+ continue;
+
+ string metadata = item.GetMetadata (metadataName);
+ if (HasTaskItem (items, metadata))
+ //return only unique metadata values
+ continue;
+
+ items.Add (new TaskItem (metadata));
+ if (only_one)
+ break;
+ }
+ }
+
+ private bool HasTaskItem (List<ITaskItem> items, string itemspec)
+ {
+ foreach (ITaskItem task_item in items)
+ if (task_item.ItemSpec == itemspec)
+ return true;
+ return false;
+ }
+
+ public override string ToString ()
+ {
+ if (IsQualified)
+ return String.Format ("%({0}.{1})", itemName, metadataName);
+ else
+ return String.Format ("%({0})", metadataName);
+ }
}
}
-#endif
\ No newline at end of file
+#endif