From a4555b5e71ff4fc8ed89396d02218694230d1292 Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Mon, 22 Aug 2016 13:41:50 +0200 Subject: [PATCH] =?utf8?q?search=20extension=20methods=20for=20expand=20de?= =?utf8?q?legate=20move=20recurent=20MemberInfo=20to=20global=20static.=20?= =?utf8?q?=09modifi=C3=A9=C2=A0:=20=20=20=20=20=20=20=20=20src/CompilerSer?= =?utf8?q?vices/CompilerServices.cs=20=09modifi=C3=A9=C2=A0:=20=20=20=20?= =?utf8?q?=20=20=20=20=20src/IMLReader.cs=20=09modifi=C3=A9=C2=A0:=20=20?= =?utf8?q?=20=20=20=20=20=20=20src/ItemTemplate.cs?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/CompilerServices/CompilerServices.cs | 39 ++++++++++++++++-------- src/IMLReader.cs | 22 +++++++++---- src/ItemTemplate.cs | 24 +++++++++++++-- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 7a73574b..26a185ed 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -16,6 +16,18 @@ namespace Crow static FieldInfo miSetCurIface = typeof(GraphicObject).GetField ("currentInterface", BindingFlags.NonPublic | BindingFlags.Instance); + #region ValueChange Reflexion member info + static MethodInfo stringEquals = typeof (string).GetMethod + ("Equals", new Type [3] { typeof (string), typeof (string), typeof (StringComparison) }); + static EventInfo eiValueChange = typeof (IValueChange).GetEvent ("ValueChanged"); + static MethodInfo miInvokeValueChange = eiValueChange.EventHandlerType.GetMethod ("Invoke"); + static Type [] argsValueChange = { typeof (object), typeof (object), miInvokeValueChange.GetParameters () [1].ParameterType }; + static FieldInfo fiNewValue = typeof (ValueChangeEventArgs).GetField ("NewValue"); + static FieldInfo fiMbName = typeof (ValueChangeEventArgs).GetField ("MemberName"); + static MethodInfo miValueChangeAdd = eiValueChange.GetAddMethod (); + #endregion + + public static void emitSetCurInterface(ILGenerator il){ il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Ldarg_1); @@ -196,16 +208,7 @@ namespace Crow b.Resolved = true; } - MethodInfo stringEquals = typeof (string).GetMethod - ("Equals", new Type [3] { typeof (string), typeof (string), typeof (StringComparison) }); Type target_Type = Bindings [0].Source.Instance.GetType (); - EventInfo ei = typeof (IValueChange).GetEvent ("ValueChanged"); - MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke"); - ParameterInfo [] evtParams = evtInvoke.GetParameters (); - Type handlerArgsType = evtParams [1].ParameterType; - Type [] args = { typeof (object), typeof (object), handlerArgsType }; - FieldInfo fiNewValue = typeof (ValueChangeEventArgs).GetField ("NewValue"); - FieldInfo fiMbName = typeof (ValueChangeEventArgs).GetField ("MemberName"); //group;only one dynMethods by target (valuechanged event source) //changed value name tested in switch @@ -228,7 +231,7 @@ namespace Crow MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot, CallingConventions.Standard, typeof (void), - args, + argsValueChange, target_Type, true); il = dm.GetILGenerator (256); @@ -376,9 +379,8 @@ namespace Crow il.Emit (OpCodes.Pop); il.Emit (OpCodes.Ret); - Delegate del = dm.CreateDelegate (ei.EventHandlerType, Bindings [0].Source.Instance); - MethodInfo addHandler = ei.GetAddMethod (); - addHandler.Invoke (grouped [0].Target.Instance, new object [] { del }); + Delegate del = dm.CreateDelegate (eiValueChange.EventHandlerType, Bindings [0].Source.Instance); + miValueChangeAdd.Invoke (grouped [0].Target.Instance, new object [] { del }); } } @@ -589,6 +591,17 @@ namespace Crow return query; } + + public static MethodInfo SearchExtMethod(Type t, string methodName){ + MethodInfo mi = null; + mi = GetExtensionMethods (Assembly.GetEntryAssembly(), t) + .Where (em => em.Name == methodName).FirstOrDefault (); + if (mi != null) + return mi; + + return GetExtensionMethods (Assembly.GetExecutingAssembly(), t) + .Where (em => em.Name == methodName).FirstOrDefault (); + } } } diff --git a/src/IMLReader.cs b/src/IMLReader.cs index dc7736f5..bf6cbc49 100644 --- a/src/IMLReader.cs +++ b/src/IMLReader.cs @@ -132,13 +132,23 @@ namespace Crow path = reader.Value; } reader.MoveToElement (); - using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) { - string uid = Guid.NewGuid ().ToString (); - Interface.Instantiators [uid] = - new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas); - - itemTemplateIds.Add (new string[] { dataType, uid, datas }); + + string itemTmpID; + + if (string.IsNullOrEmpty (path)) { + using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) { + itemTmpID = Guid.NewGuid ().ToString (); + Interface.Instantiators [itemTmpID] = + new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas); + } + }else{ + if (!reader.IsEmptyElement) + throw new Exception ("ItemTemplate with Path attribute may not include sub nodes"); + itemTmpID = path; + Interface.Instantiators [itemTmpID] = + new ItemTemplate (itemTmpID, dataType, datas); } + itemTemplateIds.Add (new string[] { dataType, itemTmpID, datas }); } } diff --git a/src/ItemTemplate.cs b/src/ItemTemplate.cs index 95d00806..0e2a98ff 100644 --- a/src/ItemTemplate.cs +++ b/src/ItemTemplate.cs @@ -27,6 +27,7 @@ using System.Xml.Serialization; using System.Xml; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; namespace Crow { @@ -36,8 +37,10 @@ namespace Crow string fetchMethodName; #region CTOR - public ItemTemplate(string path) + public ItemTemplate(string path, string _dataType = null, string _fetchDataMethod = null) : base(path) { + strDataType = _dataType; + fetchMethodName = _fetchDataMethod; } public ItemTemplate (Type _root, InstanciatorInvoker _loader,string _dataType, string _fetchDataMethod) :base(_root, _loader) @@ -102,8 +105,7 @@ namespace Crow il.Emit (OpCodes.Ldarg_1);//get the dataSource of the sender il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetProperty("DataSource").GetGetMethod ()); - MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); - il.Emit (OpCodes.Callvirt, miGetDatas); + emitGetSubData(il, dataType); //set 'return' from the fetch method as 'data' of the list il.Emit (OpCodes.Callvirt, piListData.GetSetMethod ()); @@ -115,6 +117,22 @@ namespace Crow Expand = (EventHandler)dm.CreateDelegate (evtType, host); } + void emitGetSubData(ILGenerator il, Type dataType){ + MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); + if (miGetDatas == null) + miGetDatas = CompilerServices.SearchExtMethod (dataType, fetchMethodName); + + if (miGetDatas == null) {//in last resort, search among properties + PropertyInfo piDatas = dataType.GetProperty (fetchMethodName); + if (piDatas == null) + throw new Exception ("Fetch data member not found in ItemTemplate: " + fetchMethodName); + miGetDatas = piDatas.GetGetMethod (); + if (miGetDatas == null) + throw new Exception ("Read only property for fetching data in ItemTemplate: " + fetchMethodName); + } + + il.Emit (OpCodes.Callvirt, miGetDatas); + } } } -- 2.47.3