Added documentation to Attribute builder. Added Inheritance methods. Added a base DNA attribute to GenerateTypeDeclarations method.
This commit is contained in:
@@ -3,23 +3,49 @@ using System.CodeDom;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace CodeGenerator {
|
namespace CodeGenerator {
|
||||||
|
// ReSharper disable always BitwiseOperatorOnEnumWithoutFlags
|
||||||
public class AttributeBuilder {
|
public class AttributeBuilder {
|
||||||
|
|
||||||
private CodeTypeDeclaration _attrDecl = new();
|
private CodeTypeDeclaration _attrDecl = new();
|
||||||
|
|
||||||
private List<(Type, string)> _fields = new();
|
private List<(Type, string)> _fields = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of fields registered for the attribute currently being built.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Each tuple contains the type of the field and the name of the field</remarks>
|
||||||
|
public List<(Type, string)> Fields => _fields;
|
||||||
|
|
||||||
private List<(Type, string, string)> _properties = new();
|
private List<(Type, string, string)> _properties = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of properties registered for the attribute currently being built.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Each tuple contains the type of the property, the name of the property and the name of the backing field</remarks>
|
||||||
|
public List<(Type, string, string)> Properties => _properties;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="AttributeBuilder"/> class.
|
||||||
|
/// </summary>
|
||||||
public AttributeBuilder() {
|
public AttributeBuilder() {
|
||||||
_attrDecl.IsClass = true;
|
_attrDecl.IsClass = true;
|
||||||
_attrDecl.Attributes = MemberAttributes.Public;
|
_attrDecl.Attributes = MemberAttributes.Public;
|
||||||
_attrDecl.BaseTypes.Add(typeof(Attribute));
|
_attrDecl.BaseTypes.Add(typeof(Attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="AttributeBuilder"/> class with the specified name for the Attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name the built attribute will have.</param>
|
||||||
|
/// <remarks>The set name can be always overridden by using <see cref="SetName"/> method.</remarks>
|
||||||
public AttributeBuilder(string name) : this() {
|
public AttributeBuilder(string name) : this() {
|
||||||
_attrDecl.Name = name;
|
_attrDecl.Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current state of the builder and prepares it for a new attribute declaration.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>clears the internal metadata for fields and properties, also reinstantiates the <see cref="CodeTypeDeclaration"/> internal instance</remarks>
|
||||||
public AttributeBuilder New() {
|
public AttributeBuilder New() {
|
||||||
_attrDecl = new CodeTypeDeclaration();
|
_attrDecl = new CodeTypeDeclaration();
|
||||||
_fields.Clear();
|
_fields.Clear();
|
||||||
@@ -27,11 +53,37 @@ namespace CodeGenerator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the base type of the attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseType">Fully qualified name from which this is going to be derived</param>
|
||||||
|
public AttributeBuilder DeriveFromClass(string baseType) {
|
||||||
|
_attrDecl.BaseTypes[0] = new(baseType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds another base type to the <see cref="CodeTypeDeclaration"/>. To be used only with interfaces.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interfaceName">Fully qualfied name of the type to add to the BaseTypes list.</param>
|
||||||
|
public AttributeBuilder Implements(string interfaceName) {
|
||||||
|
_attrDecl.BaseTypes.Add(interfaceName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the name of the attribute that will be generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name the attribute will have.</param>
|
||||||
public AttributeBuilder SetName(string name) {
|
public AttributeBuilder SetName(string name) {
|
||||||
_attrDecl.Name = name;
|
_attrDecl.Name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the <see cref="AttributeUsageAttribute"/> for the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="usageArgs">List of arguments for <see cref="AttributeUsageAttribute"/></param>
|
||||||
public AttributeBuilder SetAttributeUsage(CodeAttributeArgument usageArgs) {
|
public AttributeBuilder SetAttributeUsage(CodeAttributeArgument usageArgs) {
|
||||||
var attrUsage = new CodeAttributeDeclaration() {
|
var attrUsage = new CodeAttributeDeclaration() {
|
||||||
Name = nameof(AttributeUsageAttribute),
|
Name = nameof(AttributeUsageAttribute),
|
||||||
@@ -41,15 +93,32 @@ namespace CodeGenerator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable always BitwiseOperatorOnEnumWithoutFlags
|
/// <summary>
|
||||||
|
/// Adds a field to the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of the field to be added.</param>
|
||||||
|
/// <param name="attributes">Visibility parameters, OR'd sequence of <see cref="MemberAttributes"/></param>
|
||||||
|
/// <typeparam name="T">type of the attribute</typeparam>
|
||||||
public AttributeBuilder AddField<T>(string name,
|
public AttributeBuilder AddField<T>(string name,
|
||||||
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) =>
|
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) =>
|
||||||
AddField(typeof(T), name, attributes);
|
AddField(typeof(T), name, attributes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a field to the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type of the attribute. Must be a base type or a fully qualified name</param>
|
||||||
|
/// <param name="name">Name of the field to be added.</param>
|
||||||
|
/// <param name="attributes">Visibility parameters, OR'd sequence of <see cref="MemberAttributes"/></param>
|
||||||
public AttributeBuilder AddField(string type, string name,
|
public AttributeBuilder AddField(string type, string name,
|
||||||
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) =>
|
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) =>
|
||||||
AddField(Type.GetType(type), name, attributes);
|
AddField(Type.GetType(type), name, attributes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a field to the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type of the attribute. Must be a base type or a fully qualified name</param>
|
||||||
|
/// <param name="name">Name of the field to be added.</param>
|
||||||
|
/// <param name="attributes">Visibility parameters, OR'd sequence of <see cref="MemberAttributes"/></param>
|
||||||
public AttributeBuilder AddField(Type type, string name,
|
public AttributeBuilder AddField(Type type, string name,
|
||||||
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) {
|
MemberAttributes attributes = MemberAttributes.Private | MemberAttributes.Final) {
|
||||||
var field = new CodeMemberField(type, name);
|
var field = new CodeMemberField(type, name);
|
||||||
@@ -59,11 +128,29 @@ namespace CodeGenerator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an auto-property to the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type of the attribute. Must be a base type or a fully qualified name</param>
|
||||||
|
/// <param name="name">Name of the property to be added.</param>
|
||||||
|
/// <param name="attributes">Visibility parameters, OR'd sequence of <see cref="MemberAttributes"/></param>
|
||||||
|
/// <param name="get">Whether the property should have a getter</param>
|
||||||
|
/// <param name="set">Whether the property should have a setter</param>
|
||||||
|
/// <remarks>This method is a composite call to <see cref="AddField{T}"/> and <see cref="AddProperty"/></remarks>
|
||||||
public AttributeBuilder AddAutoProperty(Type type, string name, MemberAttributes attributes = MemberAttributes.Public, bool get = true, bool set = true) {
|
public AttributeBuilder AddAutoProperty(Type type, string name, MemberAttributes attributes = MemberAttributes.Public, bool get = true, bool set = true) {
|
||||||
AddField(type, $"_{name}", MemberAttributes.Private);
|
AddField(type, $"_{name}", MemberAttributes.Private);
|
||||||
return AddProperty(type, name, $"_{name}", attributes, get, set);
|
return AddProperty(type, name, $"_{name}", attributes, get, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a property to the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type of the attribute. Must be a base type or a fully qualified name</param>
|
||||||
|
/// <param name="name">Name of the property to be added.</param>
|
||||||
|
/// <param name="backingPropertyName">Name of the backing field for the property</param>
|
||||||
|
/// <param name="attributes">Visibility parameters, OR'd sequence of <see cref="MemberAttributes"/></param>
|
||||||
|
/// <param name="get">Whether the property should have a getter</param>
|
||||||
|
/// <param name="set">Whether the property should have a setter</param>
|
||||||
public AttributeBuilder AddProperty(Type type, string name, string backingPropertyName,
|
public AttributeBuilder AddProperty(Type type, string name, string backingPropertyName,
|
||||||
MemberAttributes attributes = MemberAttributes.Public, bool get = true, bool set = true) {
|
MemberAttributes attributes = MemberAttributes.Public, bool get = true, bool set = true) {
|
||||||
var prop = new CodeMemberProperty {
|
var prop = new CodeMemberProperty {
|
||||||
@@ -94,6 +181,9 @@ namespace CodeGenerator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a constructor to all the properties inside the attribute being generated.
|
||||||
|
/// </summary>
|
||||||
public AttributeBuilder AddPropertiesConstructor() {
|
public AttributeBuilder AddPropertiesConstructor() {
|
||||||
var ctor = new CodeConstructor { Attributes = MemberAttributes.Public };
|
var ctor = new CodeConstructor { Attributes = MemberAttributes.Public };
|
||||||
_attrDecl.Members.Add(ctor);
|
_attrDecl.Members.Add(ctor);
|
||||||
@@ -107,6 +197,10 @@ namespace CodeGenerator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds the <see cref="CodeTypeDeclaration"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Instance of the <see cref="CodeTypeDeclaration"/> built by the builder.</returns>
|
||||||
public CodeTypeDeclaration Build() => _attrDecl;
|
public CodeTypeDeclaration Build() => _attrDecl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ namespace CodeGenerator {
|
|||||||
private const string OutPath = @"GeneratedOutput";
|
private const string OutPath = @"GeneratedOutput";
|
||||||
private const string Namespace = "BlendFile";
|
private const string Namespace = "BlendFile";
|
||||||
private static HashSet<string> _customTypes;
|
private static HashSet<string> _customTypes;
|
||||||
|
|
||||||
private static readonly string[] ListLenghtStr = {"count", "length", "size"};
|
private static readonly string[] ListLenghtStr = {"count", "length", "size"};
|
||||||
|
|
||||||
private static void Log(string message) {
|
private static void Log(string message) {
|
||||||
@@ -142,12 +143,18 @@ namespace CodeGenerator {
|
|||||||
var attributeBuilder = new AttributeBuilder();
|
var attributeBuilder = new AttributeBuilder();
|
||||||
|
|
||||||
var typeDeclarations = new CodeTypeDeclaration[] {
|
var typeDeclarations = new CodeTypeDeclaration[] {
|
||||||
|
attributeBuilder.New().SetName("DNAAttribute")
|
||||||
|
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.All")))
|
||||||
|
.AddAutoProperty(typeof(int), "OriginalIndex")
|
||||||
|
.AddAutoProperty(typeof(string), "OriginalName")
|
||||||
|
.AddPropertiesConstructor()
|
||||||
|
.Build(),
|
||||||
attributeBuilder.New().SetName("DNAFieldAttribute")
|
attributeBuilder.New().SetName("DNAFieldAttribute")
|
||||||
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Field")))
|
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Field")))
|
||||||
.AddAutoProperty(typeof(int), "Size")
|
.AddAutoProperty(typeof(int), "Size")
|
||||||
.AddAutoProperty(typeof(string), "OriginalType")
|
.AddAutoProperty(typeof(string), "OriginalType")
|
||||||
.AddAutoProperty(typeof(string), "OriginalName")
|
|
||||||
.AddAutoProperty(typeof(int), "OriginalIndex")
|
.AddAutoProperty(typeof(int), "OriginalIndex")
|
||||||
|
.AddAutoProperty(typeof(string), "OriginalName")
|
||||||
.AddAutoProperty(typeof(string), "UnderlyingType")
|
.AddAutoProperty(typeof(string), "UnderlyingType")
|
||||||
.AddAutoProperty(typeof(bool), "IsPointer")
|
.AddAutoProperty(typeof(bool), "IsPointer")
|
||||||
.AddAutoProperty(typeof(int), "MemoryOffset")
|
.AddAutoProperty(typeof(int), "MemoryOffset")
|
||||||
@@ -155,9 +162,21 @@ namespace CodeGenerator {
|
|||||||
.Build(),
|
.Build(),
|
||||||
attributeBuilder.New().SetName("DNAClassAttribute")
|
attributeBuilder.New().SetName("DNAClassAttribute")
|
||||||
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Class | AttributeTargets.Struct")))
|
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Class | AttributeTargets.Struct")))
|
||||||
|
.AddAutoProperty(typeof(int), "Size")
|
||||||
.AddAutoProperty(typeof(int), "OriginalIndex")
|
.AddAutoProperty(typeof(int), "OriginalIndex")
|
||||||
.AddAutoProperty(typeof(string), "OriginalName")
|
.AddAutoProperty(typeof(string), "OriginalName")
|
||||||
|
.AddPropertiesConstructor()
|
||||||
|
.Build(),
|
||||||
|
attributeBuilder.New().SetName("DNAListAttribute")
|
||||||
|
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Property | AttributeTargets.Field")))
|
||||||
.AddAutoProperty(typeof(int), "Size")
|
.AddAutoProperty(typeof(int), "Size")
|
||||||
|
.AddAutoProperty(typeof(string), "OriginalType")
|
||||||
|
.AddAutoProperty(typeof(string), "OriginalName")
|
||||||
|
.AddAutoProperty(typeof(int), "OriginalIndex")
|
||||||
|
.AddAutoProperty(typeof(string), "UnderlyingType")
|
||||||
|
.AddAutoProperty(typeof(string), "CountFieldName")
|
||||||
|
.AddAutoProperty(typeof(int), "CountFieldIndex")
|
||||||
|
.AddAutoProperty(typeof(int), "MemoryOffset")
|
||||||
.AddPropertiesConstructor()
|
.AddPropertiesConstructor()
|
||||||
.Build()
|
.Build()
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user