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 ResolveI18nAssembly(MetadataResolver resolver, string name, Dictionary <string, ITaskItem> assemblies)
        {
            var assembly = resolver.Resolve(name);

            assemblies [name] = CreateAssemblyTaskItem(assembly);
        }
        void Execute(MetadataResolver resolver)
        {
            foreach (var dir in ReferenceAssembliesDirectory.Split(new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries))
            {
                resolver.AddSearchDirectory(dir);
            }

            var assemblies            = new Dictionary <string, ITaskItem> (Assemblies.Length);
            var topAssemblyReferences = new List <string> (Assemblies.Length);
            var logger = new NuGetLogger((s) => {
                LogDebugMessage("{0}", s);
            });

            LockFile lockFile = null;

            if (!string.IsNullOrEmpty(ProjectAssetFile) && File.Exists(ProjectAssetFile))
            {
                lockFile = LockFileUtilities.GetLockFile(ProjectAssetFile, logger);
            }

            try {
                foreach (var assembly in Assemblies)
                {
                    // Add each user assembly and all referenced assemblies (recursive)
                    string resolved_assembly = resolver.Resolve(assembly.ItemSpec);
                    if (MonoAndroidHelper.IsReferenceAssembly(resolved_assembly))
                    {
                        // Resolve "runtime" library
                        if (lockFile != null)
                        {
                            resolved_assembly = ResolveRuntimeAssemblyForReferenceAssembly(lockFile, assembly.ItemSpec);
                        }
                        if (lockFile == null || resolved_assembly == null)
                        {
                            var file = resolved_assembly ?? assembly.ItemSpec;
                            LogCodedWarning("XA0107", file, 0, "Ignoring Reference Assembly `{0}`.", file);
                            continue;
                        }
                    }
                    LogDebugMessage($"Adding {resolved_assembly} to topAssemblyReferences");
                    topAssemblyReferences.Add(resolved_assembly);
                    resolver.AddSearchDirectory(Path.GetDirectoryName(resolved_assembly));
                    var taskItem = new TaskItem(assembly)
                    {
                        ItemSpec = Path.GetFullPath(resolved_assembly),
                    };
                    if (string.IsNullOrEmpty(taskItem.GetMetadata("ReferenceAssembly")))
                    {
                        taskItem.SetMetadata("ReferenceAssembly", taskItem.ItemSpec);
                    }
                    string assemblyName = Path.GetFileNameWithoutExtension(resolved_assembly);
                    assemblies [assemblyName] = taskItem;
                }
            } catch (Exception ex) {
                LogError("Exception while loading assemblies: {0}", ex);
                return;
            }
            try {
                foreach (var assembly in topAssemblyReferences)
                {
                    AddAssemblyReferences(resolver, assemblies, assembly, null);
                }
            } catch (Exception ex) {
                LogError("Exception while loading assemblies: {0}", ex);
                return;
            }

            // Add I18N assemblies if needed
            AddI18nAssemblies(resolver, assemblies);

            var mainapiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion(TargetFrameworkVersion);

            foreach (var item in api_levels.Where(x => mainapiLevel < x.Value))
            {
                var itemOSVersion = MonoAndroidHelper.SupportedVersions.GetFrameworkVersionFromApiLevel(item.Value);
                LogCodedWarning("XA0105", ProjectFile, 0,
                                "The $(TargetFrameworkVersion) for {0} ({1}) is greater than the $(TargetFrameworkVersion) for your project ({2}). " +
                                "You need to increase the $(TargetFrameworkVersion) for your project.", Path.GetFileName(item.Key), itemOSVersion, TargetFrameworkVersion);
            }

            var resolvedAssemblies          = new List <ITaskItem> (assemblies.Count);
            var resolvedSymbols             = new List <ITaskItem> (assemblies.Count);
            var resolvedFrameworkAssemblies = new List <ITaskItem> (assemblies.Count);
            var resolvedUserAssemblies      = new List <ITaskItem> (assemblies.Count);

            foreach (var assembly in assemblies.Values)
            {
                var mdb = assembly + ".mdb";
                var pdb = Path.ChangeExtension(assembly.ItemSpec, "pdb");
                if (File.Exists(mdb))
                {
                    resolvedSymbols.Add(new TaskItem(mdb));
                }
                if (File.Exists(pdb) && Files.IsPortablePdb(pdb))
                {
                    resolvedSymbols.Add(new TaskItem(pdb));
                }
                resolvedAssemblies.Add(assembly);
                if (MonoAndroidHelper.IsFrameworkAssembly(assembly.ItemSpec, checkSdkPath: true))
                {
                    resolvedFrameworkAssemblies.Add(assembly);
                }
                else
                {
                    resolvedUserAssemblies.Add(assembly);
                }
            }
            ResolvedAssemblies             = resolvedAssemblies.ToArray();
            ResolvedSymbols                = resolvedSymbols.ToArray();
            ResolvedFrameworkAssemblies    = resolvedFrameworkAssemblies.ToArray();
            ResolvedUserAssemblies         = resolvedUserAssemblies.ToArray();
            ResolvedDoNotPackageAttributes = do_not_package_atts.ToArray();
        }
Exemplo n.º 4
0
        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);
        }