X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMicrosoft.Build.Tasks%2FMicrosoft.Build.Tasks%2FAssemblyResolver.cs;h=143b005366fa1ea1bbdf9a8e6dd810b3188c1626;hb=c5c194098baf1d1478473bf3097c85288281c2f7;hp=9298ba06891dae1ae2b120c2acc759f923d2f105;hpb=88930ed14c18818b25887754ae630485bf3bbb0b;p=mono.git diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs index 9298ba06891..143b005366f 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs @@ -121,7 +121,10 @@ namespace Microsoft.Build.Tasks { if (!Directory.Exists (framework_dir)) return null; - AssemblyName key_aname = new AssemblyName (reference.ItemSpec); + AssemblyName key_aname; + if (!TryGetAssemblyNameFromFullName (reference.ItemSpec, out key_aname)) + return null; + TargetFrameworkAssemblies gac_asm; if (!target_framework_cache.TryGetValue (framework_dir, out gac_asm)) { // fill gac_asm @@ -130,7 +133,7 @@ namespace Microsoft.Build.Tasks { KeyValuePair pair; if (gac_asm.NameToAssemblyNameCache.TryGetValue (key_aname.Name, out pair)) { - if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version, true)) { + if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version)) { // gac and tgt frmwk refs are not copied private return GetResolvedReference (reference, pair.Value, pair.Key, false, SearchPath.TargetFrameworkDirectory); @@ -146,40 +149,57 @@ namespace Microsoft.Build.Tasks { return null; } - public ResolvedReference FindInDirectory (ITaskItem reference, string directory, string [] file_extensions) + // Look for %(Identity).{dll|exe|..} + // if specific_version==true + // resolve if assembly names match + // else + // resolve the valid assembly + public ResolvedReference FindInDirectory (ITaskItem reference, string directory, string [] file_extensions, bool specific_version) { - if (reference.ItemSpec.IndexOf (',') < 0) { - // Try as a filename - string path = Path.Combine (directory, reference.ItemSpec); - AssemblyName aname = GetAssemblyNameFromFile (path); - if (aname != null) - return GetResolvedReference (reference, path, aname, true, SearchPath.Directory); - - foreach (string extn in file_extensions) { - string path_with_extn = path + extn; - aname = GetAssemblyNameFromFile (path_with_extn); - if (aname != null) - return GetResolvedReference (reference, path_with_extn, aname, true, - SearchPath.Directory); - } - } + string filename = reference.ItemSpec; + int comma_pos = filename.IndexOf (','); + if (comma_pos >= 0) + filename = filename.Substring (0, comma_pos); - // Probably an assembly name - AssemblyName key_aname = new AssemblyName (reference.ItemSpec); + // Try as a filename + string path = Path.GetFullPath (Path.Combine (directory, filename)); + AssemblyName aname = null; + if (specific_version && !TryGetAssemblyNameFromFullName (reference.ItemSpec, out aname)) + return null; + + ResolvedReference resolved_ref = ResolveReferenceForPath (path, reference, aname, null, SearchPath.Directory, specific_version); + if (resolved_ref != null) + return resolved_ref; + + // try path + Include + {.dll|.exe|..} foreach (string extn in file_extensions) { - foreach (string file in Directory.GetFiles (directory, "*" + extn)) { - AssemblyName found_aname = GetAssemblyNameFromFile (file); - if (found_aname == null) - // error already logged - continue; - - //FIXME: Extract 'name' and look only for name.dll name.exe ? - if (AssemblyNamesCompatible (key_aname, found_aname, false)) - return GetResolvedReference (reference, file, found_aname, true, - SearchPath.Directory); - - LogSearchMessage ("Considered {0}, but assembly name wasn't compatible.", file); - } + resolved_ref = ResolveReferenceForPath (path + extn, reference, aname, null, SearchPath.Directory, specific_version); + if (resolved_ref != null) + return resolved_ref; + } + + return null; + } + + // tries to resolve reference from the given file path, and compares assembly names + // if @specific_version == true, and logs accordingly + ResolvedReference ResolveReferenceForPath (string filename, ITaskItem reference, AssemblyName aname, + string error_message, SearchPath spath, bool specific_version) + { + AssemblyName found_aname; + if (!TryGetAssemblyNameFromFile (filename, out found_aname)) { + if (error_message != null) + log.LogMessage (MessageImportance.Low, error_message); + return null; + } + + if (!specific_version || AssemblyNamesCompatible (aname, found_aname, specific_version)) { + // Check compatibility only if specific_version == true + return GetResolvedReference (reference, filename, found_aname, true, spath); + } else { + LogSearchMessage ("Considered '{0}', but assembly name '{1}' did not match the " + + "expected '{2}' (SpecificVersion={3})", filename, found_aname, aname, specific_version); + log.LogMessage (MessageImportance.Low, "Assembly names are not compatible."); } return null; @@ -189,8 +209,8 @@ namespace Microsoft.Build.Tasks { { TargetFrameworkAssemblies gac_asm = new TargetFrameworkAssemblies (directory); foreach (string file in Directory.GetFiles (directory, "*.dll")) { - AssemblyName aname = GetAssemblyNameFromFile (file); - if (aname != null) + AssemblyName aname; + if (TryGetAssemblyNameFromFile (file, out aname)) gac_asm.NameToAssemblyNameCache [aname.Name] = new KeyValuePair (aname, file); } @@ -200,7 +220,10 @@ namespace Microsoft.Build.Tasks { public ResolvedReference ResolveGacReference (ITaskItem reference, bool specific_version) { - AssemblyName name = new AssemblyName (reference.ItemSpec); + AssemblyName name; + if (!TryGetAssemblyNameFromFullName (reference.ItemSpec, out name)) + return null; + if (!gac.ContainsKey (name.Name)) { LogSearchMessage ("Considered {0}, but could not find in the GAC.", reference.ItemSpec); @@ -249,7 +272,11 @@ namespace Microsoft.Build.Tasks { return null; } - ResolvedReference rr = GetResolvedReference (reference, pkg.File, new AssemblyName (pkg.FullName), + AssemblyName aname; + if (!TryGetAssemblyNameFromFullName (pkg.FullName, out aname)) + return null; + + ResolvedReference rr = GetResolvedReference (reference, pkg.File, aname, false, SearchPath.PkgConfig); rr.FoundInSearchPathAsString = String.Format ("{{PkgConfig}} provided by package named {0}", pkg.ParentPackage.Name); @@ -257,11 +284,13 @@ namespace Microsoft.Build.Tasks { return rr; } + // HintPath has a valid assembly + // if specific_version==true + // resolve if assembly names match + // else + // resolve the valid assembly public ResolvedReference ResolveHintPathReference (ITaskItem reference, bool specific_version) { - AssemblyName name = new AssemblyName (reference.ItemSpec); - ResolvedReference resolved = null; - string hintpath = reference.GetMetadata ("HintPath"); if (String.IsNullOrEmpty (hintpath)) { LogSearchMessage ("HintPath attribute not found"); @@ -274,26 +303,18 @@ namespace Microsoft.Build.Tasks { return null; } - AssemblyName found = GetAssemblyNameFromFile (hintpath); - if (found == null) { - log.LogMessage (MessageImportance.Low, "File at HintPath {0}, is either an invalid assembly or the file does not exist.", hintpath); + AssemblyName aname; + if (!TryGetAssemblyNameFromFullName (reference.ItemSpec, out aname)) return null; - } - if (AssemblyNamesCompatible (name, found, specific_version)) { - resolved = GetResolvedReference (reference, hintpath, found, true, SearchPath.HintPath); - } else { - LogSearchMessage ("Considered {0}, but assembly name '{1}' did not match the " + - "expected '{2}' (SpecificVersion={3})", hintpath, found, name, specific_version); - log.LogMessage (MessageImportance.Low, "Assembly names are not compatible."); - } - - return resolved; + return ResolveReferenceForPath (hintpath, reference, aname, + String.Format ("File at HintPath {0}, is either an invalid assembly or the file does not exist.", hintpath), + SearchPath.HintPath, specific_version); } - public AssemblyName GetAssemblyNameFromFile (string filename) + public bool TryGetAssemblyNameFromFile (string filename, out AssemblyName aname) { - AssemblyName aname = null; + aname = null; filename = Path.GetFullPath (filename); try { aname = AssemblyName.GetAssemblyName (filename); @@ -305,12 +326,24 @@ namespace Microsoft.Build.Tasks { filename); } - return aname; + return aname != null; + } + + bool TryGetAssemblyNameFromFullName (string full_name, out AssemblyName aname) + { + aname = null; + try { + aname = new AssemblyName (full_name); + } catch (FileLoadException) { + LogSearchMessage ("Considered '{0}' as an assembly name, but it is invalid.", full_name); + } + + return aname != null; } internal static bool AssemblyNamesCompatible (AssemblyName a, AssemblyName b, bool specificVersion) { - return AssemblyNamesCompatible (a, b, specificVersion, false); + return AssemblyNamesCompatible (a, b, specificVersion, true); } // if @specificVersion is true then match full name, else just the simple name @@ -336,11 +369,8 @@ namespace Microsoft.Build.Tasks { bool a_is_empty = (a_bytes == null || a_bytes.Length == 0); bool b_is_empty = (b_bytes == null || b_bytes.Length == 0); - if (a_is_empty && b_is_empty) - return true; - if (a_is_empty || b_is_empty) - return false; + return true; for (int i = 0; i < a_bytes.Length; i++) if (a_bytes [i] != b_bytes [i]) @@ -380,10 +410,10 @@ namespace Microsoft.Build.Tasks { search_log.Add (String.Format (msg, args)); } - public void LogSearchLoggerMessages () + public void LogSearchLoggerMessages (MessageImportance importance) { foreach (string msg in search_log) - log.LogMessage (msg); + log.LogMessage (importance, msg); } public TaskLoggingHelper Log {