Skip to content

Commit

Permalink
Release 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tomcashman committed Jan 16, 2022
1 parent 55100bd commit 42613e7
Show file tree
Hide file tree
Showing 20 changed files with 502 additions and 38 deletions.
20 changes: 20 additions & 0 deletions RdXml.Test/Sample/TestAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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;

namespace RdXml.Test.Sample
{
[System.AttributeUsage(System.AttributeTargets.Class)]
public class TestAttribute : System.Attribute
{
}
}
20 changes: 20 additions & 0 deletions RdXml.Test/Sample/TestClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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;

namespace RdXml.Test.Sample
{
[TestAttribute]
public class TestClass
{
}
}
111 changes: 109 additions & 2 deletions RdXml.Test/TypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
* See LICENSE file
*/
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RdXml.Test.Sample;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

Expand All @@ -18,12 +20,22 @@ namespace RdXml.Test
[TestClass]
public class TypeTests
{
private XmlWriterSettings xmlWriterSettings;

[TestInitialize]
public void TestInit()
{
xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.OmitXmlDeclaration = true;
}

[TestMethod]
public void TestSubType()
public void TestSubTypes()
{
string inputXml = @"<Directives xmlns=""http://schemas.microsoft.com/netfx/2013/01/metadata\"">
<Application>
<Type Name=""Dictionary"">
<Type Name=""RdXml.RdElement"">
<Subtypes Activate=""Public"" Dynamic=""Public""/>
</Type>
</Application>
Expand All @@ -35,6 +47,101 @@ public void TestSubType()
Assert.IsNotNull(directive.Application);
Assert.AreEqual(1, directive.Application.Types.Count);
Assert.IsNotNull(directive.Application.Types[0].SubTypes);

StringWriter result = new StringWriter();
directive.WriteNativeAOT(XmlWriter.Create(result, xmlWriterSettings));

string expectedXml = @"<Directives>
<Application>
<Type Name=""RdXml.RdElement"" />
<Type Name=""RdXml.RdAssembly"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdAttributeImplies"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdDirective"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdDll"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdEvent"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdField"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdGenericParameter"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdMethod"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdMethodInstantiation"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdNamespace"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdProperty"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdSubtypes"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdType"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdTypeInstantiation"" Dynamic=""Required All"" />
</Application>
</Directives>";
Assert.AreEqual(expectedXml, result.ToString());
}

[TestMethod]
public void TestNamespace()
{
string inputXml = @"<Directives xmlns=""http://schemas.microsoft.com/netfx/2013/01/metadata\"">
<Application>
<Namespace Name=""RdXml"" Dynamic=""Public"" />
</Application>
</Directives>";

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(inputXml);
RdDirective directive = new RdDirective(xmlDocument);
Assert.IsNotNull(directive.Application);
Assert.AreEqual(1, directive.Application.Namespaces.Count);

StringWriter result = new StringWriter();
directive.WriteNativeAOT(XmlWriter.Create(result, xmlWriterSettings));

string expectedXml = @"<Directives>
<Application>
<Type Name=""RdXml.RdAssembly"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdAttributeImplies"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdDirective"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdDll"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdElement"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdEvent"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdField"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdGenericParameter"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdMethod"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdMethodInstantiation"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdNamespace"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdProperty"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdSubtypes"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdType"" Dynamic=""Required All"" />
<Type Name=""RdXml.RdTypeInstantiation"" Dynamic=""Required All"" />
</Application>
</Directives>";
Assert.AreEqual(expectedXml, result.ToString());
}

[TestMethod]
public void TestAttributeImplies()
{
Type type = typeof(TestAttribute);

string inputXml = @"<Directives xmlns=""http://schemas.microsoft.com/netfx/2013/01/metadata\"">
<Application>
<Type Name=""RdXml.Test.Sample.TestAttribute"">
<AttributeImplies Dynamic=""Public""/>
</Type>
</Application>
</Directives>";

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(inputXml);
RdDirective directive = new RdDirective(xmlDocument);
Assert.IsNotNull(directive.Application);
Assert.AreEqual(1, directive.Application.Types.Count);

StringWriter result = new StringWriter();
directive.WriteNativeAOT(XmlWriter.Create(result, xmlWriterSettings));

string expectedXml = @"<Directives>
<Application>
<Type Name=""RdXml.Test.Sample.TestAttribute"" />
<Type Name=""RdXml.Test.Sample.TestClass"" Dynamic=""Required All"" />
</Application>
</Directives>";
Assert.AreEqual(expectedXml, result.ToString());
}
}
}
20 changes: 14 additions & 6 deletions RdXml/RdAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,25 @@ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentEl
{
xmlElement.SetAttribute(ATTRIBUTE_DYNAMIC, VALUE_REQUIRED_ALL);
}
if(HasMarshalDelegateAttribute || HasMarshalStructureAttribute)
if (HasMarshalStructureAttribute)
{
xmlElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_STRUCTURE, "Required All");
}
if (HasMarshalDelegateAttribute || HasMarshalStructureAttribute)
{
IEnumerable<Type> delegates = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => !t.IsClass && t.Assembly.FullName == assemblyName);
.Where(t => typeof(Delegate).IsAssignableFrom(t) && t.Assembly.FullName == assemblyName);
foreach (Type type in delegates)
{
if (type.IsGenericParameter)
{
continue;
}
if (IsCompilerGenerated(type))
{
continue;
}
if (!writtenTypes.Add(type))
{
continue;
Expand All @@ -52,10 +64,6 @@ public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentEl
{
delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_DELEGATE, "Required All");
}
if (HasMarshalStructureAttribute)
{
delegateElement.SetAttribute(RdElement.ATTRIBUTE_MARSHAL_STRUCTURE, "Required All");
}
xmlElement.AppendChild(delegateElement);
}
}
Expand Down
20 changes: 18 additions & 2 deletions RdXml/RdAttributeImplies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Linq;

