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";
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 ()
{
XPathNavigator nav = _document.CreateNavigator ();
nav.MoveToFirstChild ();
- ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
+
+ // This step can be created with XML files that aren't necessarily
+ // linker descriptor files. So bail if we don't have a <linker> element.
+ if (nav.LocalName != "linker")
+ return;
+
+ 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)
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);
}
}