| File: Linker\EmbeddedXmlInfo.cs | Web Access |
| Project: src\runtime\src\tools\illink\src\linker\Mono.Linker.csproj (illink) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Linq; using System.Xml; using ILLink.Shared; using Mono.Cecil; using Mono.Linker.Steps; namespace Mono.Linker { public class EmbeddedXmlInfo { static EmbeddedResource? GetEmbeddedXml(AssemblyDefinition assembly, Func<Resource, bool> predicate) { return assembly.Modules .SelectMany(mod => mod.Resources) .Where(res => res.ResourceType == ResourceType.Embedded) .Where(res => res.Name.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) .Where(res => predicate(res)) .SingleOrDefault() as EmbeddedResource; } public void ProcessDescriptors(AssemblyDefinition assembly, LinkContext context) { if (context.Annotations.GetAction(assembly) == AssemblyAction.Skip) return; var rsc = GetEmbeddedXml(assembly, res => ShouldProcessRootDescriptorResource(assembly, context, res.Name)); if (rsc == null) return; DescriptorMarker? marker = null; try { context.LogMessage($"Processing embedded trimming descriptor '{rsc.Name}' from '{assembly.Name}'."); marker = GetExternalResolveStep(context, rsc, assembly); } catch (XmlException ex) { /* This could happen if some broken XML file is embedded. */ context.LogError(null, DiagnosticId.XmlException, rsc.Name, ex.ToString()); } marker?.Mark(); } public SubstitutionInfo? ProcessSubstitutions(AssemblyDefinition assembly, LinkContext context) { if (context.Annotations.GetAction(assembly) == AssemblyAction.Skip) return null; var rsc = GetEmbeddedXml(assembly, res => res.Name.Equals("ILLink.Substitutions.xml", StringComparison.OrdinalIgnoreCase)); if (rsc == null) return null; BodySubstitutionParser? parser = null; try { context.LogMessage($"Processing embedded substitution descriptor '{rsc.Name}' from '{assembly.Name}'."); parser = GetExternalSubstitutionParser(context, rsc, assembly); } catch (XmlException ex) { context.LogError(null, DiagnosticId.XmlException, rsc.Name, ex.ToString()); } if (parser == null) return null; var substitutionInfo = new SubstitutionInfo(); parser.Parse(substitutionInfo); return substitutionInfo; } public AttributeInfo? ProcessAttributes(AssemblyDefinition assembly, LinkContext context) { if (context.Annotations.GetAction(assembly) == AssemblyAction.Skip) return null; var rsc = GetEmbeddedXml(assembly, res => res.Name.Equals("ILLink.LinkAttributes.xml", StringComparison.OrdinalIgnoreCase)); if (rsc == null) return null; LinkAttributesParser? parser = null; try { context.LogMessage($"Processing embedded '{rsc.Name}' from '{assembly.Name}'."); parser = GetExternalLinkAttributesParser(context, rsc, assembly); } catch (XmlException ex) { context.LogError(null, DiagnosticId.XmlException, rsc.Name, ex.ToString()); } if (parser == null) return null; var attributeInfo = new AttributeInfo(); parser.Parse(attributeInfo); return attributeInfo; } static string GetAssemblyName(string descriptor) { int pos = descriptor.LastIndexOf('.'); if (pos == -1) return descriptor; return descriptor.Substring(0, pos); } static bool ShouldProcessRootDescriptorResource(AssemblyDefinition assembly, LinkContext context, string resourceName) { if (resourceName.Equals("ILLink.Descriptors.xml", StringComparison.OrdinalIgnoreCase)) return true; if (GetAssemblyName(resourceName) != assembly.Name.Name) return false; switch (context.Annotations.GetAction(assembly)) { case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: case AssemblyAction.AddBypassNGenUsed: case AssemblyAction.Copy: return true; default: return false; } } protected virtual DescriptorMarker GetExternalResolveStep(LinkContext context, EmbeddedResource resource, AssemblyDefinition assembly) { return new DescriptorMarker(context, resource.GetResourceStream(), resource, assembly, "resource " + resource.Name + " in " + assembly.FullName); } protected virtual BodySubstitutionParser GetExternalSubstitutionParser(LinkContext context, EmbeddedResource resource, AssemblyDefinition assembly) { return new BodySubstitutionParser(context, resource.GetResourceStream(), resource, assembly, "resource " + resource.Name + " in " + assembly.FullName); } protected virtual LinkAttributesParser GetExternalLinkAttributesParser(LinkContext context, EmbeddedResource resource, AssemblyDefinition assembly) { return new LinkAttributesParser(context, resource.GetResourceStream(), resource, assembly, "resource " + resource.Name + " in " + assembly.FullName); } } }