public ResolvedReference FindInTargetFramework (ITaskItem reference, string framework_dir, bool specific_version)
{
- AssemblyName key_aname = new AssemblyName (reference.ItemSpec);
+ if (!Directory.Exists (framework_dir))
+ return null;
+
+ 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
KeyValuePair<AssemblyName, string> 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);
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;
{
TargetFrameworkAssemblies gac_asm = new TargetFrameworkAssemblies (directory);
foreach (string file in Directory.GetFiles (directory, "*.dll")) {
- AssemblyName aname = GetAssemblyNameFromFile (file);
- gac_asm.NameToAssemblyNameCache [aname.Name] =
- new KeyValuePair<AssemblyName, string> (aname, file);
+ AssemblyName aname;
+ if (TryGetAssemblyNameFromFile (file, out aname))
+ gac_asm.NameToAssemblyNameCache [aname.Name] =
+ new KeyValuePair<AssemblyName, string> (aname, file);
}
return gac_asm;
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);
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);
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");
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);
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
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])
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 {