void AddAssemblyReferences(MetadataResolver resolver, Dictionary <string, ITaskItem> assemblies, string assemblyPath, List <string> resolutionPath) { var reader = resolver.GetAssemblyReader(assemblyPath); var assembly = reader.GetAssemblyDefinition(); var assemblyName = reader.GetString(assembly.Name); // Don't repeat assemblies we've already done bool topLevel = resolutionPath == null; if (!topLevel && assemblies.ContainsKey(assemblyName)) { return; } if (resolutionPath == null) { resolutionPath = new List <string>(); } CheckAssemblyAttributes(assembly, assemblyName, reader, out string targetFrameworkIdentifier); LogMessage("{0}Adding assembly reference for {1}, recursively...", new string (' ', indent), assemblyName); resolutionPath.Add(assemblyName); indent += 2; // Add this assembly ITaskItem assemblyItem = null; if (topLevel) { if (assemblies.TryGetValue(assemblyName, out assemblyItem)) { if (!string.IsNullOrEmpty(targetFrameworkIdentifier) && string.IsNullOrEmpty(assemblyItem.GetMetadata("TargetFrameworkIdentifier"))) { assemblyItem.SetMetadata("TargetFrameworkIdentifier", targetFrameworkIdentifier); } } } else { assemblies [assemblyName] = assemblyItem = CreateAssemblyTaskItem(assemblyPath, targetFrameworkIdentifier); } // Recurse into each referenced assembly foreach (var handle in reader.AssemblyReferences) { var reference = reader.GetAssemblyReference(handle); string reference_assembly; try { var referenceName = reader.GetString(reference.Name); if (assemblyItem != null && referenceName == "Mono.Android") { assemblyItem.SetMetadata("HasMonoAndroidReference", "True"); } reference_assembly = resolver.Resolve(referenceName); } catch (FileNotFoundException ex) { var references = new StringBuilder(); for (int i = 0; i < resolutionPath.Count; i++) { if (i != 0) { references.Append(" > "); } references.Append('`'); references.Append(resolutionPath [i]); references.Append('`'); } string missingAssembly = ex.FileName; if (missingAssembly.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { missingAssembly = Path.GetFileNameWithoutExtension(missingAssembly); } if (MonoAndroidHelper.IsFrameworkAssembly(ex.FileName)) { LogCodedError("XA2002", Properties.Resources.XA2002_Framework, missingAssembly, references); } else { LogCodedError("XA2002", Properties.Resources.XA2002_NuGet, missingAssembly, references, resolutionPath [0]); } return; } AddAssemblyReferences(resolver, assemblies, reference_assembly, resolutionPath); } indent -= 2; resolutionPath.RemoveAt(resolutionPath.Count - 1); }
void AddAssemblyReferences(MetadataResolver resolver, Dictionary <string, ITaskItem> assemblies, string assemblyPath, List <string> resolutionPath) { var reader = resolver.GetAssemblyReader(assemblyPath); var assembly = reader.GetAssemblyDefinition(); var assemblyName = reader.GetString(assembly.Name); // Don't repeat assemblies we've already done bool topLevel = resolutionPath == null; if (!topLevel && assemblies.ContainsKey(assemblyName)) { return; } if (resolutionPath == null) { resolutionPath = new List <string>(); } CheckAssemblyAttributes(assembly, reader, out string targetFrameworkIdentifier); LogMessage("{0}Adding assembly reference for {1}, recursively...", new string (' ', indent), assemblyName); resolutionPath.Add(assemblyName); indent += 2; // Add this assembly if (topLevel) { if (!string.IsNullOrEmpty(targetFrameworkIdentifier) && assemblies.TryGetValue(assemblyName, out ITaskItem taskItem)) { if (string.IsNullOrEmpty(taskItem.GetMetadata("TargetFrameworkIdentifier"))) { taskItem.SetMetadata("TargetFrameworkIdentifier", targetFrameworkIdentifier); } } } else { assemblies [assemblyName] = CreateAssemblyTaskItem(assemblyPath, targetFrameworkIdentifier); } // Recurse into each referenced assembly foreach (var handle in reader.AssemblyReferences) { var reference = reader.GetAssemblyReference(handle); string reference_assembly; try { reference_assembly = resolver.Resolve(reader.GetString(reference.Name)); } catch (FileNotFoundException ex) { var references = new StringBuilder(); for (int i = 0; i < resolutionPath.Count; i++) { if (i != 0) { references.Append(" > "); } references.Append('`'); references.Append(resolutionPath [i]); references.Append('`'); } string missingAssembly = ex.FileName; if (missingAssembly.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { missingAssembly = Path.GetFileNameWithoutExtension(missingAssembly); } string message = $"Can not resolve reference: `{missingAssembly}`, referenced by {references}."; if (MonoAndroidHelper.IsFrameworkAssembly(ex.FileName)) { LogCodedError("XA2002", $"{message} Perhaps it doesn't exist in the Mono for Android profile?"); } else { LogCodedError("XA2002", $"{message} Please add a NuGet package or assembly reference for `{missingAssembly}`, or remove the reference to `{resolutionPath [0]}`."); } return; } AddAssemblyReferences(resolver, assemblies, reference_assembly, resolutionPath); } indent -= 2; resolutionPath.RemoveAt(resolutionPath.Count - 1); }