diff --git a/RdXml.Test/RdXml.Test.csproj b/RdXml.Test/RdXml.Test.csproj
new file mode 100644
index 0000000..35b65d2
--- /dev/null
+++ b/RdXml.Test/RdXml.Test.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RdXml.Test/TypeTests.cs b/RdXml.Test/TypeTests.cs
new file mode 100644
index 0000000..9b2e470
--- /dev/null
+++ b/RdXml.Test/TypeTests.cs
@@ -0,0 +1,40 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml.Test
+{
+ [TestClass]
+ public class TypeTests
+ {
+ [TestMethod]
+ public void TestSubType()
+ {
+ string inputXml = @"
+
+
+
+
+
+ ";
+
+ XmlDocument xmlDocument = new XmlDocument();
+ xmlDocument.LoadXml(inputXml);
+ RdDirective directive = new RdDirective(xmlDocument);
+ Assert.IsNotNull(directive.Application);
+ Assert.AreEqual(1, directive.Application.Types.Count);
+ Assert.IsNotNull(directive.Application.Types[0].SubTypes);
+ }
+ }
+}
diff --git a/RdXml/RdAssembly.cs b/RdXml/RdAssembly.cs
new file mode 100644
index 0000000..732958c
--- /dev/null
+++ b/RdXml/RdAssembly.cs
@@ -0,0 +1,85 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Linq;
+
+namespace RdXml
+{
+ public class RdAssembly : RdNamespace
+ {
+ public new const string ELEMENT_TAG = "Assembly";
+
+ public RdAssembly(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes)
+ {
+ string assemblyName = AssemblyName;
+
+ XmlElement xmlElement = xmlDocument.CreateElement(ELEMENT_TAG);
+ xmlElement.SetAttribute(ATTRIBUTE_NAME, assemblyName);
+ xmlDocument.AppendChild(xmlElement);
+
+ if (HasReflectAttribute)
+ {
+ xmlElement.SetAttribute(ATTRIBUTE_DYNAMIC, VALUE_REQUIRED_ALL);
+ }
+ if(HasMarshalDelegateAttribute || HasMarshalStructureAttribute)
+ {
+ IEnumerable delegates = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(t => t.GetTypes())
+ .Where(t => !t.IsClass && t.Assembly.FullName == assemblyName);
+ foreach (Type type in delegates)
+ {
+ if (!writtenTypes.Add(type))
+ {
+ continue;
+ }
+ XmlElement delegateElement = xmlDocument.CreateElement(RdType.ELEMENT_TAG);
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_NAME, type.FullName);
+ if (HasMarshalDelegateAttribute)
+ {
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_DELEGATE, "Required All");
+ }
+ if (HasMarshalStructureAttribute)
+ {
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_STRUCTURE, "Required All");
+ }
+ xmlElement.AppendChild(delegateElement);
+ }
+ }
+
+ foreach (RdNamespace @namespace in Namespaces)
+ {
+ @namespace.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ foreach (RdType type in Types)
+ {
+ type.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ foreach (RdTypeInstantiation typeInstantiation in TypeInstantiations)
+ {
+ typeInstantiation.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ }
+
+ public new string AssemblyName
+ {
+ get
+ {
+ return XmlElement.GetAttribute(ATTRIBUTE_NAME);
+ }
+ }
+ }
+}
diff --git a/RdXml/RdAttributeImplies.cs b/RdXml/RdAttributeImplies.cs
new file mode 100644
index 0000000..cd0fdbe
--- /dev/null
+++ b/RdXml/RdAttributeImplies.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdAttributeImplies : RdElement
+ {
+ public const string ELEMENT_TAG = "AttributeImplies";
+
+ public RdAttributeImplies(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdDirective.cs b/RdXml/RdDirective.cs
new file mode 100644
index 0000000..0a3ac12
--- /dev/null
+++ b/RdXml/RdDirective.cs
@@ -0,0 +1,86 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdDirective : RdElement
+ {
+ public const string ELEMENT_TAG = "Directives";
+ public const string APPLICATION_TAG = "Application";
+ public const string LIBRARY_TAG = "Library";
+
+ public RdDll Application { get; private set; }
+ public List Libraries { get; } = new List();
+
+ public RdDirective(XmlDocument xmlDocument) : base(null, xmlDocument.DocumentElement)
+ {
+ XmlNodeList applicationNodeList = xmlDocument.GetElementsByTagName(APPLICATION_TAG);
+ if(applicationNodeList.Count > 0)
+ {
+ Application = new RdDll(this, (XmlElement) applicationNodeList[0]);
+ }
+
+ XmlNodeList libraryNodeList = xmlDocument.GetElementsByTagName(LIBRARY_TAG);
+ foreach(XmlNode xmlNode in libraryNodeList)
+ {
+ Libraries.Add(new RdDll(this, (XmlElement) xmlNode));
+ }
+ }
+
+ public void WriteNativeAOT(Stream outputStream)
+ {
+ XmlDocument result = new XmlDocument();
+ HashSet writtenTypes = new HashSet();
+ WriteNativeAOT(result, result.DocumentElement, writtenTypes);
+ result.Save(outputStream);
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ XmlElement rootElement = result.CreateElement(ELEMENT_TAG);
+ result.AppendChild(rootElement);
+
+ if(Application != null)
+ {
+ Application.WriteNativeAOT(result, rootElement, writtenTypes);
+ }
+ foreach(RdDll dll in Libraries)
+ {
+ dll.WriteNativeAOT(result, rootElement, writtenTypes);
+ }
+ }
+
+ public static RdDirective FromStream(Stream stream)
+ {
+ XmlDocument xmlDocument = new XmlDocument();
+ xmlDocument.Load(stream);
+ return new RdDirective(xmlDocument);
+ }
+
+ public static RdDirective FromTextReader(TextReader textReader)
+ {
+ XmlDocument xmlDocument = new XmlDocument();
+ xmlDocument.Load(textReader);
+ return new RdDirective(xmlDocument);
+ }
+
+ public static RdDirective FromXmlReader(XmlReader xmlReader)
+ {
+ XmlDocument xmlDocument = new XmlDocument();
+ xmlDocument.Load(xmlReader);
+ return new RdDirective(xmlDocument);
+ }
+ }
+}
diff --git a/RdXml/RdDll.cs b/RdXml/RdDll.cs
new file mode 100644
index 0000000..e5f8674
--- /dev/null
+++ b/RdXml/RdDll.cs
@@ -0,0 +1,71 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdDll : RdElement
+ {
+ public List Assemblies { get; } = new List();
+ public List Namespaces { get; } = new List();
+ public List Types { get; } = new List();
+ public List TypeInstantiations { get; } = new List();
+
+ public RdDll(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ XmlNodeList assemblyNodeList = xmlElement.GetElementsByTagName(RdAssembly.ELEMENT_TAG);
+ foreach(XmlNode assemblyNode in assemblyNodeList)
+ {
+ Assemblies.Add(new RdAssembly(this, (XmlElement) assemblyNode));
+ }
+ XmlNodeList namespaceList = xmlElement.GetElementsByTagName(RdNamespace.ELEMENT_TAG);
+ foreach (XmlNode namespaceNode in namespaceList)
+ {
+ Namespaces.Add(new RdNamespace(this, (XmlElement)namespaceNode));
+ }
+ XmlNodeList typeList = xmlElement.GetElementsByTagName(RdType.ELEMENT_TAG);
+ foreach (XmlNode typeNode in typeList)
+ {
+ Types.Add(new RdType(this, (XmlElement)typeNode));
+ }
+ XmlNodeList typeInstantiationList = xmlElement.GetElementsByTagName(RdTypeInstantiation.ELEMENT_TAG);
+ foreach (XmlNode typeInstantiationNode in typeInstantiationList)
+ {
+ TypeInstantiations.Add(new RdTypeInstantiation(this, (XmlElement)typeInstantiationNode));
+ }
+ }
+
+ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes)
+ {
+ XmlElement xmlElement = xmlDocument.CreateElement(XmlElement.Name);
+ parentElement.AppendChild(xmlElement);
+
+ foreach(RdAssembly assembly in Assemblies)
+ {
+ assembly.WriteNativeAOT(xmlDocument, xmlElement, writtenTypes);
+ }
+ foreach(RdNamespace @namespace in Namespaces)
+ {
+ @namespace.WriteNativeAOT(xmlDocument, xmlElement, writtenTypes);
+ }
+ foreach(RdType type in Types)
+ {
+ type.WriteNativeAOT(xmlDocument, xmlElement, writtenTypes);
+ }
+ foreach(RdTypeInstantiation typeInstantiation in TypeInstantiations)
+ {
+ typeInstantiation.WriteNativeAOT(xmlDocument, xmlElement, writtenTypes);
+ }
+ }
+ }
+}
diff --git a/RdXml/RdElement.cs b/RdXml/RdElement.cs
new file mode 100644
index 0000000..c9f6af8
--- /dev/null
+++ b/RdXml/RdElement.cs
@@ -0,0 +1,103 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public abstract class RdElement
+ {
+ public const string ATTRIBUTE_NAME = "Name";
+ public const string ATTRIBUTE_ACTIVATE = "Activate";
+ public const string ATTRIBUTE_BROWSE = "Browse";
+ public const string ATTRIBUTE_DYNAMIC = "Dynamic";
+ public const string ATTRIBUTE_SERIALIZE = "Serialize";
+ public const string ATTRIBUTE_DATA_CONTRACT_SERIALIZER = "DataContractSerializer";
+ public const string ATTRIBUTE_DATA_CONTRACT_JSON_SERIALIZER = "DataContractJsonSerializer";
+ public const string ATTRIBUTE_XML_SERIALIZER = "XmlSerializer";
+ public const string ATTRIBUTE_MARSHAL_OBJECT = "MarshalObject";
+ public const string ATTRIBUTE_MARSHAL_DELEGATE = "MarshalDelegate";
+ public const string ATTRIBUTE_MARSHAL_STRUCTURE = "MarshalStructure";
+ public const string VALUE_REQUIRED_ALL = "Required All";
+
+ protected RdElement Parent { get; }
+ protected XmlElement XmlElement { get; }
+
+ public RdElement(RdElement parent, XmlElement xmlElement)
+ {
+ Parent = parent;
+ XmlElement = xmlElement;
+ }
+
+ public abstract void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes);
+
+ public bool HasReflectAttribute
+ {
+ get
+ {
+ if(XmlElement.HasAttribute(ATTRIBUTE_ACTIVATE))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_BROWSE))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_DYNAMIC))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_SERIALIZE))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_DATA_CONTRACT_SERIALIZER))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_DATA_CONTRACT_JSON_SERIALIZER))
+ {
+ return true;
+ }
+ if (XmlElement.HasAttribute(ATTRIBUTE_XML_SERIALIZER))
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public bool HasMarshalDelegateAttribute
+ {
+ get
+ {
+ if(XmlElement.HasAttribute(ATTRIBUTE_MARSHAL_OBJECT))
+ {
+ return true;
+ }
+ return XmlElement.HasAttribute(ATTRIBUTE_MARSHAL_DELEGATE);
+ }
+ }
+
+ public bool HasMarshalStructureAttribute
+ {
+ get
+ {
+ if (XmlElement.HasAttribute(ATTRIBUTE_MARSHAL_OBJECT))
+ {
+ return true;
+ }
+ return XmlElement.HasAttribute(ATTRIBUTE_MARSHAL_STRUCTURE);
+ }
+ }
+ }
+}
diff --git a/RdXml/RdEvent.cs b/RdXml/RdEvent.cs
new file mode 100644
index 0000000..d9eb2fc
--- /dev/null
+++ b/RdXml/RdEvent.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdEvent : RdElement
+ {
+ public const string ELEMENT_TAG = "Event";
+
+ public RdEvent(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdField.cs b/RdXml/RdField.cs
new file mode 100644
index 0000000..d7c2bda
--- /dev/null
+++ b/RdXml/RdField.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdField : RdElement
+ {
+ public const string ELEMENT_TAG = "Field";
+
+ public RdField(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdGenericParameter.cs b/RdXml/RdGenericParameter.cs
new file mode 100644
index 0000000..1ce535d
--- /dev/null
+++ b/RdXml/RdGenericParameter.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdGenericParameter : RdElement
+ {
+ public const string ELEMENT_TAG = "GenericParameter";
+
+ public RdGenericParameter(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdMethod.cs b/RdXml/RdMethod.cs
new file mode 100644
index 0000000..606b643
--- /dev/null
+++ b/RdXml/RdMethod.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdMethod : RdElement
+ {
+ public const string ELEMENT_TAG = "Method";
+
+ public RdMethod(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdMethodInstantiation.cs b/RdXml/RdMethodInstantiation.cs
new file mode 100644
index 0000000..a5ffe54
--- /dev/null
+++ b/RdXml/RdMethodInstantiation.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdMethodInstantiation : RdElement
+ {
+ public const string ELEMENT_TAG = "MethodInstantiation";
+
+ public RdMethodInstantiation(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdNamespace.cs b/RdXml/RdNamespace.cs
new file mode 100644
index 0000000..7a68ce4
--- /dev/null
+++ b/RdXml/RdNamespace.cs
@@ -0,0 +1,165 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Linq;
+
+namespace RdXml
+{
+ public class RdNamespace : RdElement
+ {
+ public const string ELEMENT_TAG = "Namespace";
+
+ public List Namespaces { get; } = new List();
+ public List Types { get; } = new List();
+ public List TypeInstantiations { get; } = new List();
+
+ public RdNamespace(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ XmlNodeList namespaceList = xmlElement.GetElementsByTagName(RdNamespace.ELEMENT_TAG);
+ foreach (XmlNode namespaceNode in namespaceList)
+ {
+ Namespaces.Add(new RdNamespace(this, (XmlElement)namespaceNode));
+ }
+ XmlNodeList typeList = xmlElement.GetElementsByTagName(RdType.ELEMENT_TAG);
+ foreach (XmlNode typeNode in typeList)
+ {
+ Types.Add(new RdType(this, (XmlElement)typeNode));
+ }
+ XmlNodeList typeInstantiationList = xmlElement.GetElementsByTagName(RdTypeInstantiation.ELEMENT_TAG);
+ foreach (XmlNode typeInstantiationNode in typeInstantiationList)
+ {
+ TypeInstantiations.Add(new RdTypeInstantiation(this, (XmlElement)typeInstantiationNode));
+ }
+ }
+
+ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes)
+ {
+ string namespaceName = NamespaceName;
+ string assemblyName = AssemblyName;
+
+ foreach (RdNamespace @namespace in Namespaces)
+ {
+ @namespace.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ foreach (RdType type in Types)
+ {
+ type.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ foreach (RdTypeInstantiation typeInstantiation in TypeInstantiations)
+ {
+ typeInstantiation.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+
+ //Only write other Namespace types after explicit declarations
+ WriteNativeAOTTypes(xmlDocument, parentElement, writtenTypes, namespaceName, assemblyName);
+ WriteNativeAOTDelegates(xmlDocument, parentElement, writtenTypes, namespaceName);
+ }
+
+ private void WriteNativeAOTTypes(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes, string namespaceName, string assemblyName)
+ {
+ IEnumerable classes;
+ if (!string.IsNullOrEmpty(assemblyName))
+ {
+ classes = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(t => t.GetTypes())
+ .Where(t => t.IsClass && t.Namespace == namespaceName && t.Assembly.FullName == assemblyName);
+ }
+ else
+ {
+ classes = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(t => t.GetTypes())
+ .Where(t => t.IsClass && t.Namespace == namespaceName);
+ }
+
+ foreach (Type type in classes)
+ {
+ if (!writtenTypes.Add(type))
+ {
+ continue;
+ }
+ XmlElement typeElement = xmlDocument.CreateElement(RdType.ELEMENT_TAG);
+ typeElement.SetAttribute(RdElement.ATTRIBUTE_NAME, type.FullName);
+ if(HasReflectAttribute)
+ {
+ typeElement.SetAttribute(RdElement.ATTRIBUTE_DYNAMIC, VALUE_REQUIRED_ALL);
+ }
+ parentElement.AppendChild(typeElement);
+ }
+ }
+
+ private void WriteNativeAOTDelegates(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes, string namespaceName)
+ {
+ IEnumerable delegates = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(t => t.GetTypes())
+ .Where(t => !t.IsClass && t.Namespace == namespaceName);
+ foreach (Type type in delegates)
+ {
+ if (!writtenTypes.Add(type))
+ {
+ continue;
+ }
+ XmlElement delegateElement = xmlDocument.CreateElement(RdType.ELEMENT_TAG);
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_NAME, type.FullName);
+ if (HasMarshalDelegateAttribute)
+ {
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_DELEGATE, VALUE_REQUIRED_ALL);
+ }
+ if (HasMarshalStructureAttribute)
+ {
+ delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_STRUCTURE, VALUE_REQUIRED_ALL);
+ }
+ parentElement.AppendChild(delegateElement);
+ }
+ }
+
+ public string NamespaceName
+ {
+ get
+ {
+ StringBuilder result = new StringBuilder();
+ string thisName = XmlElement.GetAttribute(ATTRIBUTE_NAME);
+ if (Parent is RdNamespace @namespace && !(Parent is RdAssembly))
+ {
+ string parentNamespace = @namespace.NamespaceName;
+ if(!thisName.StartsWith(parentNamespace))
+ {
+ result.Append(parentNamespace);
+ if (!parentNamespace.EndsWith("."))
+ {
+ result.Append('.');
+ }
+ }
+ }
+ result.Append(thisName);
+ return result.ToString();
+ }
+ }
+
+ public string AssemblyName
+ {
+ get
+ {
+ if (Parent is RdAssembly assembly)
+ {
+ return assembly.AssemblyName;
+ }
+ if (Parent is RdNamespace @namespace)
+ {
+ return @namespace.AssemblyName;
+ }
+ return "";
+ }
+ }
+
+ }
+}
diff --git a/RdXml/RdProperty.cs b/RdXml/RdProperty.cs
new file mode 100644
index 0000000..3e6b981
--- /dev/null
+++ b/RdXml/RdProperty.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdProperty : RdElement
+ {
+ public const string ELEMENT_TAG = "Property";
+
+ public RdProperty(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdSubtypes.cs b/RdXml/RdSubtypes.cs
new file mode 100644
index 0000000..b4dc92b
--- /dev/null
+++ b/RdXml/RdSubtypes.cs
@@ -0,0 +1,30 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdSubtypes : RdElement
+ {
+ public const string ELEMENT_TAG = "Subtypes";
+
+ public RdSubtypes(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ }
+
+ public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet writtenTypes)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/RdXml/RdType.cs b/RdXml/RdType.cs
new file mode 100644
index 0000000..50abb6f
--- /dev/null
+++ b/RdXml/RdType.cs
@@ -0,0 +1,51 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdType : RdTypeInstantiation
+ {
+ public new const string ELEMENT_TAG = "Type";
+
+ public RdSubtypes SubTypes { get; private set; }
+ public RdAttributeImplies AttributeImplies { get; private set; }
+ public List GenericParameters { get; } = new List();
+
+ public RdType(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ XmlNodeList subtypeList = xmlElement.GetElementsByTagName(RdSubtypes.ELEMENT_TAG);
+ if(subtypeList.Count > 0)
+ {
+ SubTypes = new RdSubtypes(this, (XmlElement)subtypeList[0]);
+ }
+
+ XmlNodeList attributeImplesList = xmlElement.GetElementsByTagName(RdAttributeImplies.ELEMENT_TAG);
+ if (attributeImplesList.Count > 0)
+ {
+ AttributeImplies = new RdAttributeImplies(this, (XmlElement)attributeImplesList[0]);
+ }
+
+ XmlNodeList genericParametersList = xmlElement.GetElementsByTagName(RdGenericParameter.ELEMENT_TAG);
+ foreach (XmlNode genericParameterNode in genericParametersList)
+ {
+ GenericParameters.Add(new RdGenericParameter(this, (XmlElement)genericParameterNode));
+ }
+ }
+
+ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes)
+ {
+ base.WriteNativeAOT(xmlDocument, parentElement, writtenTypes);
+ }
+ }
+}
diff --git a/RdXml/RdTypeInstantiation.cs b/RdXml/RdTypeInstantiation.cs
new file mode 100644
index 0000000..502fb79
--- /dev/null
+++ b/RdXml/RdTypeInstantiation.cs
@@ -0,0 +1,122 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace RdXml
+{
+ public class RdTypeInstantiation : RdElement
+ {
+ public const string ELEMENT_TAG = "TypeInstantiation";
+
+ public List Types { get; } = new List();
+ public List TypeInstantiations { get; } = new List();
+ public List Methods { get; } = new List();
+ public List MethodInstantiations { get; } = new List();
+ public List Properties { get; } = new List();
+ public List Fields { get; } = new List();
+ public List Events { get; } = new List();
+
+ public RdTypeInstantiation(RdElement parent, XmlElement xmlElement) : base(parent, xmlElement)
+ {
+ XmlNodeList typeList = xmlElement.GetElementsByTagName(RdType.ELEMENT_TAG);
+ foreach (XmlNode typeNode in typeList)
+ {
+ Types.Add(new RdType(this, (XmlElement)typeNode));
+ }
+
+ XmlNodeList typeInstantiationList = xmlElement.GetElementsByTagName(RdTypeInstantiation.ELEMENT_TAG);
+ foreach (XmlNode typeInstantiationNode in typeInstantiationList)
+ {
+ TypeInstantiations.Add(new RdTypeInstantiation(this, (XmlElement)typeInstantiationNode));
+ }
+
+ XmlNodeList methodList = xmlElement.GetElementsByTagName(RdMethod.ELEMENT_TAG);
+ foreach (XmlNode methodNode in methodList)
+ {
+ Methods.Add(new RdMethod(this, (XmlElement)methodNode));
+ }
+
+ XmlNodeList methodInstantiationList = xmlElement.GetElementsByTagName(RdMethodInstantiation.ELEMENT_TAG);
+ foreach (XmlNode methodInstantiationNode in methodInstantiationList)
+ {
+ MethodInstantiations.Add(new RdMethodInstantiation(this, (XmlElement)methodInstantiationNode));
+ }
+
+ XmlNodeList propertyList = xmlElement.GetElementsByTagName(RdProperty.ELEMENT_TAG);
+ foreach (XmlNode propertyNode in propertyList)
+ {
+ Properties.Add(new RdProperty(this, (XmlElement)propertyNode));
+ }
+
+ XmlNodeList fieldList = xmlElement.GetElementsByTagName(RdField.ELEMENT_TAG);
+ foreach (XmlNode fieldNode in fieldList)
+ {
+ Fields.Add(new RdField(this, (XmlElement)fieldNode));
+ }
+
+ XmlNodeList eventList = xmlElement.GetElementsByTagName(RdEvent.ELEMENT_TAG);
+ foreach (XmlNode eventNode in eventList)
+ {
+ Events.Add(new RdEvent(this, (XmlElement)eventNode));
+ }
+ }
+
+ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet writtenTypes)
+ {
+ string typeName = TypeName;
+ Type resolvedType = Type.GetType(typeName);
+ if (writtenTypes.Add(resolvedType))
+ {
+ XmlElement xmlElement = xmlDocument.CreateElement(ELEMENT_TAG);
+ xmlElement.SetAttribute(ATTRIBUTE_NAME, TypeName);
+ xmlDocument.AppendChild(xmlElement);
+
+ if (HasReflectAttribute)
+ {
+ xmlElement.SetAttribute(RdElement.ATTRIBUTE_DYNAMIC, VALUE_REQUIRED_ALL);
+ }
+ if (HasMarshalDelegateAttribute)
+ {
+ xmlElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_DELEGATE, VALUE_REQUIRED_ALL);
+ }
+ if (HasMarshalStructureAttribute)
+ {
+ xmlElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_STRUCTURE, VALUE_REQUIRED_ALL);
+ }
+ }
+ }
+
+ public string TypeName
+ {
+ get
+ {
+ StringBuilder result = new StringBuilder();
+ string thisName = XmlElement.GetAttribute(ATTRIBUTE_NAME);
+ if (Parent is RdNamespace @namespace && !(Parent is RdAssembly))
+ {
+ string parentNamespace = @namespace.NamespaceName;
+ if (!thisName.StartsWith(parentNamespace))
+ {
+ result.Append(parentNamespace);
+ if (!parentNamespace.EndsWith("."))
+ {
+ result.Append('.');
+ }
+ }
+ }
+ result.Append(thisName);
+ return result.ToString();
+ }
+ }
+ }
+}
diff --git a/RdXml/RdXml.csproj b/RdXml/RdXml.csproj
new file mode 100644
index 0000000..040842f
--- /dev/null
+++ b/RdXml/RdXml.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard20
+
+
+
diff --git a/RdXmlConverter.Core/CliOptions.cs b/RdXmlConverter.Core/CliOptions.cs
new file mode 100644
index 0000000..a3ab4b6
--- /dev/null
+++ b/RdXmlConverter.Core/CliOptions.cs
@@ -0,0 +1,26 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using CommandLine;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RdXmlConverter
+{
+ class CliOptions
+ {
+ [Option("rdxml", Required = true, HelpText = "Input UWP rd.xml file")]
+ public string InputRdXml { get; set; }
+ [Option('o', "output", Required = true, HelpText = "Output NativeAOT rd.xml file")]
+ public string OutputRdXml { get; set; }
+ [Option('i', "input", Required = true, HelpText = "Input directory containing DLLs")]
+ public string InputDllDirectory { get; set; }
+ }
+}
diff --git a/RdXmlConverter.Core/Program.cs b/RdXmlConverter.Core/Program.cs
new file mode 100644
index 0000000..495f9e0
--- /dev/null
+++ b/RdXmlConverter.Core/Program.cs
@@ -0,0 +1,55 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using CommandLine;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+
+namespace RdXmlConverter
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Parser.Default.ParseArguments(args)
+ .WithParsed(options =>
+ {
+ if(!Directory.Exists(options.InputDllDirectory))
+ {
+ Console.Error.WriteLine(options.InputDllDirectory + " is not a directory");
+ return;
+ }
+
+ Run(options);
+ });
+ }
+
+ static void Run(CliOptions options)
+ {
+ string [] dlls = Directory.GetFiles(options.InputDllDirectory, "*.dll");
+ if(dlls.Length == 0)
+ {
+ Console.Error.WriteLine("No DLLs in specified directory");
+ return;
+ }
+ foreach(string dllFilename in dlls)
+ {
+ Assembly.LoadFrom(dllFilename);
+ }
+
+ XmlDocument doc = new XmlDocument();
+ doc.PreserveWhitespace = true;
+ doc.Load(options.InputRdXml);
+
+
+ }
+ }
+}
diff --git a/RdXmlConverter.Core/RdXmlConverter.Core.csproj b/RdXmlConverter.Core/RdXmlConverter.Core.csproj
new file mode 100644
index 0000000..41e7dad
--- /dev/null
+++ b/RdXmlConverter.Core/RdXmlConverter.Core.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RdXmlConverter.Framework/App.config b/RdXmlConverter.Framework/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/RdXmlConverter.Framework/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RdXmlConverter.Framework/CliOptions.cs b/RdXmlConverter.Framework/CliOptions.cs
new file mode 100644
index 0000000..a9527bc
--- /dev/null
+++ b/RdXmlConverter.Framework/CliOptions.cs
@@ -0,0 +1,28 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using CommandLine;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RdXmlConverter.Framework
+{
+ class CliOptions
+ {
+ [Option("rdxml", Required = true, HelpText = "Input UWP rd.xml file")]
+ public string InputRdXml { get; set; }
+ [Option('o', "output", Required = true, HelpText = "Output NativeAOT rd.xml file")]
+ public string OutputRdXml { get; set; }
+ [Option('i', "input", Required = true, HelpText = "Input directory containing DLLs")]
+ public string InputDllDirectory { get; set; }
+ }
+}
diff --git a/RdXmlConverter.Framework/Program.cs b/RdXmlConverter.Framework/Program.cs
new file mode 100644
index 0000000..cfed55f
--- /dev/null
+++ b/RdXmlConverter.Framework/Program.cs
@@ -0,0 +1,24 @@
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * Copyright 2022 Thomas Cashman
+ *
+ * See LICENSE file
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RdXmlConverter.Framework
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ }
+ }
+}
diff --git a/RdXmlConverter.Framework/Properties/AssemblyInfo.cs b/RdXmlConverter.Framework/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0b47a1d
--- /dev/null
+++ b/RdXmlConverter.Framework/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RdXmlConverter.Framework")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RdXmlConverter.Framework")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b4722dd2-7267-4c70-826c-1daba067797a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/RdXmlConverter.Framework/RdXmlConverter.Framework.csproj b/RdXmlConverter.Framework/RdXmlConverter.Framework.csproj
new file mode 100644
index 0000000..88e7e2e
--- /dev/null
+++ b/RdXmlConverter.Framework/RdXmlConverter.Framework.csproj
@@ -0,0 +1,64 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B4722DD2-7267-4C70-826C-1DABA067797A}
+ Exe
+ RdXmlConverter.Framework
+ RdXmlConverter.Framework
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\CommandLineParser.2.8.0\lib\net461\CommandLine.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {dc9c03bd-4ee5-470e-a3a5-9f3b5185f47d}
+ RdXml
+
+
+
+
\ No newline at end of file
diff --git a/RdXmlConverter.Framework/packages.config b/RdXmlConverter.Framework/packages.config
new file mode 100644
index 0000000..3eb2507
--- /dev/null
+++ b/RdXmlConverter.Framework/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/RdXmlConverter.sln b/RdXmlConverter.sln
new file mode 100644
index 0000000..c0b108f
--- /dev/null
+++ b/RdXmlConverter.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RdXml", "RdXml\RdXml.csproj", "{DC9C03BD-4EE5-470E-A3A5-9F3B5185F47D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RdXmlConverter.Core", "RdXmlConverter.Core\RdXmlConverter.Core.csproj", "{3E798DE6-CFDB-4E98-89D1-CD148E6673CB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RdXmlConverter.Framework", "RdXmlConverter.Framework\RdXmlConverter.Framework.csproj", "{B4722DD2-7267-4C70-826C-1DABA067797A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RdXml.Test", "RdXml.Test\RdXml.Test.csproj", "{75C11015-6C03-4CAD-B343-6A7A5148D686}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DC9C03BD-4EE5-470E-A3A5-9F3B5185F47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DC9C03BD-4EE5-470E-A3A5-9F3B5185F47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DC9C03BD-4EE5-470E-A3A5-9F3B5185F47D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DC9C03BD-4EE5-470E-A3A5-9F3B5185F47D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3E798DE6-CFDB-4E98-89D1-CD148E6673CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3E798DE6-CFDB-4E98-89D1-CD148E6673CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3E798DE6-CFDB-4E98-89D1-CD148E6673CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3E798DE6-CFDB-4E98-89D1-CD148E6673CB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4722DD2-7267-4C70-826C-1DABA067797A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4722DD2-7267-4C70-826C-1DABA067797A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4722DD2-7267-4C70-826C-1DABA067797A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4722DD2-7267-4C70-826C-1DABA067797A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75C11015-6C03-4CAD-B343-6A7A5148D686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75C11015-6C03-4CAD-B343-6A7A5148D686}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75C11015-6C03-4CAD-B343-6A7A5148D686}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75C11015-6C03-4CAD-B343-6A7A5148D686}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F94CFE0E-08C4-4ACB-B922-020BA757204C}
+ EndGlobalSection
+EndGlobal