mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 11:32: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 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) {
|
||||
type = nullType;
|
||||
nullable = true;
|
||||
var nullable = forceNullable;
|
||||
|
||||
if (!forceNullable)
|
||||
{
|
||||
var nullType = System.Nullable.GetUnderlyingType(type);
|
||||
|
||||
if (nullType != null)
|
||||
{
|
||||
type = nullType;
|
||||
nullable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsGenericType)
|
||||
|
@ -72,6 +72,7 @@
|
||||
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
||||
<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.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||
|
||||
|
@ -15,6 +15,7 @@ using Esiur.Proxy;
|
||||
using Esiur.Core;
|
||||
using System.Text.Json;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
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>
|
||||
/// Get the value of a given property by name.
|
||||
/// </summary>
|
||||
@ -844,6 +866,13 @@ public class Instance
|
||||
/// </summary>
|
||||
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>
|
||||
/// Create new instance.
|
||||
/// </summary>
|
||||
@ -893,10 +922,11 @@ public class Instance
|
||||
#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)
|
||||
{
|
||||
//if (evt.EventHandlerType != typeof(ResourceEventHandler))
|
||||
// continue;
|
||||
|
||||
if (evt.EventInfo == null)
|
||||
continue;
|
||||
@ -906,21 +936,51 @@ public class Instance
|
||||
if (eventGenericType == typeof(ResourceEventHandler<>))
|
||||
{
|
||||
|
||||
// var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
// if (ca.Length == 0)
|
||||
// continue;
|
||||
var dm = new DynamicMethod("_", null,
|
||||
new Type[] {typeof(Instance), evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
else if (eventGenericType == typeof(CustomResourceEventHandler<>))
|
||||
{
|
||||
//var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
//if (ca.Length == 0)
|
||||
// continue;
|
||||
var dm = new DynamicMethod("_", null,
|
||||
new Type[] { typeof(Instance), typeof(object), typeof(Func<Session, bool>),
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,9 @@ using System.Threading.Tasks;
|
||||
|
||||
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 CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args);
|
||||
//public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args);
|
||||
|
@ -9,6 +9,7 @@ using Esiur.Core;
|
||||
using System.Security.Cryptography;
|
||||
using Esiur.Proxy;
|
||||
using Esiur.Net.IIP;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Esiur.Resource.Template;
|
||||
|
||||
@ -393,9 +394,150 @@ public class TypeTemplate
|
||||
|
||||
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)
|
||||
{
|
||||
@ -403,30 +545,15 @@ public class TypeTemplate
|
||||
foreach (var ci in constantsInfo)
|
||||
{
|
||||
var privateAttr = ci.GetCustomAttribute<PrivateAttribute>(true);
|
||||
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
|
||||
if (privateAttr != null)
|
||||
continue;
|
||||
|
||||
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
addConstant(ci, publicAttr);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
{
|
||||
@ -434,117 +561,41 @@ public class TypeTemplate
|
||||
|
||||
if (privateAttr == null)
|
||||
{
|
||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||
|
||||
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);
|
||||
var publicAttr = pi.GetCustomAttribute<PublicAttribute>(true);
|
||||
addProperty(pi, publicAttr);
|
||||
}
|
||||
else
|
||||
{
|
||||
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
||||
if (attributeAttr != null)
|
||||
{
|
||||
var an = attributeAttr.Name ?? pi.Name;
|
||||
var at = new AttributeTemplate(this, 0, an, pi.DeclaringType != type);
|
||||
at.PropertyInfo = pi;
|
||||
attributes.Add(at);
|
||||
addAttribute(pi, attributeAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (templateType == TemplateType.Resource)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
{
|
||||
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
|
||||
if (privateAttr != null)
|
||||
continue;
|
||||
|
||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
||||
|
||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
||||
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);
|
||||
addEvent(ei, publicAttr);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
|
||||
if (privateAttr != null)
|
||||
continue;
|
||||
|
||||
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 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);
|
||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||
addFunction(mi, publicAttr);
|
||||
}
|
||||
|
||||
}
|
||||
@ -554,27 +605,13 @@ public class TypeTemplate
|
||||
foreach (var ci in constantsInfo)
|
||||
{
|
||||
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
||||
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
|
||||
if (publicAttr == null)
|
||||
continue;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
addConstant(ci, publicAttr);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
{
|
||||
@ -582,45 +619,20 @@ public class TypeTemplate
|
||||
|
||||
if (publicAttr != null)
|
||||
{
|
||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
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);
|
||||
addProperty(pi, publicAttr);
|
||||
}
|
||||
else
|
||||
{
|
||||
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
||||
if (attributeAttr != null)
|
||||
{
|
||||
var pn = attributeAttr.Name ?? pi.Name;
|
||||
var at = new AttributeTemplate(this, 0, pn, pi.DeclaringType != type);
|
||||
at.PropertyInfo = pi;
|
||||
attributes.Add(at);
|
||||
addAttribute(pi, attributeAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (templateType == TemplateType.Resource)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
{
|
||||
@ -629,97 +641,32 @@ public class TypeTemplate
|
||||
if (publicAttr == null)
|
||||
continue;
|
||||
|
||||
|
||||
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);
|
||||
addEvent(ei, publicAttr);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||
if (publicAttr == null)
|
||||
continue;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
addFunction(mi, publicAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (i = 0; i < events.Count; i++)
|
||||
for (var i = 0; i < events.Count; i++)
|
||||
members.Add(events[i]);
|
||||
// append slots
|
||||
for (i = 0; i < functions.Count; i++)
|
||||
for (var i = 0; i < functions.Count; i++)
|
||||
members.Add(functions[i]);
|
||||
// append properties
|
||||
for (i = 0; i < properties.Count; i++)
|
||||
for (var i = 0; i < properties.Count; i++)
|
||||
members.Add(properties[i]);
|
||||
|
||||
// append constants
|
||||
for (i = 0; i < constants.Count; i++)
|
||||
for (var i = 0; i < constants.Count; i++)
|
||||
members.Add(constants[i]);
|
||||
|
||||
// bake it binarily
|
||||
@ -729,7 +676,6 @@ public class TypeTemplate
|
||||
|
||||
|
||||
|
||||
|
||||
if (HasParent(type))
|
||||
{
|
||||
// find the first parent type that implements IResource
|
||||
|
Loading…
x
Reference in New Issue
Block a user