Well-Known metadata support is now in ProjectItemInstance too, sharing code with...
authorAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Wed, 27 Nov 2013 11:51:06 +0000 (20:51 +0900)
committerAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Fri, 29 Nov 2013 09:23:38 +0000 (18:23 +0900)
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollection.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectItem.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildEngine4.cs
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ProjectTaskItem.cs

index 5e5b90692b402268af64479bdcbe61345ff6628d..71f98269109924ca8af05b8f7b225fb26655ba31 100644 (file)
@@ -41,6 +41,7 @@ using System.IO;
 using System.Linq;
 using System.Xml;
 using System.Reflection;
+using System.Globalization;
 
 namespace Microsoft.Build.Evaluation
 {
@@ -451,5 +452,38 @@ namespace Microsoft.Build.Evaluation
                                }
                        }
                }
+               
+               static readonly char [] path_sep = {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar};
+               
+               internal static string GetWellKnownMetadata (string name, string file, Func<string,string> getFullPath, string recursiveDir)
+               {
+                       switch (name.ToLower (CultureInfo.InvariantCulture)) {
+                       case "fullpath":
+                               return getFullPath (file);
+                       case "rootdir":
+                               return Path.GetPathRoot (getFullPath (file));
+                       case "filename":
+                               return Path.GetFileNameWithoutExtension (file);
+                       case "extension":
+                               return Path.GetExtension (file);
+                       case "relativedir":
+                                       var idx = file.LastIndexOfAny (path_sep);
+                                       return idx < 0 ? string.Empty : file.Substring (0, idx + 1);
+                       case "directory":
+                                       var fp = getFullPath (file);
+                                       return Path.GetDirectoryName (fp).Substring (Path.GetPathRoot (fp).Length);
+                       case "recursivedir":
+                               return recursiveDir;
+                       case "identity":
+                               return file;
+                       case "modifiedtime":
+                               return new FileInfo (getFullPath (file)).LastWriteTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       case "createdtime":
+                               return new FileInfo (getFullPath (file)).CreationTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       case "accessedtime":
+                               return new FileInfo (getFullPath (file)).LastAccessTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       }
+                       return null;
+               }
        }
 }
index 47a00a88598ddbde3f01809c21eb1bbe30262c00..cc187f9b94c0b8e5f1f26d67bad8af188f55e205 100644 (file)
@@ -67,34 +67,14 @@ namespace Microsoft.Build.Evaluation
                {
                        return metadata.FirstOrDefault (m => m.Name == name);
                }
-               
-               static readonly char [] path_sep = {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar};
-               
-               static readonly Dictionary<string,Func<ProjectItem,string>> well_known_metadata = new Dictionary<string, Func<ProjectItem,string>> {
-                               {"FullPath", p => Path.Combine (p.Project.GetFullPath (p.evaluated_include)) },
-                               {"RootDir", p => Path.GetPathRoot (p.Project.GetFullPath (p.evaluated_include)) },
-                               {"Filename", p => Path.GetFileNameWithoutExtension (p.evaluated_include) },
-                               {"Extension", p => Path.GetExtension (p.evaluated_include) },
-                               {"RelativeDir", p => {
-                                       var idx = p.evaluated_include.LastIndexOfAny (path_sep);
-                                       return idx < 0 ? string.Empty : p.evaluated_include.Substring (0, idx + 1); }
-                                       },
-                               {"Directory", p => {
-                                       var fp = p.Project.GetFullPath (p.evaluated_include);
-                                       return Path.GetDirectoryName (fp).Substring (Path.GetPathRoot (fp).Length); }
-                                       },
-                               {"RecursiveDir", p => p.RecursiveDir },
-                               {"Identity", p => p.EvaluatedInclude },
-                               {"ModifiedTime", p => new FileInfo (p.Project.GetFullPath (p.evaluated_include)).LastWriteTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff") },
-                               {"CreatedTime", p => new FileInfo (p.Project.GetFullPath (p.evaluated_include)).CreationTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff") },
-                               {"AccessedTime", p => new FileInfo (p.Project.GetFullPath (p.evaluated_include)).LastAccessTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff") },
-                               };
 
                public string GetMetadataValue (string name)
                {
-                       var wellKnown = well_known_metadata.FirstOrDefault (p => p.Key.Equals (name, StringComparison.OrdinalIgnoreCase));
-                       if (wellKnown.Value != null)
-                               return wellKnown.Value (this);
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       var wk = ProjectCollection.GetWellKnownMetadata (name, EvaluatedInclude, project.GetFullPath, RecursiveDir);
+                       if (wk != null)
+                               return wk;
                        var m = GetMetadata (name);
                        return m != null ? m.EvaluatedValue : string.Empty;
                }
index bc941798097d0a5a401e0d0d0e0f1399bb7a8ac1..c6986e214987bdb86e74bbcb599e9be263b2d965 100644 (file)
@@ -512,6 +512,13 @@ namespace Microsoft.Build.Execution
                }
 
                internal BuildTaskDatabase TaskDatabase { get; private set; }
+               
+               internal string GetFullPath (string pathRelativeToProject)
+               {
+                       if (Path.IsPathRooted (pathRelativeToProject))
+                               return pathRelativeToProject;
+                       return Path.GetFullPath (Path.Combine (Directory, pathRelativeToProject));
+               }
        }
 }
 
