[linker] Mark declaring types of nested types resolved from xml descriptors. Fixes...
[mono.git] / mcs / tools / linker / Mono.Linker.Steps / ResolveFromXmlStep.cs
index a0fe3934cac49a2b6e37f020a10d14b5033355bb..aa4f6afc760388c38a5f1267ab4f2aa69f9ce473 100644 (file)
@@ -38,6 +38,13 @@ using Mono.Cecil;
 
 namespace Mono.Linker.Steps {
 
+       public class XmlResolutionException : Exception {
+               public XmlResolutionException (string message, Exception innerException)
+                       : base (message, innerException)
+               {
+               }
+       }
+
        public class ResolveFromXmlStep : ResolveStep {
 
                static readonly string _signature = "signature";
@@ -47,10 +54,12 @@ namespace Mono.Linker.Steps {
                static readonly string _ns = string.Empty;
 
                XPathDocument _document;
+               string _xmlDocumentLocation;
 
-               public ResolveFromXmlStep (XPathDocument document)
+               public ResolveFromXmlStep (XPathDocument document, string xmlDocumentLocation = "<unspecified>")
                {
                        _document = document;
+                       _xmlDocumentLocation = xmlDocumentLocation;
                }
 
                protected override void Process ()
@@ -63,7 +72,11 @@ namespace Mono.Linker.Steps {
                        if (nav.LocalName != "linker")
                                return;
 
-                       ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
+                       try {
+                               ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
+                       } catch (Exception ex) {
+                               throw new XmlResolutionException (string.Format ("Failed to process XML description: {0}", _xmlDocumentLocation), ex);
+                       }
                }
 
                void ProcessAssemblies (LinkContext context, XPathNodeIterator iterator)
@@ -129,15 +142,24 @@ namespace Mono.Linker.Steps {
                        return new Regex (pattern.Replace(".", @"\.").Replace("*", "(.*)"));
                }
 
+               void MatchType (TypeDefinition type, Regex regex, XPathNavigator nav)
+               {
+                       if (regex.Match (type.FullName).Success)
+                               ProcessType (type, nav);
+
+                       if (!type.HasNestedTypes)
+                               return;
+
+                       foreach (var nt in type.NestedTypes)
+                               MatchType (nt, regex, nav);
+               }
+
                void ProcessTypePattern (string fullname, AssemblyDefinition assembly, XPathNavigator nav)
                {
                        Regex regex = CreateRegexFromPattern (fullname);
 
                        foreach (TypeDefinition type in assembly.MainModule.Types) {
-                               if (!regex.Match (type.FullName).Success)
-                                       continue;
-
-                               ProcessType (type, nav);
+                               MatchType (type, regex, nav);
                        }
                }
 
@@ -152,6 +174,14 @@ namespace Mono.Linker.Steps {
 
                        Annotations.Mark (type);
 
+                       if (type.IsNested) {
+                               var parent = type;
+                               while (parent.IsNested) {
+                                       parent = parent.DeclaringType;
+                                       Annotations.Mark (parent);
+                               }
+                       }
+
                        switch (preserve) {
                        case TypePreserve.Nothing:
                                if (!nav.HasChildren)