namespace RdXml
{
Expand All @@ -22,9 +23,24 @@ public RdAttributeImplies(RdElement parent, XmlElement xmlElement) : base(parent
{
}

public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes)
public override void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet<Type> writtenTypes)
{
throw new NotImplementedException();
RdType parentTypeElement = (RdType)Parent;
string typeName = parentTypeElement.TypeName;
Type resolvedType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.FullName == typeName).First();

IEnumerable<Type> typesWithAttribute = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.GetCustomAttributes(resolvedType, true).Length > 0);
foreach (Type type in typesWithAttribute)
{
AppendType(xmlDocument, parentElement, writtenTypes, type,
HasReflectAttribute,
HasMarshalDelegateAttribute,
HasMarshalStructureAttribute);
}
}
}
}
16 changes: 16 additions & 0 deletions RdXml/RdDirective.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ public void WriteNativeAOT(Stream outputStream)
result.Save(outputStream);
}

public void WriteNativeAOT(TextWriter textWriter)
{
XmlDocument result = new XmlDocument();
HashSet<Type> writtenTypes = new HashSet<Type>();
WriteNativeAOT(result, result.DocumentElement, writtenTypes);
result.Save(textWriter);
}

public void WriteNativeAOT(XmlWriter xmlWriter)
{
XmlDocument result = new XmlDocument();
HashSet<Type> writtenTypes = new HashSet<Type>();
WriteNativeAOT(result, result.DocumentElement, writtenTypes);
result.Save(xmlWriter);
}

public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes)
{
XmlElement rootElement = result.CreateElement(ELEMENT_TAG);
Expand Down
41 changes: 40 additions & 1 deletion RdXml/RdElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;

Expand Down Expand Up @@ -38,7 +39,45 @@ public RdElement(RdElement parent, XmlElement xmlElement)
XmlElement = xmlElement;
}

public abstract void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes);
public abstract void WriteNativeAOT(XmlDocument xmlDocument, XmlElement parentElement, HashSet<Type> writtenTypes);

protected void AppendType(XmlDocument xmlDocument, XmlElement parentElement, HashSet<Type> writtenTypes,
Type type, bool dynamic, bool marshalDelegate, bool marshalStructure)
{
if(type.IsGenericParameter)
{
return;
}
if(IsCompilerGenerated(type))
{
return;
}
if(!writtenTypes.Add(type))
{
return;
}
XmlElement xmlElement = xmlDocument.CreateElement(RdType.ELEMENT_TAG);
xmlElement.SetAttribute(ATTRIBUTE_NAME, type.FullName);
parentElement.AppendChild(xmlElement);

if(dynamic)
{
xmlElement.SetAttribute(ATTRIBUTE_DYNAMIC, VALUE_REQUIRED_ALL);
}
if(marshalDelegate)
{
xmlElement.SetAttribute(ATTRIBUTE_MARSHAL_DELEGATE, VALUE_REQUIRED_ALL);
}
if(marshalStructure)
{
xmlElement.SetAttribute(ATTRIBUTE_MARSHAL_STRUCTURE, VALUE_REQUIRED_ALL);
}
}

protected bool IsCompilerGenerated(Type type)
{
return Attribute.GetCustomAttribute(type, typeof(CompilerGeneratedAttribute)) != null;
}

public bool HasReflectAttribute
{
Expand Down
2 changes: 1 addition & 1 deletion RdXml/RdEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public RdEvent(RdElement parent, XmlElement xmlElement) : base(parent, xmlElemen

public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes)
{
throw new NotImplementedException();
//TODO: How to handle this?
}
}
}
16 changes: 15 additions & 1 deletion RdXml/RdField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Linq;

namespace RdXml
{
Expand All @@ -24,7 +26,19 @@ public RdField(RdElement parent, XmlElement xmlElement) : base(parent, xmlElemen

public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes)
{
throw new NotImplementedException();
RdType parentTypeElement = (RdType)Parent;
string typeName = parentTypeElement.TypeName;
Type parentType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.FullName == typeName).First();
AppendType(result, parentElement, writtenTypes, parentType, true, false, false);

FieldInfo fieldInfo = parentType.GetField(XmlElement.GetAttribute(ATTRIBUTE_NAME));
if (fieldInfo == null)
{
return;
}
AppendType(result, parentElement, writtenTypes, fieldInfo.FieldType, true, false, false);
}
}
}
2 changes: 1 addition & 1 deletion RdXml/RdGenericParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public RdGenericParameter(RdElement parent, XmlElement xmlElement) : base(parent

public override void WriteNativeAOT(XmlDocument result, XmlElement parentElement, HashSet<Type> writtenTypes)
{
throw new NotImplementedException();
//TODO: How to resolve this? Scan everything?
}
}
}
Loading

0 comments on commit 42613e7

Please sign in to comment.