index d437440334e42709c9c9124bbc0095898dcbf6f3..720c4b32b165710aa09f7359963358ca43a05120 100644 (file)
@@ -34,6 +34,8 @@ using Microsoft.Build.Framework;
 using Microsoft.Build.Evaluation;
 using System.Collections;
 using Microsoft.Build.Construction;
+using System.Globalization;
+using System.IO;
 
 namespace Microsoft.Build.Execution
 {
@@ -56,11 +58,19 @@ namespace Microsoft.Build.Execution
                
                public ProjectMetadataInstance GetMetadata (string name)
                {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       // This does not return any Well Known metadata
                        return Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
                }
 
                public string GetMetadataValue (string name)
                {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       var wk = ProjectCollection.GetWellKnownMetadata (name, EvaluatedInclude, project.GetFullPath, RecursiveDir);
+                       if (wk != null)
+                               return wk;
                        var m = GetMetadata (name);
                        return m != null ? m.EvaluatedValue : null;
                }
index 5c3ff664ee3962d1d1a5261c244f8e2b2bc69519..b259e7318b34177b7e0cf119d49cff3b300e8026 100644 (file)
@@ -269,7 +269,8 @@ namespace Microsoft.Build.Internal
                                        throw new InvalidOperationException (string.Format ("Task {0} does not have property {1}", ti.Name, p.Key));
                                if (!prop.CanWrite)
                                        throw new InvalidOperationException (string.Format ("Task {0} has property {1} but it is read-only.", ti.Name, p.Key));
-                               prop.SetValue (task, ConvertTo (value, prop.PropertyType), null);
+                               var valueInstance = ConvertTo (value, prop.PropertyType);
+                               prop.SetValue (task, valueInstance, null);
                        }
                        
                        // Do execute task.
@@ -308,7 +309,7 @@ namespace Microsoft.Build.Internal
                object ConvertTo (string source, Type targetType)
                {
                        if (targetType == typeof (ITaskItem) || targetType.IsSubclassOf (typeof (ITaskItem)))
-                               return new TargetOutputTaskItem () { ItemSpec = source };
+                               return new TargetOutputTaskItem () { ItemSpec = WindowsCompatibilityExtensions.NormalizeFilePath (source) };
                        if (targetType.IsArray)
                                return new ArrayList (source.Split (';').Where (s => !string.IsNullOrEmpty (s)).Select (s => ConvertTo (s, targetType.GetElementType ())).ToArray ())
                                                .ToArray (targetType.GetElementType ());
@@ -365,6 +366,9 @@ namespace Microsoft.Build.Internal
                        }
                        public string GetMetadata (string metadataName)
                        {
+                               var wk = ProjectCollection.GetWellKnownMetadata (metadataName, ItemSpec, Path.GetFullPath, null);
+                               if (wk != null)
+                                       return wk;
                                return (string) metadata [metadataName];
                        }
                        public void RemoveMetadata (string metadataName)
index 5a6bf161dff354a4a85ce01a5e8a6fe41c759a07..98d4bb2a583c3e0923389c1ca1a89462c205f007 100644 (file)
@@ -29,6 +29,8 @@ using System;
 using System.Linq;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using System.IO;
 
 namespace Microsoft.Build.Internal
 {
@@ -40,7 +42,7 @@ namespace Microsoft.Build.Internal
                public ProjectTaskItem (ProjectItemElement item, string evaluatedIncludePart)
                {
                        this.item = item;
-                       this.evaluated_include_part = evaluatedIncludePart;
+                       this.evaluated_include_part = WindowsCompatibilityExtensions.NormalizeFilePath (evaluatedIncludePart);
                }
                #region ITaskItem implementation
                System.Collections.IDictionary ITaskItem.CloneCustomMetadata ()
@@ -56,6 +58,9 @@ namespace Microsoft.Build.Internal
                }
                string ITaskItem.GetMetadata (string metadataName)
                {
+                       var wk = ProjectCollection.GetWellKnownMetadata (metadataName, evaluated_include_part, Path.GetFullPath, null);
+                       if (wk != null)
+                               return wk;
                        var mde = item.Metadata.FirstOrDefault (m => m.Name == metadataName);
                        return mde != null ? mde.Value : null;
                }