mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 11:32:59 +00:00
Make...Template
This commit is contained in:
parent
2f379732ae
commit
ebcf8525fa
@ -6,7 +6,7 @@
|
|||||||
<Copyright>Ahmed Kh. Zamil</Copyright>
|
<Copyright>Ahmed Kh. Zamil</Copyright>
|
||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Version>2.2.7</Version>
|
<Version>2.2.8</Version>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
||||||
<Authors>Ahmed Kh. Zamil</Authors>
|
<Authors>Ahmed Kh. Zamil</Authors>
|
||||||
<AssemblyVersion></AssemblyVersion>
|
<AssemblyVersion></AssemblyVersion>
|
||||||
|
@ -1302,7 +1302,7 @@ partial class DistributedConnection
|
|||||||
// return;
|
// 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 =>
|
}).Error(x =>
|
||||||
{
|
{
|
||||||
@ -1355,7 +1355,7 @@ partial class DistributedConnection
|
|||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
InvokeFunction(fi, callback, arguments, IIPPacket.IIPPacketAction.StaticCall, null);
|
InvokeFunction(ft, callback, arguments, IIPPacket.IIPPacketAction.StaticCall, null);
|
||||||
|
|
||||||
}).Error(x =>
|
}).Error(x =>
|
||||||
{
|
{
|
||||||
@ -1415,14 +1415,14 @@ partial class DistributedConnection
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
var fi = r.GetType().GetMethod(ft.Name);
|
//var fi = r.GetType().GetMethod(ft.Name);
|
||||||
|
|
||||||
if (fi == null)
|
//if (fi == null)
|
||||||
{
|
//{
|
||||||
// ft found, fi not found, this should never happen
|
// // ft found, fi not found, this should never happen
|
||||||
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound);
|
// SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound);
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied)
|
if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied)
|
||||||
@ -1432,7 +1432,7 @@ partial class DistributedConnection
|
|||||||
return;
|
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<byte, object> arguments, IIPPacket.IIPPacketAction actionType, object target = null)
|
void InvokeFunction(FunctionTemplate ft, uint callback, Map<byte, object> arguments, IIPPacket.IIPPacketAction actionType, object target = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
// cast arguments
|
// cast arguments
|
||||||
ParameterInfo[] pis = fi.GetParameters();
|
ParameterInfo[] pis = ft.MethodInfo.GetParameters();
|
||||||
|
|
||||||
object[] args = new object[pis.Length];
|
object[] args = new object[pis.Length];
|
||||||
|
|
||||||
@ -1453,15 +1453,30 @@ partial class DistributedConnection
|
|||||||
if (pis.Last().ParameterType == typeof(DistributedConnection))
|
if (pis.Last().ParameterType == typeof(DistributedConnection))
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < pis.Length - 1; i++)
|
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;
|
args[args.Length - 1] = this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < pis.Length; i++)
|
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
|
try
|
||||||
{
|
{
|
||||||
rt = fi.Invoke(target, args);
|
rt = ft.MethodInfo.Invoke(target, args);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@ using System.Net;
|
|||||||
using Esiur.Resource;
|
using Esiur.Resource;
|
||||||
using Esiur.Security.Membership;
|
using Esiur.Security.Membership;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Esiur.Resource.Template;
|
||||||
|
|
||||||
namespace Esiur.Net.IIP;
|
namespace Esiur.Net.IIP;
|
||||||
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
||||||
@ -183,11 +184,18 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyList<string, Delegate> Calls { get; } = new KeyList<string, Delegate>();
|
public KeyList<string, CallInfo?> Calls { get; } = new KeyList<string, CallInfo?>();
|
||||||
|
|
||||||
|
public struct CallInfo
|
||||||
|
{
|
||||||
|
public FunctionTemplate Template;
|
||||||
|
public Delegate Delegate;
|
||||||
|
}
|
||||||
|
|
||||||
public DistributedServer MapCall(string call, Delegate handler)
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Esiur.Data;
|
using Esiur.Data;
|
||||||
|
|
||||||
@ -12,6 +14,8 @@ public class ConstantTemplate : MemberTemplate
|
|||||||
public readonly string Annotation;
|
public readonly string Annotation;
|
||||||
public readonly RepresentationType ValueType;
|
public readonly RepresentationType ValueType;
|
||||||
|
|
||||||
|
public FieldInfo FieldInfo { get; set; }
|
||||||
|
|
||||||
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation)
|
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation)
|
||||||
: base(template, index, name, inherited)
|
: base(template, index, name, inherited)
|
||||||
{
|
{
|
||||||
@ -29,7 +33,7 @@ public class ConstantTemplate : MemberTemplate
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] Compose()
|
public override byte[] Compose()
|
||||||
{
|
{
|
||||||
var name = base.Compose();
|
var name = base.Compose();
|
||||||
|
|
||||||
@ -63,5 +67,29 @@ public class ConstantTemplate : MemberTemplate
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ConstantTemplate MakeConstantTemplate(Type type, FieldInfo ci, PublicAttribute publicAttr, byte index = 0, TypeTemplate typeTemplate = null)
|
||||||
|
{
|
||||||
|
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var nullableAttr = ci.GetCustomAttribute<NullableAttribute>(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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -60,4 +61,51 @@ public class EventTemplate : MemberTemplate
|
|||||||
this.Listenable = listenable;
|
this.Listenable = listenable;
|
||||||
this.ArgumentType = argumentType;
|
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<AnnotationAttribute>(true);
|
||||||
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
var nullableAttr = ei.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
var nullableContextAttr = ei.GetCustomAttribute<NullableContextAttribute>(true);
|
||||||
|
|
||||||
|
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
using Esiur.Data;
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -71,4 +74,115 @@ public class FunctionTemplate : MemberTemplate
|
|||||||
this.Annotation = annotation;
|
this.Annotation = annotation;
|
||||||
this.IsStatic = isStatic;
|
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<AnnotationAttribute>(true);
|
||||||
|
var nullableAttr = mi.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
var nullableContextAttr = mi.GetCustomAttribute<NullableContextAttribute>(true);
|
||||||
|
|
||||||
|
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
||||||
|
|
||||||
|
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<byte>();
|
||||||
|
|
||||||
|
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<NullableAttribute>(true);
|
||||||
|
var argNullableContextAttr = x.GetCustomAttribute<NullableContextAttribute>(true) ?? nullableContextAttr;
|
||||||
|
|
||||||
|
var argFlags = argNullableAttr?.Flags?.ToList() ?? new List<byte>();
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
using Esiur.Data;
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -144,4 +146,70 @@ public class PropertyTemplate : MemberTemplate
|
|||||||
this.WriteAnnotation = writeAnnotation;
|
this.WriteAnnotation = writeAnnotation;
|
||||||
this.ValueType = valueType;
|
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<AnnotationAttribute>(true);
|
||||||
|
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||||
|
|
||||||
|
var nullableContextAttr = pi.GetCustomAttribute<NullableContextAttribute>(true);
|
||||||
|
var nullableAttr = pi.GetCustomAttribute<NullableAttribute>(true);
|
||||||
|
|
||||||
|
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
||||||
|
|
||||||
|
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 + "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -351,14 +351,6 @@ public class TypeTemplate
|
|||||||
return list.ToArray();
|
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 = ".")
|
public static string GetTypeClassName(Type type, string separator = ".")
|
||||||
{
|
{
|
||||||
@ -376,6 +368,31 @@ public class TypeTemplate
|
|||||||
return $"{type.Namespace}{separator}{type.Name}";
|
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<AnnotationAttribute>(true);
|
||||||
|
var nullableAttr = ci.GetCustomAttribute<NullableAttribute>(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)
|
public TypeTemplate(Type type, bool addToWarehouse = false)
|
||||||
{
|
{
|
||||||
if (Codec.InheritsClass(type, typeof(DistributedResource)))
|
if (Codec.InheritsClass(type, typeof(DistributedResource)))
|
||||||
@ -417,126 +434,9 @@ 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);
|
|
||||||
|
|
||||||
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<AnnotationAttribute>(true);
|
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
|
||||||
|
|
||||||
var nullableContextAttr = pi.GetCustomAttribute<NullableContextAttribute>(true);
|
|
||||||
var nullableAttr = pi.GetCustomAttribute<NullableAttribute>(true);
|
|
||||||
|
|
||||||
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
|
||||||
|
|
||||||
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<AnnotationAttribute>(true);
|
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
|
||||||
var nullableAttr = ei.GetCustomAttribute<NullableAttribute>(true);
|
|
||||||
var nullableContextAttr = ei.GetCustomAttribute<NullableContextAttribute>(true);
|
|
||||||
|
|
||||||
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
|
||||||
|
|
||||||
// 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 addAttribute = (PropertyInfo pi, AttributeAttribute attributeAttr) =>
|
||||||
{
|
{
|
||||||
@ -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<AnnotationAttribute>(true);
|
|
||||||
var nullableAttr = mi.GetCustomAttribute<NullableAttribute>(true);
|
|
||||||
var nullableContextAttr = mi.GetCustomAttribute<NullableContextAttribute>(true);
|
|
||||||
|
|
||||||
var flags = nullableAttr?.Flags?.ToList() ?? new List<byte>();
|
|
||||||
|
|
||||||
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<byte>();
|
|
||||||
|
|
||||||
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<NullableAttribute>(true);
|
|
||||||
var argNullableContextAttr = x.GetCustomAttribute<NullableContextAttribute>(true) ?? nullableContextAttr;
|
|
||||||
|
|
||||||
var argFlags = argNullableAttr?.Flags?.ToList() ?? new List<byte>();
|
|
||||||
|
|
||||||
|
|
||||||
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<PublicAttribute>(true);
|
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(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)
|
if (privateAttr == null)
|
||||||
{
|
{
|
||||||
var publicAttr = pi.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = pi.GetCustomAttribute<PublicAttribute>(true);
|
||||||
addProperty(pi, publicAttr);
|
var pt = PropertyTemplate.MakePropertyTemplate(type, pi, (byte)properties.Count, publicAttr?.Name, this);
|
||||||
|
properties.Add(pt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -701,8 +498,8 @@ public class TypeTemplate
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
||||||
|
var et = EventTemplate.MakeEventTemplate(type, ei, (byte)events.Count, publicAttr?.Name, this);
|
||||||
addEvent(ei, publicAttr);
|
events.Add(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
@ -712,7 +509,9 @@ public class TypeTemplate
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(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)
|
if (publicAttr == null)
|
||||||
continue;
|
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)
|
if (publicAttr != null)
|
||||||
{
|
{
|
||||||
addProperty(pi, publicAttr);
|
var pt = PropertyTemplate.MakePropertyTemplate(type, pi, (byte)properties.Count, publicAttr?.Name, this);
|
||||||
|
properties.Add(pt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -759,7 +560,8 @@ public class TypeTemplate
|
|||||||
if (publicAttr == null)
|
if (publicAttr == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
addEvent(ei, publicAttr);
|
var et = EventTemplate.MakeEventTemplate(type, ei, (byte)events.Count, publicAttr?.Name, this);
|
||||||
|
events.Add(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
@ -768,7 +570,9 @@ public class TypeTemplate
|
|||||||
if (publicAttr == null)
|
if (publicAttr == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
addFunction(mi, publicAttr);
|
var ft = FunctionTemplate.MakeFunctionTemplate(type, mi, (byte)functions.Count, publicAttr?.Name, this);
|
||||||
|
functions.Add(ft);
|
||||||
|
//addFunction(mi, publicAttr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user