diff --git a/Esiur/Esiur.csproj b/Esiur/Esiur.csproj index b878e8f..e094037 100644 --- a/Esiur/Esiur.csproj +++ b/Esiur/Esiur.csproj @@ -6,7 +6,7 @@ Ahmed Kh. Zamil http://www.esiur.com true - 2.2.7 + 2.2.8 https://github.com/esiur/esiur-dotnet Ahmed Kh. Zamil diff --git a/Esiur/Net/IIP/DistributedConnectionProtocol.cs b/Esiur/Net/IIP/DistributedConnectionProtocol.cs index 93fc3cc..7421151 100644 --- a/Esiur/Net/IIP/DistributedConnectionProtocol.cs +++ b/Esiur/Net/IIP/DistributedConnectionProtocol.cs @@ -230,7 +230,7 @@ partial class DistributedConnection await SendDetachRequest(instanceId); } - catch + catch { } @@ -708,7 +708,7 @@ partial class DistributedConnection { if (res != null) { - + // unsubscribe Unsubscribe(res); // remove from cache @@ -1302,7 +1302,7 @@ partial class DistributedConnection // return; //} - InvokeFunction(call.Method, callback, arguments, IIPPacket.IIPPacketAction.ProcedureCall, call.Target); + InvokeFunction(call.Value.Template, callback, arguments, IIPPacket.IIPPacketAction.ProcedureCall, call.Value.Delegate.Target); }).Error(x => { @@ -1355,7 +1355,7 @@ partial class DistributedConnection // return; //} - InvokeFunction(fi, callback, arguments, IIPPacket.IIPPacketAction.StaticCall, null); + InvokeFunction(ft, callback, arguments, IIPPacket.IIPPacketAction.StaticCall, null); }).Error(x => { @@ -1415,14 +1415,14 @@ partial class DistributedConnection else { - var fi = r.GetType().GetMethod(ft.Name); + //var fi = r.GetType().GetMethod(ft.Name); - if (fi == null) - { - // ft found, fi not found, this should never happen - SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound); - return; - } + //if (fi == null) + //{ + // // ft found, fi not found, this should never happen + // SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound); + // return; + //} if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied) @@ -1432,7 +1432,7 @@ partial class DistributedConnection return; } - InvokeFunction(fi, callback, arguments, IIPPacket.IIPPacketAction.InvokeFunction, r); + InvokeFunction(ft, callback, arguments, IIPPacket.IIPPacketAction.InvokeFunction, r); } }); }); @@ -1440,11 +1440,11 @@ partial class DistributedConnection - void InvokeFunction(MethodInfo fi, uint callback, Map arguments, IIPPacket.IIPPacketAction actionType, object target = null) + void InvokeFunction(FunctionTemplate ft, uint callback, Map arguments, IIPPacket.IIPPacketAction actionType, object target = null) { // cast arguments - ParameterInfo[] pis = fi.GetParameters(); + ParameterInfo[] pis = ft.MethodInfo.GetParameters(); object[] args = new object[pis.Length]; @@ -1453,15 +1453,30 @@ partial class DistributedConnection if (pis.Last().ParameterType == typeof(DistributedConnection)) { for (byte i = 0; i < pis.Length - 1; i++) - args[i] = arguments.ContainsKey(i) ? - DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing; + { + if (arguments.ContainsKey(i)) + args[i] = DC.CastConvert(arguments[i], pis[i].ParameterType); + else if (ft.Arguments[i].Type.Nullable)// Nullable.GetUnderlyingType(pis[i].ParameterType) != null) + args[i] = null; + else + args[i] = Type.Missing; + + } + //args[i] = arguments.ContainsKey(i) ? + // DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing; args[args.Length - 1] = this; } else { for (byte i = 0; i < pis.Length; i++) - args[i] = arguments.ContainsKey(i) ? - DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing; + { + if (arguments.ContainsKey(i)) + args[i] = DC.CastConvert(arguments[i], pis[i].ParameterType); + else if (ft.Arguments[i].Type.Nullable) //Nullable.GetUnderlyingType(pis[i].ParameterType) != null) + args[i] = null; + else + args[i] = Type.Missing; + } } } @@ -1469,7 +1484,7 @@ partial class DistributedConnection try { - rt = fi.Invoke(target, args); + rt = ft.MethodInfo.Invoke(target, args); } catch (Exception ex) { diff --git a/Esiur/Net/IIP/DistributedServer.cs b/Esiur/Net/IIP/DistributedServer.cs index ae8276b..b370825 100644 --- a/Esiur/Net/IIP/DistributedServer.cs +++ b/Esiur/Net/IIP/DistributedServer.cs @@ -35,6 +35,7 @@ using System.Net; using Esiur.Resource; using Esiur.Security.Membership; using System.Threading.Tasks; +using Esiur.Resource.Template; namespace Esiur.Net.IIP; public class DistributedServer : NetworkServer, IResource @@ -183,11 +184,18 @@ public class DistributedServer : NetworkServer, IResource } - public KeyList Calls { get; } = new KeyList(); + public KeyList Calls { get; } = new KeyList(); + + public struct CallInfo + { + public FunctionTemplate Template; + public Delegate Delegate; + } public DistributedServer MapCall(string call, Delegate handler) { - Calls.Add(call, handler); + var ft = FunctionTemplate.MakeFunctionTemplate(null, handler.Method); + Calls.Add(call, new CallInfo(){ Delegate = handler, Template = ft}); return this; } diff --git a/Esiur/Resource/Template/ConstantTemplate.cs b/Esiur/Resource/Template/ConstantTemplate.cs index a6690b5..3844573 100644 --- a/Esiur/Resource/Template/ConstantTemplate.cs +++ b/Esiur/Resource/Template/ConstantTemplate.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using Esiur.Data; @@ -12,7 +14,9 @@ public class ConstantTemplate : MemberTemplate public readonly string Annotation; public readonly RepresentationType ValueType; - public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation) + public FieldInfo FieldInfo { get; set; } + + public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation) : base(template, index, name, inherited) { Annotation = annotation; @@ -29,7 +33,7 @@ public class ConstantTemplate : MemberTemplate //} } - public override byte[] Compose() + public override byte[] Compose() { var name = base.Compose(); @@ -63,5 +67,29 @@ public class ConstantTemplate : MemberTemplate .ToArray(); } } + + + public static ConstantTemplate MakeConstantTemplate(Type type, FieldInfo ci, PublicAttribute publicAttr, byte index = 0, TypeTemplate typeTemplate = null) + { + var annotationAttr = ci.GetCustomAttribute(true); + var nullableAttr = ci.GetCustomAttribute(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 (typeTemplate?.Type == TemplateType.Enum) + value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType()); + + var ct = new ConstantTemplate(typeTemplate, index, publicAttr?.Name ?? ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation); + ct.FieldInfo = ci; + + return ct; + + } + } diff --git a/Esiur/Resource/Template/EventTemplate.cs b/Esiur/Resource/Template/EventTemplate.cs index cf8a6dd..776e46e 100644 --- a/Esiur/Resource/Template/EventTemplate.cs +++ b/Esiur/Resource/Template/EventTemplate.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -60,4 +61,51 @@ public class EventTemplate : MemberTemplate this.Listenable = listenable; this.ArgumentType = argumentType; } + + public static EventTemplate MakeEventTemplate(Type type, EventInfo ei, byte index = 0, string customName = null, TypeTemplate typeTemplate = null) + { + 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 annotationAttr = ei.GetCustomAttribute(true); + var listenableAttr = ei.GetCustomAttribute(true); + var nullableAttr = ei.GetCustomAttribute(true); + var nullableContextAttr = ei.GetCustomAttribute(true); + + var flags = nullableAttr?.Flags?.ToList() ?? new List(); + + // skip the eventHandler class + if (flags.Count > 1) + flags = flags.Skip(1).ToList(); + + if (nullableContextAttr?.Flag == 2) + { + if (flags.Count == 1) + evtType.SetNotNull(flags.FirstOrDefault()); + else + evtType.SetNotNull(flags); + } + else + { + if (flags.Count == 1) + evtType.SetNull(flags.FirstOrDefault()); + else + evtType.SetNull(flags); + } + + var et = new EventTemplate(typeTemplate, index, customName ?? ei.Name, ei.DeclaringType != type, evtType); + et.EventInfo = ei; + + if (annotationAttr != null) + et.Annotation = annotationAttr.Annotation; + + if (listenableAttr != null) + et.Listenable = true; + + return et; + } + } diff --git a/Esiur/Resource/Template/FunctionTemplate.cs b/Esiur/Resource/Template/FunctionTemplate.cs index 0b6f9aa..7f4e2cf 100644 --- a/Esiur/Resource/Template/FunctionTemplate.cs +++ b/Esiur/Resource/Template/FunctionTemplate.cs @@ -1,8 +1,11 @@ -using Esiur.Data; +using Esiur.Core; +using Esiur.Data; +using Esiur.Net.IIP; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -71,4 +74,115 @@ public class FunctionTemplate : MemberTemplate this.Annotation = annotation; this.IsStatic = isStatic; } + + + + public static FunctionTemplate MakeFunctionTemplate(Type type, MethodInfo mi, byte index = 0, string customName = null, TypeTemplate typeTemplate = null) + { + + var genericRtType = mi.ReturnType.IsGenericType ? mi.ReturnType.GetGenericTypeDefinition() : null; + + var rtType = genericRtType == typeof(AsyncReply<>) ? + RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]) : + RepresentationType.FromType(mi.ReturnType); + + if (rtType == null) + throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return"); + + var annotationAttr = mi.GetCustomAttribute(true); + var nullableAttr = mi.GetCustomAttribute(true); + var nullableContextAttr = mi.GetCustomAttribute(true); + + var flags = nullableAttr?.Flags?.ToList() ?? new List(); + + var rtNullableAttr = mi.ReturnTypeCustomAttributes.GetCustomAttributes(typeof(NullableAttribute), true).FirstOrDefault() as NullableAttribute; + var rtNullableContextAttr = mi.ReturnTypeCustomAttributes + .GetCustomAttributes(typeof(NullableContextAttribute), true) + .FirstOrDefault() as NullableContextAttribute + ?? nullableContextAttr; + + var rtFlags = rtNullableAttr?.Flags?.ToList() ?? new List(); + + if (rtFlags.Count > 0 && genericRtType == typeof(AsyncReply<>)) + rtFlags.RemoveAt(0); + + if (rtNullableContextAttr?.Flag == 2) + { + if (rtFlags.Count == 1) + rtType.SetNotNull(rtFlags.FirstOrDefault()); + else + rtType.SetNotNull(rtFlags); + } + else + { + if (rtFlags.Count == 1) + rtType.SetNull(rtFlags.FirstOrDefault()); + else + rtType.SetNull(rtFlags); + } + + 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}`"); + + + var argNullableAttr = x.GetCustomAttribute(true); + var argNullableContextAttr = x.GetCustomAttribute(true) ?? nullableContextAttr; + + var argFlags = argNullableAttr?.Flags?.ToList() ?? new List(); + + + if (argNullableContextAttr?.Flag == 2) + { + if (argFlags.Count == 1) + argType.SetNotNull(argFlags.FirstOrDefault()); + else + argType.SetNotNull(argFlags); + } + else + { + if (rtFlags.Count == 1) + argType.SetNull(argFlags.FirstOrDefault()); + else + argType.SetNull(argFlags); + } + + return new ArgumentTemplate() + { + Name = x.Name, + Type = argType, + ParameterInfo = x, + Optional = x.IsOptional + }; + }) + .ToArray(); + + var fn = customName ?? mi.Name; + + var ft = new FunctionTemplate(typeTemplate, index, fn, mi.DeclaringType != type, + mi.IsStatic, + arguments, rtType); + + if (annotationAttr != null) + ft.Annotation = annotationAttr.Annotation; + else + ft.Annotation = "(" + 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); + + return ft; + } + } diff --git a/Esiur/Resource/Template/PropertyTemplate.cs b/Esiur/Resource/Template/PropertyTemplate.cs index a024eb9..fd2e38d 100644 --- a/Esiur/Resource/Template/PropertyTemplate.cs +++ b/Esiur/Resource/Template/PropertyTemplate.cs @@ -1,8 +1,10 @@ using Esiur.Data; +using Esiur.Net.IIP; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -144,4 +146,70 @@ public class PropertyTemplate : MemberTemplate this.WriteAnnotation = writeAnnotation; this.ValueType = valueType; } + + + + public static PropertyTemplate MakePropertyTemplate(Type type, PropertyInfo pi, byte index = 0, string customName = null, TypeTemplate typeTemplate = null) + { + var genericPropType = pi.PropertyType.IsGenericType ? pi.PropertyType.GetGenericTypeDefinition() : null; + + var propType = genericPropType == typeof(DistributedPropertyContext<>) ? + RepresentationType.FromType(pi.PropertyType.GetGenericArguments()[0]) : + RepresentationType.FromType(pi.PropertyType); + + if (propType == null) + throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`"); + + var annotationAttr = pi.GetCustomAttribute(true); + var storageAttr = pi.GetCustomAttribute(true); + + var nullableContextAttr = pi.GetCustomAttribute(true); + var nullableAttr = pi.GetCustomAttribute(true); + + var flags = nullableAttr?.Flags?.ToList() ?? new List(); + + if (flags.Count > 0 && genericPropType == typeof(DistributedPropertyContext<>)) + flags.RemoveAt(0); + + if (nullableContextAttr?.Flag == 2) + { + if (flags.Count == 1) + propType.SetNotNull(flags.FirstOrDefault()); + else + propType.SetNotNull(flags); + } + else + { + if (flags.Count == 1) + propType.SetNull(flags.FirstOrDefault()); + else + propType.SetNull(flags); + } + + var pt = new PropertyTemplate(typeTemplate, index, customName ?? pi.Name, pi.DeclaringType != type, propType); + + if (storageAttr != null) + pt.Recordable = storageAttr.Mode == StorageMode.Recordable; + + if (annotationAttr != null) + pt.ReadAnnotation = annotationAttr.Annotation; + else + pt.ReadAnnotation = GetTypeAnnotationName(pi.PropertyType); + + pt.PropertyInfo = pi; + + return pt; + } + + + public static string GetTypeAnnotationName(Type type) + { + var nullType = Nullable.GetUnderlyingType(type); + if (nullType == null) + return type.Name; + else + return type.Name + "?"; + } + + } diff --git a/Esiur/Resource/Template/TypeTemplate.cs b/Esiur/Resource/Template/TypeTemplate.cs index 506270e..c96b3e0 100644 --- a/Esiur/Resource/Template/TypeTemplate.cs +++ b/Esiur/Resource/Template/TypeTemplate.cs @@ -351,14 +351,6 @@ public class TypeTemplate return list.ToArray(); } - public string GetTypeAnnotationName(Type type) - { - var nullType = Nullable.GetUnderlyingType(type); - if (nullType == null) - return type.Name; - else - return type.Name + "?"; - } public static string GetTypeClassName(Type type, string separator = ".") { @@ -376,6 +368,31 @@ public class TypeTemplate return $"{type.Namespace}{separator}{type.Name}"; } + + + + public static ConstantTemplate MakeConstantTemplate(Type type, FieldInfo ci, PublicAttribute publicAttr, byte index = 0, TypeTemplate typeTemplate = null) + { + var annotationAttr = ci.GetCustomAttribute(true); + var nullableAttr = ci.GetCustomAttribute(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 (typeTemplate.Type == TemplateType.Enum) + value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType()); + + var ct = new ConstantTemplate(typeTemplate, index, publicAttr?.Name ?? ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation); + + return ct; + + } + + public TypeTemplate(Type type, bool addToWarehouse = false) { if (Codec.InheritsClass(type, typeof(DistributedResource))) @@ -411,133 +428,16 @@ public class TypeTemplate PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance); - MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); + MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); FieldInfo[] constantsInfo = type.GetFields(BindingFlags.Public | BindingFlags.Static); bool classIsPublic = type.IsEnum || (type.GetCustomAttribute() != null); - var addConstant = (FieldInfo ci, PublicAttribute publicAttr) => - { - - var annotationAttr = ci.GetCustomAttribute(true); - var nullableAttr = ci.GetCustomAttribute(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, (byte)constants.Count, publicAttr?.Name ?? ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation); - - constants.Add(ct); - }; - - var addProperty = (PropertyInfo pi, PublicAttribute publicAttr) => - { - - var genericPropType = pi.PropertyType.IsGenericType ? pi.PropertyType.GetGenericTypeDefinition() : null; - - var propType = genericPropType == typeof(DistributedPropertyContext<>) ? - RepresentationType.FromType(pi.PropertyType.GetGenericArguments()[0]) : - RepresentationType.FromType(pi.PropertyType); - - if (propType == null) - throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`"); - - var annotationAttr = pi.GetCustomAttribute(true); - var storageAttr = pi.GetCustomAttribute(true); - - var nullableContextAttr = pi.GetCustomAttribute(true); - var nullableAttr = pi.GetCustomAttribute(true); - - var flags = nullableAttr?.Flags?.ToList() ?? new List(); - - if (flags.Count > 0 && genericPropType == typeof(DistributedPropertyContext<>)) - flags.RemoveAt(0); - - if (nullableContextAttr?.Flag == 2) - { - if (flags.Count == 1) - propType.SetNotNull(flags.FirstOrDefault()); - else - propType.SetNotNull(flags); - } - else - { - if (flags.Count == 1) - propType.SetNull(flags.FirstOrDefault()); - else - propType.SetNull(flags); - } - - var pt = new PropertyTemplate(this, (byte)properties.Count, publicAttr?.Name ?? pi.Name, pi.DeclaringType != type, propType); - - if (storageAttr != null) - pt.Recordable = storageAttr.Mode == StorageMode.Recordable; - - if (annotationAttr != null) - pt.ReadAnnotation = annotationAttr.Annotation; - else - pt.ReadAnnotation = GetTypeAnnotationName(pi.PropertyType); - - pt.PropertyInfo = pi; - - properties.Add(pt); - - }; - - var addEvent = (EventInfo ei, PublicAttribute publicAttr) => - { - 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 annotationAttr = ei.GetCustomAttribute(true); - var listenableAttr = ei.GetCustomAttribute(true); - var nullableAttr = ei.GetCustomAttribute(true); - var nullableContextAttr = ei.GetCustomAttribute(true); - - var flags = nullableAttr?.Flags?.ToList() ?? new List(); - - // skip the eventHandler class - if (flags.Count > 1) - flags = flags.Skip(1).ToList(); - - if (nullableContextAttr?.Flag == 2) - { - if (flags.Count == 1) - evtType.SetNotNull(flags.FirstOrDefault()); - else - evtType.SetNotNull(flags); - } - else - { - if (flags.Count == 1) - evtType.SetNull(flags.FirstOrDefault()); - else - evtType.SetNull(flags); - } - - var et = new EventTemplate(this, (byte)events.Count, publicAttr?.Name ?? ei.Name, ei.DeclaringType != type, evtType); - et.EventInfo = ei; - - if (annotationAttr != null) - et.Annotation = annotationAttr.Annotation; - - if (listenableAttr != null) - et.Listenable = true; - - events.Add(et); - }; + + + var addAttribute = (PropertyInfo pi, AttributeAttribute attributeAttr) => { var an = attributeAttr.Name ?? pi.Name; @@ -547,111 +447,6 @@ public class TypeTemplate }; - var addFunction = (MethodInfo mi, PublicAttribute publicAttr) => - { - var genericRtType = mi.ReturnType.IsGenericType ? mi.ReturnType.GetGenericTypeDefinition() : null; - - var rtType = genericRtType == typeof(AsyncReply<>) ? - RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]) : - RepresentationType.FromType(mi.ReturnType); - - if (rtType == null) - throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return"); - - var annotationAttr = mi.GetCustomAttribute(true); - var nullableAttr = mi.GetCustomAttribute(true); - var nullableContextAttr = mi.GetCustomAttribute(true); - - var flags = nullableAttr?.Flags?.ToList() ?? new List(); - - var rtNullableAttr = mi.ReturnTypeCustomAttributes.GetCustomAttributes(typeof(NullableAttribute), true).FirstOrDefault() as NullableAttribute; - var rtNullableContextAttr = mi.ReturnTypeCustomAttributes - .GetCustomAttributes(typeof(NullableContextAttribute), true) - .FirstOrDefault() as NullableContextAttribute - ?? nullableContextAttr; - - var rtFlags = rtNullableAttr?.Flags?.ToList() ?? new List(); - - if (rtFlags.Count > 0 && genericRtType == typeof(AsyncReply<>)) - rtFlags.RemoveAt(0); - - if (rtNullableContextAttr?.Flag == 2) - { - if (rtFlags.Count == 1) - rtType.SetNotNull(rtFlags.FirstOrDefault()); - else - rtType.SetNotNull(rtFlags); - } - else - { - if (rtFlags.Count == 1) - rtType.SetNull(rtFlags.FirstOrDefault()); - else - rtType.SetNull(rtFlags); - } - - 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}`"); - - - var argNullableAttr = x.GetCustomAttribute(true); - var argNullableContextAttr = x.GetCustomAttribute(true) ?? nullableContextAttr; - - var argFlags = argNullableAttr?.Flags?.ToList() ?? new List(); - - - if (argNullableContextAttr?.Flag == 2) - { - if (argFlags.Count == 1) - argType.SetNotNull(argFlags.FirstOrDefault()); - else - argType.SetNotNull(argFlags); - } - else - { - if (rtFlags.Count == 1) - argType.SetNull(argFlags.FirstOrDefault()); - else - argType.SetNull(argFlags); - } - - 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, - mi.IsStatic, - arguments, rtType); - - if (annotationAttr != null) - ft.Annotation = annotationAttr.Annotation; - else - ft.Annotation = "(" + 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); - - }; @@ -667,7 +462,8 @@ public class TypeTemplate var publicAttr = ci.GetCustomAttribute(true); - addConstant(ci, publicAttr); + var ct = MakeConstantTemplate(type, ci, publicAttr, (byte)constants.Count, this); + constants.Add(ct); } @@ -678,7 +474,8 @@ public class TypeTemplate if (privateAttr == null) { var publicAttr = pi.GetCustomAttribute(true); - addProperty(pi, publicAttr); + var pt = PropertyTemplate.MakePropertyTemplate(type, pi, (byte)properties.Count, publicAttr?.Name, this); + properties.Add(pt); } else { @@ -701,8 +498,8 @@ public class TypeTemplate continue; var publicAttr = ei.GetCustomAttribute(true); - - addEvent(ei, publicAttr); + var et = EventTemplate.MakeEventTemplate(type, ei, (byte)events.Count, publicAttr?.Name, this); + events.Add(et); } foreach (MethodInfo mi in methodsInfo) @@ -712,7 +509,9 @@ public class TypeTemplate continue; var publicAttr = mi.GetCustomAttribute(true); - addFunction(mi, publicAttr); + var ft = FunctionTemplate.MakeFunctionTemplate(type, mi, (byte)functions.Count, publicAttr?.Name, this); + functions.Add(ft); + //addFunction(mi, publicAttr); } } @@ -726,7 +525,8 @@ public class TypeTemplate if (publicAttr == null) continue; - addConstant(ci, publicAttr); + var ct = MakeConstantTemplate(type, ci, publicAttr, (byte)constants.Count, this); + constants.Add(ct); } @@ -736,7 +536,8 @@ public class TypeTemplate if (publicAttr != null) { - addProperty(pi, publicAttr); + var pt = PropertyTemplate.MakePropertyTemplate(type, pi, (byte)properties.Count, publicAttr?.Name, this); + properties.Add(pt); } else { @@ -759,7 +560,8 @@ public class TypeTemplate if (publicAttr == null) continue; - addEvent(ei, publicAttr); + var et = EventTemplate.MakeEventTemplate(type, ei, (byte)events.Count, publicAttr?.Name, this); + events.Add(et); } foreach (MethodInfo mi in methodsInfo) @@ -768,7 +570,9 @@ public class TypeTemplate if (publicAttr == null) continue; - addFunction(mi, publicAttr); + var ft = FunctionTemplate.MakeFunctionTemplate(type, mi, (byte)functions.Count, publicAttr?.Name, this); + functions.Add(ft); + //addFunction(mi, publicAttr); } } }