2007-05-17 Marek Sieradzki <marek.sieradzki@gmail.com>
authorMarek Sieradzki <msierad@mono-cvs.ximian.com>
Thu, 17 May 2007 11:41:35 +0000 (11:41 -0000)
committerMarek Sieradzki <msierad@mono-cvs.ximian.com>
Thu, 17 May 2007 11:41:35 +0000 (11:41 -0000)
        * ResolveAssemblyReference.cs
        * AssemblyResolver.cs: Resolve HintPath properly.

svn path=/trunk/mcs/; revision=77538

mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs

index 6ecbe4a28f21cc49a478987bd097d7a75e1b1dc6..2beb067cd29ed48d48be79ce8ad62b7264bd667c 100644 (file)
@@ -40,15 +40,12 @@ namespace Microsoft.Build.Tasks {
 
                // name -> (version -> assemblypath)
                Dictionary <string, Dictionary <Version, string>> gac;
+               TaskLoggingHelper log;
 
-               Dictionary <string, Dictionary <Version, string>> hint_path_assemblies;
-               Dictionary <string, object> hint_paths;
-       
                public AssemblyResolver ()
                {
                        gac = new Dictionary <string, Dictionary <Version, string>> ();
-                       hint_path_assemblies = new Dictionary <string, Dictionary <Version, string>> ();
-                       hint_paths = new Dictionary <string, object> ();
+
                        GatherGacAssemblies ();
                }
 
@@ -89,64 +86,33 @@ namespace Microsoft.Build.Tasks {
                        }
                }
 
-               void GatherHintPathAssemblies (string hintPath)
-               {
-                       if (hint_paths.ContainsKey (hintPath))
-                               return;
-
-                       Assembly a;
-                       AssemblyName name;
-
-                       try {
-                               foreach (string assembly_name in Directory.GetFiles (Path.GetDirectoryName (hintPath))) {
-                                       try {
-                                               a = Assembly.ReflectionOnlyLoadFrom (assembly_name);
-                                               name = new AssemblyName (a.FullName);
-       
-                                               if (!hint_path_assemblies.ContainsKey (name.Name))
-                                                       hint_path_assemblies [name.Name] = new Dictionary <Version, string> ();
-                                               hint_path_assemblies [name.Name] [name.Version] = assembly_name;
-                                               hint_paths [hintPath] = null;
-                                       } catch {
-                                       }
-                               }
-                       } catch {
-                       }
-               }
-
                public string ResolveAssemblyReference (ITaskItem reference)
                {
                        AssemblyName name = null;
                        string resolved = null;
 
-                       try {
-                               name = new AssemblyName (reference.ItemSpec);
-                       } catch {
-                               return null;
-                       }
+                       name = new AssemblyName (reference.ItemSpec);
+
+                       if (reference.GetMetadata ("HintPath") != String.Empty) {
+
+                               bool specificVersion;
 
-                       if (reference.GetMetadata ("HintPath") != String.Empty)
-                               resolved = ResolveHintPathReference (name, reference.GetMetadata ("HintPath"));
+                               if (reference.GetMetadata ("SpecificVersion") != String.Empty) {
+                                       specificVersion = Boolean.Parse (reference.GetMetadata ("SpecificVersion"));
+                               } else {
+                                       specificVersion = IsStrongNamed (name);
+                               }
+
+                               resolved = ResolveHintPathReference (name, reference.GetMetadata ("HintPath"), specificVersion);
+                       }
                        
                        if (resolved == null)
-                               resolved = ResolveGacReference (name);
+                               resolved = ResolveGacReference (name, gac);
 
                        return resolved;
                }
 
-               string ResolveGacReference (AssemblyName name)
-               {
-                       return ResolveGenericReference (name, gac);
-               }
-
-               string ResolveHintPathReference (AssemblyName name, string hintpath)
-               {
-                       if (hintpath != String.Empty)
-                               GatherHintPathAssemblies (hintpath);
-                       return ResolveGenericReference (name, hint_path_assemblies);
-               }
-
-               string ResolveGenericReference (AssemblyName name, Dictionary <string, Dictionary <Version, string>> dic)
+               string ResolveGacReference (AssemblyName name, Dictionary <string, Dictionary <Version, string>> dic)
                {
                        // FIXME: deal with SpecificVersion=False
 
@@ -166,6 +132,63 @@ namespace Microsoft.Build.Tasks {
                        Version highest = versions [versions.Length - 1];
                        return dic [name.Name] [highest];
                }
+
+               string ResolveHintPathReference (AssemblyName name, string hintpath, bool specificVersion)
+               {
+                       AssemblyName found;
+                       string ret = null;
+
+                       if (!File.Exists (hintpath))
+                               log.LogMessage (MessageImportance.Low, "HintPath {0} does not exist.", hintpath);
+
+                       try {
+                               found = AssemblyName.GetAssemblyName (hintpath);
+                               if (AssemblyNamesCompatible (name, found, specificVersion))
+                                       ret = hintpath;
+                               else
+                                       log.LogMessage (MessageImportance.Low, "Assembly names are not compatible.");
+                       } catch {
+                       }
+
+                       return ret;
+               }
+
+               static bool AssemblyNamesCompatible (AssemblyName a, AssemblyName b, bool specificVersion)
+               {
+                       if (a.Name != b.Name)
+                               return false;
+
+                       if (a.CultureInfo != null && a.CultureInfo != b.CultureInfo)
+                               return false;
+
+                       if (specificVersion && a.Version != null && a.Version > b.Version)
+                               return false;
+
+                       byte [] a_bytes = a.GetPublicKeyToken ();
+                       byte [] b_bytes = b.GetPublicKeyToken ();
+
+                       if (specificVersion) {
+                               if (a_bytes == null || a_bytes.Length == 0)
+                                       return false;
+                               if (b_bytes == null || b_bytes.Length == 0)
+                                       return false;
+
+                               for (int i = 0; i < a_bytes.Length; i++)
+                                       if (a_bytes [i] != b_bytes [i])
+                                               return false;
+                       }
+
+                       return true;
+               }
+
+               static bool IsStrongNamed (AssemblyName name)
+               {
+                       return (name.Version != null && name.GetPublicKeyToken ().Length != 0);
+               }
+
+               public TaskLoggingHelper Log {
+                       set { log = value; }
+               }
        }
 }
 
index 2c7492e083736a308491dc1ba5143f93b2d3ee3f..398584cefbe2d4d3f8afa59c5bcbb7af25eacfeb 100644 (file)
@@ -1,3 +1,8 @@
+2007-05-17  Marek Sieradzki  <marek.sieradzki@gmail.com>
+
+       * ResolveAssemblyReference.cs
+       * AssemblyResolver.cs: Resolve HintPath properly.
+
 2007-03-19  Marek Sieradzki  <marek.sieradzki@gmail.com>
 
        * CombinePath.cs: Implemented.
index 8b8ea842f6e698f091555d84627fd58c8e941770..2af876b0dc9aa14d74a77c3bc81c56144c089ebf 100644 (file)
@@ -72,6 +72,7 @@ namespace Microsoft.Build.Tasks {
 
                public override bool Execute ()
                {
+                       assembly_resolver.Log = Log;
                        List <ITaskItem> tempResolvedFiles = new List <ITaskItem> ();
                
                        foreach (ITaskItem item in assemblies) {