Merge branch 'BigIntegerParse'
[mono.git] / mcs / class / Microsoft.Build.Utilities / Microsoft.Build.Utilities / TaskItem.cs
index 8bfa5cd70b8b5cfbe010c259afa22e36d5d6ba03..0928d929335a78ef2d7a4319e3c24b847dcf729e 100644 (file)
@@ -32,92 +32,120 @@ using System.Collections;
 using System.Collections.Specialized;
 using System.IO;
 using Microsoft.Build.Framework;
+using Mono.XBuild.Utilities;
 
 namespace Microsoft.Build.Utilities
 {
-       public sealed class TaskItem : MarshalByRefObject, ITaskItem
+#if !MICROSOFT_BUILD_DLL
+       public
+#endif
+       sealed class TaskItem : MarshalByRefObject, ITaskItem
+#if NET_4_0
+               , ITaskItem2
+#endif
        {
-               IDictionary     metadata;
-               string          itemSpec;
-               string          recursiveDir;
-               
+               IDictionary             escapedMetadata;
+               string                  escapedItemSpec;
+
                public TaskItem ()
                {
-                       this.itemSpec = String.Empty;
-                       this.recursiveDir = String.Empty;
-                       this.metadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+                       this.escapedItemSpec = String.Empty;
+                       this.escapedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
                }
 
                public TaskItem (ITaskItem sourceItem)
                {
-                       this.itemSpec = sourceItem.ItemSpec;
-                       this.recursiveDir = String.Empty;
-                       this.metadata = sourceItem.CloneCustomMetadata ();
+                       if (sourceItem == null)
+                               throw new ArgumentNullException ("sourceItem");
+
+#if NET_4_0
+                       var ti2 = sourceItem as ITaskItem2;
+                       if (ti2 != null) {
+                               escapedItemSpec = ti2.EvaluatedIncludeEscaped;
+                               escapedMetadata = ti2.CloneCustomMetadataEscaped ();
+                       } else
+#endif
+                       {
+                               escapedItemSpec = MSBuildUtils.Escape (sourceItem.ItemSpec);
+                               escapedMetadata = sourceItem.CloneCustomMetadata ();
+                               foreach (string key in new ArrayList (escapedMetadata.Keys))
+                                       escapedMetadata [key] = MSBuildUtils.Escape ((string)escapedMetadata [key]);
+                       }
                }
 
                public TaskItem (string itemSpec)
                {
-                       this.ItemSpec = itemSpec;
-                       this.recursiveDir = String.Empty;
-                       this.metadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+                       if (itemSpec == null)
+                               throw new ArgumentNullException ("itemSpec");
+                       
+                       escapedItemSpec = itemSpec;
+                       escapedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
                }
 
                public TaskItem (string itemSpec, IDictionary itemMetadata)
                {
-                       this.itemSpec = itemSpec;
-                       this.recursiveDir = String.Empty;
-                       this.metadata = itemMetadata;
+                       if (itemSpec == null)
+                               throw new ArgumentNullException ("itemSpec");
+                       
+                       if (itemMetadata == null)
+                               throw new ArgumentNullException ("itemMetadata");
+                       
+                       escapedItemSpec = itemSpec;
+                       escapedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable (itemMetadata);
                }
 
                public IDictionary CloneCustomMetadata ()
                {
                        IDictionary clonedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
-                       foreach (DictionaryEntry de in metadata)
-                               clonedMetadata.Add (de.Key, de.Value);
+                       foreach (DictionaryEntry de in escapedMetadata)
+                               clonedMetadata.Add (de.Key, MSBuildUtils.Unescape ((string) de.Value));
                        return clonedMetadata;
                }
 
+               IDictionary CloneCustomMetadataEscaped ()
+               {
+                       return CollectionsUtil.CreateCaseInsensitiveHashtable (escapedMetadata);
+               }
+
+#if NET_4_0
+               IDictionary ITaskItem2.CloneCustomMetadataEscaped ()
+               {
+                       return CloneCustomMetadataEscaped ();
+               }
+#endif
+
                public void CopyMetadataTo (ITaskItem destinationItem)
                {
-                       foreach (DictionaryEntry e in metadata) {
-                               destinationItem.SetMetadata ((string)e.Key, (string)e.Value);
+                       foreach (DictionaryEntry e in escapedMetadata) {
+                               if (destinationItem.GetMetadata ((string)e.Key) == String.Empty) {
+                                       destinationItem.SetMetadata ((string)e.Key, MSBuildUtils.Unescape ((string)e.Value));
+                               }
                        }
                }
 
                public static explicit operator string (TaskItem taskItemToCast)
                {
-                       return taskItemToCast.ToString ();
+                       return taskItemToCast.ItemSpec;
                }
 
                public string GetMetadata (string metadataName)
                {
-                       switch (metadataName.ToLower ()) {
-                       case "fullpath":
-                               return Path.GetFullPath (itemSpec);
-                       case "rootdir":
-                               return "/";
-                       case "filename":
-                               return Path.GetFileNameWithoutExtension (itemSpec);
-                       case "extension":
-                               return Path.GetExtension (itemSpec);
-                       case "relativedir":
-                               return Path.GetDirectoryName (itemSpec);
-                       case "directory":
-                               return Path.GetDirectoryName (Path.GetFullPath (itemSpec));
-                       case "recursivedir":
-                               return recursiveDir;
-                       case "identity":
-                               return Path.Combine (Path.GetDirectoryName (itemSpec), Path.GetFileName (itemSpec));
-                       case "modifiedtime":
-                               return File.GetLastWriteTime (itemSpec).ToString ();
-                       case "createdtime":
-                               return File.GetCreationTime (itemSpec).ToString ();
-                       case "accessedtime":
-                               return File.GetLastAccessTime (itemSpec).ToString ();
-                       default:
-                               return (string) metadata [metadataName];
-                       }
+                       return MSBuildUtils.Unescape (GetMetadataValue (metadataName));
+               }
+
+               string GetMetadataValue (string metadataName)
+               {
+                       if (ReservedNameUtils.IsReservedMetadataName (metadataName))
+                               return ReservedNameUtils.GetReservedMetadata (ItemSpec, metadataName, escapedMetadata);
+                       return ((string) escapedMetadata [metadataName]) ?? String.Empty;
+               }
+
+#if NET_4_0
+               string ITaskItem2.GetMetadataValueEscaped (string metadataName)
+               {
+                       return GetMetadataValue (metadataName);
                }
+#endif
 
                public override object InitializeLifetimeService ()
                {
@@ -126,36 +154,69 @@ namespace Microsoft.Build.Utilities
 
                public void RemoveMetadata (string metadataName)
                {
-                       if (metadata.Contains (metadataName))
-                               metadata.Remove (metadataName);
+                       if (metadataName == null)
+                               throw new ArgumentNullException ("metadataName");
+                       if (ReservedNameUtils.IsReservedMetadataName (metadataName))
+                               throw new ArgumentException ("Can't remove reserved metadata");
+                       escapedMetadata.Remove (metadataName);
                }
 
                public void SetMetadata (string metadataName, string metadataValue)
                {
-                       if (metadata.Contains (metadataName))
-                               metadata.Remove (metadataName);
-                       metadata.Add (metadataName, metadataValue);
+                       if (metadataName == null)
+                               throw new ArgumentNullException ("metadataName");
+                       if (metadataValue == null)
+                               throw new ArgumentNullException ("metadataValue");
+
+                       // allow RecursiveDir to be set, it gets set by DirectoryScanner
+                       if (String.Compare (metadataName, "RecursiveDir", StringComparison.InvariantCultureIgnoreCase) != 0 &&
+                               ReservedNameUtils.IsReservedMetadataName (metadataName))
+                               throw new ArgumentException ("Can't modify reserved metadata");
+                               
+                       escapedMetadata [metadataName] = metadataValue;
                }
 
+#if NET_4_0
+               void ITaskItem2.SetMetadataValueLiteral (string metadataName, string metadataValue)
+               {
+                       SetMetadata (metadataName, MSBuildUtils.Escape (metadataValue));
+               }
+#endif
                public override string ToString ()
                {
-                       return itemSpec;
+                       return escapedItemSpec;
                }
-
+               
                public string ItemSpec {
-                       get { return itemSpec; }
-                       set { itemSpec = value; }
+                       get { return MSBuildUtils.Unescape (escapedItemSpec); }
+                       set { escapedItemSpec = value; }
+               }
+
+#if NET_4_0
+               string ITaskItem2.EvaluatedIncludeEscaped {
+                       get { return escapedItemSpec; }
+                       set { escapedItemSpec = value; }
                }
+#endif
 
                public int MetadataCount {
-               // predefined metadata
-                       get { return metadata.Count + 11; }
+                       get { return escapedMetadata.Count + 11; }
                }
 
                public ICollection MetadataNames {
-                       get { return metadata.Keys; }
+                       get {
+                               ArrayList list = new ArrayList ();
+                               
+                               foreach (string s in ReservedNameUtils.ReservedMetadataNames)
+                                       list.Add (s);
+                               foreach (string s in escapedMetadata.Keys)
+                                       list.Add (s);
+
+                               return list;
+                       }
                }
+
        }
 }
 
-#endif
\ No newline at end of file
+#endif