mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-07 12:02:59 +00:00
DynamicMethod Nullable Events
This commit is contained in:
parent
20fcaba518
commit
2809d389bd
27
Esiur/Data/NullableAttribute.cs
Normal file
27
Esiur/Data/NullableAttribute.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace System.Runtime.CompilerServices
|
||||||
|
{
|
||||||
|
[AttributeUsage(
|
||||||
|
AttributeTargets.Class |
|
||||||
|
AttributeTargets.Event |
|
||||||
|
AttributeTargets.Field |
|
||||||
|
AttributeTargets.GenericParameter |
|
||||||
|
AttributeTargets.Parameter |
|
||||||
|
AttributeTargets.Property |
|
||||||
|
AttributeTargets.ReturnValue,
|
||||||
|
AllowMultiple = false,
|
||||||
|
Inherited = false)]
|
||||||
|
public sealed class NullableAttribute : Attribute
|
||||||
|
{
|
||||||
|
public readonly byte[] Flags;
|
||||||
|
public readonly byte Flag;
|
||||||
|
|
||||||
|
public NullableAttribute(byte flag)
|
||||||
|
{
|
||||||
|
Flag = flag;// new byte[] { flag };
|
||||||
|
}
|
||||||
|
public NullableAttribute(byte[] flags)
|
||||||
|
{
|
||||||
|
Flags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Esiur/Data/NullableContextAttribute.cs
Normal file
19
Esiur/Data/NullableContextAttribute.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
namespace System.Runtime.CompilerServices
|
||||||
|
{
|
||||||
|
[System.AttributeUsage(
|
||||||
|
AttributeTargets.Class |
|
||||||
|
AttributeTargets.Delegate |
|
||||||
|
AttributeTargets.Interface |
|
||||||
|
AttributeTargets.Method |
|
||||||
|
AttributeTargets.Struct,
|
||||||
|
AllowMultiple = false,
|
||||||
|
Inherited = false)]
|
||||||
|
public sealed class NullableContextAttribute : Attribute
|
||||||
|
{
|
||||||
|
public readonly byte Flag;
|
||||||
|
public NullableContextAttribute(byte flag)
|
||||||
|
{
|
||||||
|
Flag = flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -89,14 +89,20 @@ namespace Esiur.Data
|
|||||||
|
|
||||||
public RepresentationType?[] SubTypes = new RepresentationType[3];
|
public RepresentationType?[] SubTypes = new RepresentationType[3];
|
||||||
|
|
||||||
public static RepresentationType? FromType(Type type)
|
public static RepresentationType? FromType(Type type, bool forceNullable = false)
|
||||||
{
|
{
|
||||||
var nullType = System.Nullable.GetUnderlyingType(type);
|
|
||||||
var nullable = false;
|
|
||||||
|
|
||||||
if (nullType != null) {
|
var nullable = forceNullable;
|
||||||
type = nullType;
|
|
||||||
nullable = true;
|
if (!forceNullable)
|
||||||
|
{
|
||||||
|
var nullType = System.Nullable.GetUnderlyingType(type);
|
||||||
|
|
||||||
|
if (nullType != null)
|
||||||
|
{
|
||||||
|
type = nullType;
|
||||||
|
nullable = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.IsGenericType)
|
if (type.IsGenericType)
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
||||||
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
||||||
|
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
|
||||||
<PackageReference Include="System.Text.Json" Version="6.0.1" GeneratePathProperty="true" />
|
<PackageReference Include="System.Text.Json" Version="6.0.1" GeneratePathProperty="true" />
|
||||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ using Esiur.Proxy;
|
|||||||
using Esiur.Core;
|
using Esiur.Core;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
|
||||||
namespace Esiur.Resource;
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
@ -607,6 +608,27 @@ public class Instance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void EmitResourceEventByIndex(byte eventIndex, object value)
|
||||||
|
{
|
||||||
|
IResource res;
|
||||||
|
if (this.resource.TryGetTarget(out res))
|
||||||
|
{
|
||||||
|
var eventTemplate = template.GetEventTemplateByIndex(eventIndex);
|
||||||
|
EventOccurred?.Invoke(new EventOccurredInfo(res, eventTemplate, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void EmitCustomResourceEventByIndex(object issuer, Func<Session, bool> receivers, byte eventIndex, object value)
|
||||||
|
{
|
||||||
|
IResource res;
|
||||||
|
if (this.resource.TryGetTarget(out res))
|
||||||
|
{
|
||||||
|
var eventTemplate = template.GetEventTemplateByIndex(eventIndex);
|
||||||
|
CustomEventOccurred?.Invoke(new CustomEventOccurredInfo(res, eventTemplate, receivers, issuer, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the value of a given property by name.
|
/// Get the value of a given property by name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -844,6 +866,13 @@ public class Instance
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public AutoList<IPermissionsManager, Instance> Managers => managers;
|
public AutoList<IPermissionsManager, Instance> Managers => managers;
|
||||||
|
|
||||||
|
|
||||||
|
public void CallMeTest(Instance ins, int? val) =>
|
||||||
|
ins.EmitResourceEventByIndex(201, val);
|
||||||
|
|
||||||
|
public void CallMeTest2(Instance instance, object issuer, Func<Session, bool> receivers, int? val) =>
|
||||||
|
instance.EmitCustomResourceEventByIndex(issuer, receivers, 201, val);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create new instance.
|
/// Create new instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -893,10 +922,11 @@ public class Instance
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
var emitEventByIndexMethod = GetType().GetMethod("EmitResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
var emitCustomEventByIndexMethod = GetType().GetMethod("EmitCustomResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
foreach (var evt in template.Events)
|
foreach (var evt in template.Events)
|
||||||
{
|
{
|
||||||
//if (evt.EventHandlerType != typeof(ResourceEventHandler))
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
if (evt.EventInfo == null)
|
if (evt.EventInfo == null)
|
||||||
continue;
|
continue;
|
||||||
@ -906,21 +936,51 @@ public class Instance
|
|||||||
if (eventGenericType == typeof(ResourceEventHandler<>))
|
if (eventGenericType == typeof(ResourceEventHandler<>))
|
||||||
{
|
{
|
||||||
|
|
||||||
// var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
var dm = new DynamicMethod("_", null,
|
||||||
// if (ca.Length == 0)
|
new Type[] {typeof(Instance), evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },
|
||||||
// continue;
|
typeof(Instance).Module, true);
|
||||||
|
|
||||||
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt, args);
|
|
||||||
|
var il = dm.GetILGenerator();
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (int)evt.Index);
|
||||||
|
il.Emit(OpCodes.Ldarg_1);
|
||||||
|
il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]);
|
||||||
|
il.Emit(OpCodes.Callvirt, emitEventByIndexMethod);
|
||||||
|
il.Emit(OpCodes.Nop);
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
|
||||||
|
var proxyDelegate= dm.CreateDelegate(evt.EventInfo.EventHandlerType, this);
|
||||||
|
|
||||||
|
//ResourceEventHandler<object> proxyDelegate = new ResourceEventHandler<object>((args) => EmitResourceEvent(evt, args));
|
||||||
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (eventGenericType == typeof(CustomResourceEventHandler<>))
|
else if (eventGenericType == typeof(CustomResourceEventHandler<>))
|
||||||
{
|
{
|
||||||
//var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
var dm = new DynamicMethod("_", null,
|
||||||
//if (ca.Length == 0)
|
new Type[] { typeof(Instance), typeof(object), typeof(Func<Session, bool>),
|
||||||
// continue;
|
evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },
|
||||||
|
typeof(Instance).Module, true);
|
||||||
|
|
||||||
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
|
|
||||||
|
var il = dm.GetILGenerator();
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Ldarg_1);
|
||||||
|
il.Emit(OpCodes.Ldarg_2);
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (int)evt.Index);
|
||||||
|
il.Emit(OpCodes.Ldarg_3);
|
||||||
|
il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]);
|
||||||
|
il.Emit(OpCodes.Callvirt, emitCustomEventByIndexMethod);
|
||||||
|
il.Emit(OpCodes.Nop);
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
|
||||||
|
var proxyDelegate = dm.CreateDelegate(evt.EventInfo.EventHandlerType, this);
|
||||||
|
|
||||||
|
//CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
|
||||||
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Esiur.Resource;
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
public delegate R DCovariant<out R>();
|
//public delegate R DCovariant<out R>();
|
||||||
|
|
||||||
public delegate void ResourceEventHandler<in T>(T argument);
|
public delegate void ResourceEventHandler<in T>(T argument);//where T : class;
|
||||||
// public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args);
|
// public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args);
|
||||||
//public delegate void CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args);
|
//public delegate void CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args);
|
||||||
//public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args);
|
//public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args);
|
||||||
|
@ -9,6 +9,7 @@ using Esiur.Core;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using Esiur.Proxy;
|
using Esiur.Proxy;
|
||||||
using Esiur.Net.IIP;
|
using Esiur.Net.IIP;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Esiur.Resource.Template;
|
namespace Esiur.Resource.Template;
|
||||||
|
|
||||||
@ -393,9 +394,150 @@ public class TypeTemplate
|
|||||||
|
|
||||||
bool classIsPublic = type.IsEnum || (type.GetCustomAttribute<PublicAttribute>() != null);
|
bool classIsPublic = type.IsEnum || (type.GetCustomAttribute<PublicAttribute>() != null);
|
||||||
|
|
||||||
|
var addConstant = (FieldInfo ci, PublicAttribute publicAttr) => {
|
||||||
|
|
||||||
|
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var nullableAttr = ci.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
|
||||||
|
var valueType = RepresentationType.FromType(ci.FieldType);//, nullable != null && nullable.NullableFlags[0] == 2);
|
||||||
|
|
||||||
|
if (valueType == null)
|
||||||
|
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
||||||
|
|
||||||
|
var value = ci.GetValue(null);
|
||||||
|
|
||||||
|
if (templateType == TemplateType.Enum)
|
||||||
|
value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType());
|
||||||
|
|
||||||
|
var ct = new ConstantTemplate(this, (byte)constants.Count, publicAttr?.Name ?? ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
||||||
|
|
||||||
|
constants.Add(ct);
|
||||||
|
};
|
||||||
|
|
||||||
|
var addProperty = (PropertyInfo pi, PublicAttribute publicAttr) =>
|
||||||
|
{
|
||||||
|
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||||
|
var nullableAttr = pi.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
|
||||||
|
var attrType = RepresentationType.FromType(pi.PropertyType, nullableAttr != null && nullableAttr.Flag == 2);
|
||||||
|
|
||||||
|
if (attrType == null)
|
||||||
|
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
|
||||||
|
|
||||||
|
var pt = new PropertyTemplate(this, (byte)properties.Count, publicAttr?.Name ?? pi.Name, pi.DeclaringType != type, attrType);
|
||||||
|
|
||||||
|
if (storageAttr != null)
|
||||||
|
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
||||||
|
|
||||||
|
if (annotationAttr != null)
|
||||||
|
pt.ReadExpansion = annotationAttr.Annotation;
|
||||||
|
else
|
||||||
|
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
|
||||||
|
|
||||||
|
pt.PropertyInfo = pi;
|
||||||
|
|
||||||
|
properties.Add(pt);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var addEvent = (EventInfo ei, PublicAttribute publicAttr) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
var nullableAttr = ei.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
|
||||||
|
var argIsNull = nullableAttr != null &&
|
||||||
|
nullableAttr.Flags != null &&
|
||||||
|
nullableAttr.Flags.Length > 1 &&
|
||||||
|
nullableAttr.Flags[1] == 2;
|
||||||
|
|
||||||
|
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
||||||
|
var evtType = RepresentationType.FromType(argType, argIsNull);
|
||||||
|
|
||||||
|
if (evtType == null)
|
||||||
|
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
|
||||||
|
|
||||||
|
var et = new EventTemplate(this, (byte)events.Count, publicAttr?.Name ?? ei.Name, ei.DeclaringType != type, evtType);
|
||||||
|
et.EventInfo = ei;
|
||||||
|
|
||||||
|
if (annotationAttr != null)
|
||||||
|
et.Expansion = annotationAttr.Annotation;
|
||||||
|
|
||||||
|
if (listenableAttr != null)
|
||||||
|
et.Listenable = true;
|
||||||
|
|
||||||
|
events.Add(et);
|
||||||
|
};
|
||||||
|
|
||||||
|
var addAttribute = (PropertyInfo pi, AttributeAttribute attributeAttr)=>
|
||||||
|
{
|
||||||
|
var an = attributeAttr.Name ?? pi.Name;
|
||||||
|
var at = new AttributeTemplate(this, 0, an, pi.DeclaringType != type);
|
||||||
|
at.PropertyInfo = pi;
|
||||||
|
attributes.Add(at);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var addFunction = (MethodInfo mi, PublicAttribute publicAttr) =>
|
||||||
|
{
|
||||||
|
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var nullableAttr = mi.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
var nullableContextAttr = mi.GetCustomAttribute<NullableContextAttribute>(true);
|
||||||
|
|
||||||
|
var contextIsNull = nullableContextAttr != null && nullableContextAttr.Flag == 2;
|
||||||
|
|
||||||
|
var returnType = RepresentationType.FromType(mi.ReturnType,
|
||||||
|
nullableAttr != null ? nullableAttr.Flag == 2 : contextIsNull);
|
||||||
|
|
||||||
|
if (returnType == null)
|
||||||
|
throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return");
|
||||||
|
|
||||||
|
var args = mi.GetParameters();
|
||||||
|
|
||||||
|
if (args.Length > 0)
|
||||||
|
{
|
||||||
|
if (args.Last().ParameterType == typeof(DistributedConnection))
|
||||||
|
args = args.Take(args.Count() - 1).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
var arguments = args.Select(x =>
|
||||||
|
{
|
||||||
|
var xNullableAttr = x.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
var xNullableContextAttr = x.GetCustomAttribute<NullableContextAttribute>(true);
|
||||||
|
|
||||||
|
var argType = RepresentationType.FromType(x.ParameterType,
|
||||||
|
xNullableAttr != null ? xNullableAttr.Flag == 2 : contextIsNull);
|
||||||
|
|
||||||
|
if (argType == null)
|
||||||
|
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
|
||||||
|
|
||||||
|
return new ArgumentTemplate()
|
||||||
|
{
|
||||||
|
Name = x.Name,
|
||||||
|
Type = argType,
|
||||||
|
ParameterInfo = x,
|
||||||
|
Optional = x.IsOptional
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var fn = publicAttr.Name ?? mi.Name;
|
||||||
|
|
||||||
|
var ft = new FunctionTemplate(this, (byte)functions.Count, fn, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
|
||||||
|
|
||||||
|
if (annotationAttr != null)
|
||||||
|
ft.Expansion = annotationAttr.Annotation;
|
||||||
|
else
|
||||||
|
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
||||||
|
|
||||||
|
ft.MethodInfo = mi;
|
||||||
|
functions.Add(ft);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
byte i = 0;
|
|
||||||
|
|
||||||
if (classIsPublic)
|
if (classIsPublic)
|
||||||
{
|
{
|
||||||
@ -403,30 +545,15 @@ public class TypeTemplate
|
|||||||
foreach (var ci in constantsInfo)
|
foreach (var ci in constantsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = ci.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = ci.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
|
|
||||||
if (privateAttr != null)
|
if (privateAttr != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
||||||
|
|
||||||
var valueType = RepresentationType.FromType(ci.FieldType);
|
addConstant(ci, publicAttr);
|
||||||
|
|
||||||
if (valueType == null)
|
|
||||||
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
|
||||||
|
|
||||||
var value = ci.GetValue(null);
|
|
||||||
|
|
||||||
if (templateType == TemplateType.Enum)
|
|
||||||
value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType());
|
|
||||||
|
|
||||||
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
|
||||||
|
|
||||||
|
|
||||||
constants.Add(ct);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
foreach (var pi in propsInfo)
|
foreach (var pi in propsInfo)
|
||||||
{
|
{
|
||||||
@ -434,117 +561,41 @@ public class TypeTemplate
|
|||||||
|
|
||||||
if (privateAttr == null)
|
if (privateAttr == null)
|
||||||
{
|
{
|
||||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
var publicAttr = pi.GetCustomAttribute<PublicAttribute>(true);
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
addProperty(pi, publicAttr);
|
||||||
|
|
||||||
var attrType = RepresentationType.FromType(pi.PropertyType);
|
|
||||||
|
|
||||||
if (attrType == null)
|
|
||||||
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
|
|
||||||
|
|
||||||
var pt = new PropertyTemplate(this, i++, pi.Name, pi.DeclaringType != type, attrType);
|
|
||||||
|
|
||||||
if (storageAttr != null)
|
|
||||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
pt.ReadExpansion = annotationAttr.Annotation;
|
|
||||||
else
|
|
||||||
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
|
|
||||||
|
|
||||||
pt.PropertyInfo = pi;
|
|
||||||
//pt.Serilize = publicAttr.Serialize;
|
|
||||||
properties.Add(pt);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
||||||
if (attributeAttr != null)
|
if (attributeAttr != null)
|
||||||
{
|
{
|
||||||
var an = attributeAttr.Name ?? pi.Name;
|
addAttribute(pi, attributeAttr);
|
||||||
var at = new AttributeTemplate(this, 0, an, pi.DeclaringType != type);
|
|
||||||
at.PropertyInfo = pi;
|
|
||||||
attributes.Add(at);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateType == TemplateType.Resource)
|
if (templateType == TemplateType.Resource)
|
||||||
{
|
{
|
||||||
i = 0;
|
|
||||||
foreach (var ei in eventsInfo)
|
foreach (var ei in eventsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
if (privateAttr != null)
|
if (privateAttr != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
|
||||||
|
|
||||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
addEvent(ei, publicAttr);
|
||||||
var evtType = RepresentationType.FromType(argType);
|
|
||||||
|
|
||||||
if (evtType == null)
|
|
||||||
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
|
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, ei.Name, ei.DeclaringType != type, evtType);
|
|
||||||
et.EventInfo = ei;
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
et.Expansion = annotationAttr.Annotation;
|
|
||||||
|
|
||||||
if (listenableAttr != null)
|
|
||||||
et.Listenable = true;
|
|
||||||
|
|
||||||
events.Add(et);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
if (privateAttr != null)
|
if (privateAttr != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||||
|
addFunction(mi, publicAttr);
|
||||||
var returnType = RepresentationType.FromType(mi.ReturnType);
|
|
||||||
|
|
||||||
if (returnType == null)
|
|
||||||
throw new Exception($"Unsupported type {mi.ReturnType} in method {type.Name}.{mi.Name} return");
|
|
||||||
|
|
||||||
var args = mi.GetParameters();
|
|
||||||
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
if (args.Last().ParameterType == typeof(DistributedConnection))
|
|
||||||
args = args.Take(args.Count() - 1).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
var arguments = args.Select(x =>
|
|
||||||
{
|
|
||||||
var argType = RepresentationType.FromType(x.ParameterType);
|
|
||||||
if (argType == null)
|
|
||||||
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
|
|
||||||
|
|
||||||
return new ArgumentTemplate()
|
|
||||||
{
|
|
||||||
Name = x.Name,
|
|
||||||
Type = argType,
|
|
||||||
ParameterInfo = x,
|
|
||||||
Optional = x.IsOptional
|
|
||||||
};
|
|
||||||
}).ToArray();
|
|
||||||
|
|
||||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
ft.Expansion = annotationAttr.Annotation;
|
|
||||||
else
|
|
||||||
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
|
||||||
|
|
||||||
ft.MethodInfo = mi;
|
|
||||||
functions.Add(ft);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -554,27 +605,13 @@ public class TypeTemplate
|
|||||||
foreach (var ci in constantsInfo)
|
foreach (var ci in constantsInfo)
|
||||||
{
|
{
|
||||||
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
||||||
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
|
|
||||||
if (publicAttr == null)
|
if (publicAttr == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
addConstant(ci, publicAttr);
|
||||||
var valueType = RepresentationType.FromType(ci.FieldType);
|
|
||||||
|
|
||||||
if (valueType == null)
|
|
||||||
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
|
||||||
|
|
||||||
var value = ci.GetValue(null);
|
|
||||||
|
|
||||||
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
|
||||||
|
|
||||||
|
|
||||||
constants.Add(ct);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
foreach (var pi in propsInfo)
|
foreach (var pi in propsInfo)
|
||||||
{
|
{
|
||||||
@ -582,45 +619,20 @@ public class TypeTemplate
|
|||||||
|
|
||||||
if (publicAttr != null)
|
if (publicAttr != null)
|
||||||
{
|
{
|
||||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
addProperty(pi, publicAttr);
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
|
||||||
var valueType = RepresentationType.FromType(pi.PropertyType);
|
|
||||||
|
|
||||||
if (valueType == null)
|
|
||||||
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
|
|
||||||
|
|
||||||
|
|
||||||
var pn = publicAttr.Name ?? pi.Name;
|
|
||||||
|
|
||||||
var pt = new PropertyTemplate(this, i++, pn, pi.DeclaringType != type, valueType);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
|
||||||
if (storageAttr != null)
|
|
||||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
pt.ReadExpansion = annotationAttr.Annotation;
|
|
||||||
else
|
|
||||||
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
|
|
||||||
|
|
||||||
pt.PropertyInfo = pi;
|
|
||||||
//pt.Serilize = publicAttr.Serialize;
|
|
||||||
properties.Add(pt);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
||||||
if (attributeAttr != null)
|
if (attributeAttr != null)
|
||||||
{
|
{
|
||||||
var pn = attributeAttr.Name ?? pi.Name;
|
addAttribute(pi, attributeAttr);
|
||||||
var at = new AttributeTemplate(this, 0, pn, pi.DeclaringType != type);
|
|
||||||
at.PropertyInfo = pi;
|
|
||||||
attributes.Add(at);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateType == TemplateType.Resource)
|
if (templateType == TemplateType.Resource)
|
||||||
{
|
{
|
||||||
i = 0;
|
|
||||||
|
|
||||||
foreach (var ei in eventsInfo)
|
foreach (var ei in eventsInfo)
|
||||||
{
|
{
|
||||||
@ -629,97 +641,32 @@ public class TypeTemplate
|
|||||||
if (publicAttr == null)
|
if (publicAttr == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
addEvent(ei, publicAttr);
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
|
||||||
|
|
||||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
|
||||||
|
|
||||||
var en = publicAttr.Name ?? ei.Name;
|
|
||||||
|
|
||||||
var evtType = RepresentationType.FromType(argType);
|
|
||||||
|
|
||||||
if (evtType == null)
|
|
||||||
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
|
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, en, ei.DeclaringType != type, evtType);
|
|
||||||
et.EventInfo = ei;
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
et.Expansion = annotationAttr.Annotation;
|
|
||||||
|
|
||||||
if (listenableAttr != null)
|
|
||||||
et.Listenable = true;
|
|
||||||
|
|
||||||
events.Add(et);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
{
|
{
|
||||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||||
if (publicAttr == null)
|
if (publicAttr == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
addFunction(mi, publicAttr);
|
||||||
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
var returnType = RepresentationType.FromType(mi.ReturnType);
|
|
||||||
|
|
||||||
if (returnType == null)
|
|
||||||
throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return");
|
|
||||||
|
|
||||||
var args = mi.GetParameters();
|
|
||||||
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
if (args.Last().ParameterType == typeof(DistributedConnection))
|
|
||||||
args = args.Take(args.Count() - 1).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
var arguments = args.Select(x =>
|
|
||||||
{
|
|
||||||
var argType = RepresentationType.FromType(x.ParameterType);
|
|
||||||
if (argType == null)
|
|
||||||
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
|
|
||||||
|
|
||||||
return new ArgumentTemplate()
|
|
||||||
{
|
|
||||||
Name = x.Name,
|
|
||||||
Type = argType,
|
|
||||||
ParameterInfo = x,
|
|
||||||
Optional = x.IsOptional
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
var fn = publicAttr.Name ?? mi.Name;
|
|
||||||
|
|
||||||
var ft = new FunctionTemplate(this, i++, fn, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
|
||||||
ft.Expansion = annotationAttr.Annotation;
|
|
||||||
else
|
|
||||||
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
|
||||||
|
|
||||||
ft.MethodInfo = mi;
|
|
||||||
functions.Add(ft);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// append signals
|
// append signals
|
||||||
for (i = 0; i < events.Count; i++)
|
for (var i = 0; i < events.Count; i++)
|
||||||
members.Add(events[i]);
|
members.Add(events[i]);
|
||||||
// append slots
|
// append slots
|
||||||
for (i = 0; i < functions.Count; i++)
|
for (var i = 0; i < functions.Count; i++)
|
||||||
members.Add(functions[i]);
|
members.Add(functions[i]);
|
||||||
// append properties
|
// append properties
|
||||||
for (i = 0; i < properties.Count; i++)
|
for (var i = 0; i < properties.Count; i++)
|
||||||
members.Add(properties[i]);
|
members.Add(properties[i]);
|
||||||
|
|
||||||
// append constants
|
// append constants
|
||||||
for (i = 0; i < constants.Count; i++)
|
for (var i = 0; i < constants.Count; i++)
|
||||||
members.Add(constants[i]);
|
members.Add(constants[i]);
|
||||||
|
|
||||||
// bake it binarily
|
// bake it binarily
|
||||||
@ -729,7 +676,6 @@ public class TypeTemplate
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (HasParent(type))
|
if (HasParent(type))
|
||||||
{
|
{
|
||||||
// find the first parent type that implements IResource
|
// find the first parent type that implements IResource
|
||||||
|
Loading…
x
Reference in New Issue
Block a user