Exemplo n.º 1
0
        //data is on the stack
        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)
                {
                    FieldInfo fiDatas = dataType.GetField(fetchMethodName);
                    if (fiDatas == null)                    //and among fields
                    {
                        throw new Exception("Fetch data member not found in ItemTemplate: " + fetchMethodName);
                    }
                    il.Emit(OpCodes.Ldfld, fiDatas);
                    return;
                }
                miGetDatas = piDatas.GetGetMethod();
                if (miGetDatas == null)
                {
                    throw new Exception("Read only property for fetching data in ItemTemplate: " + fetchMethodName);
                }
            }

            il.Emit(OpCodes.Callvirt, miGetDatas);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Inits il generator, RootType must have been read first
        /// </summary>
        void InitEmitter()
        {
            dm = new DynamicMethod("dyn_instantiator",
                                   MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
                                   CallingConventions.Standard,
                                   typeof(void), new Type[] { typeof(object), typeof(Interface) }, RootType, true);

            il = dm.GetILGenerator(256);
            il.DeclareLocal(typeof(GraphicObject));
            il.Emit(OpCodes.Nop);
            //set local GraphicObject to root object passed as 1st argument
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Stloc_0);
            CompilerServices.emitSetCurInterface(il);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Try to find member by name in instance class or, if not found,
        /// in extension methods
        /// </summary>
        /// <returns>True if found, false otherwise</returns>
        /// <param name="_memberName">Member name to search for</param>
        public bool TryFindMember(string _memberName)
        {
            if (Instance == null)
            {
                return(false);
            }
            Type t = Instance.GetType();

            Member = t.GetMember(_memberName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).FirstOrDefault();

            #region search for extensions methods if member not found in type
            if (Member == null && !string.IsNullOrEmpty(_memberName))
            {
                Assembly a = Assembly.GetExecutingAssembly();
                Member = CompilerServices.GetExtensionMethods(a, t).Where(em => em.Name == _memberName).FirstOrDefault();
            }
            #endregion

            return(Member != null);
        }
Exemplo n.º 4
0
        protected void loadItem(object o, Group page, string _dataTest)
        {
            if (o == null)            //TODO:surely a threading sync problem
            {
                return;
            }
            GraphicObject g        = null;
            ItemTemplate  iTemp    = null;
            Type          dataType = o.GetType();
            string        itempKey = dataType.FullName;

            if (_dataTest != "TypeOf")
            {
                itempKey = getItempKey(dataType, o, _dataTest);
            }

            if (ItemTemplates.ContainsKey(itempKey))
            {
                iTemp = ItemTemplates [itempKey];
            }
            else
            {
                foreach (string it in ItemTemplates.Keys)
                {
                    Type t = CompilerServices.tryGetType(it);
                    if (t == null)
                    {
                        continue;
                    }
                    if (t.IsAssignableFrom(dataType))                       //TODO:types could be cached
                    {
                        iTemp = ItemTemplates [it];
                        break;
                    }
                }
                if (iTemp == null)
                {
                    iTemp = ItemTemplates ["default"];
                }
            }

            lock (IFace.LayoutMutex) {
                g = iTemp.CreateInstance();
                                #if DESIGN_MODE
                g.design_isTGItem = true;
                                #endif
                page.AddChild(g);
//				if (isPaged)
                g.LogicalParent = this;
                g.MouseDown    += itemClick;
            }

            if (iTemp.Expand != null && g is Expandable)
            {
                Expandable e = g as Expandable;
                e.Expand         += iTemp.Expand;
                e.GetIsExpandable = iTemp.HasSubItems;
            }

            g.DataSource = o;
        }
Exemplo n.º 5
0
		/// <summary> Loads the default values from XML attributes default </summary>
		public void loadDefaultValues()
		{
			#if DEBUG_LOAD
			Debug.WriteLine ("LoadDefValues for " + this.ToString ());
			#endif

			Type thisType = this.GetType ();

			if (!string.IsNullOrEmpty (Style)) {
				if (Interface.DefaultValuesLoader.ContainsKey (Style)) {
					Interface.DefaultValuesLoader [Style] (this);
					return;
				}
			} else {
				if (Interface.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
					Interface.DefaultValuesLoader [thisType.FullName] (this);
					return;
				} else if (!Interface.Styling.ContainsKey (thisType.FullName)) {
					if (Interface.DefaultValuesLoader.ContainsKey (thisType.Name)) {
						Interface.DefaultValuesLoader [thisType.Name] (this);
						return;
					}
				}
			}

			List<Style> styling = new List<Style>();

			//Search for a style matching :
			//1: Full class name, with full namespace
			//2: class name
			//3: style may have been registered with their ressource ID minus .style extention
			//   those files being placed in a Styles folder
			string styleKey = Style;
			if (!string.IsNullOrEmpty (Style)) {
				if (Interface.Styling.ContainsKey (Style)) {
					styling.Add (Interface.Styling [Style]);
				}
			}
			if (Interface.Styling.ContainsKey (thisType.FullName)) {
				styling.Add (Interface.Styling [thisType.FullName]);
				if (string.IsNullOrEmpty (styleKey))
					styleKey = thisType.FullName;
			}
			if (Interface.Styling.ContainsKey (thisType.Name)) {
				styling.Add (Interface.Styling [thisType.Name]);
				if (string.IsNullOrEmpty (styleKey))
					styleKey = thisType.Name;
			}

			if (string.IsNullOrEmpty (styleKey))
				styleKey = thisType.FullName;


			//Reflexion being very slow compared to dyn method or delegates,
			//I compile the initial values coded in the CustomAttribs of the class,
			//all other instance of this type would not longer use reflexion to init properly
			//but will fetch the  dynamic initialisation method compiled for this precise type
			//TODO:measure speed gain.
			#region Delfault values Loading dynamic compilation
			DynamicMethod dm = null;
			ILGenerator il = null;

			dm = new DynamicMethod("dyn_loadDefValues",
				MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
				CallingConventions.Standard,
				typeof(void),new Type[] {CompilerServices.TObject},thisType,true);

			il = dm.GetILGenerator(256);
			il.DeclareLocal(CompilerServices.TObject);
			il.Emit(OpCodes.Nop);
			//set local GraphicObject to root object passed as 1st argument
			il.Emit (OpCodes.Ldarg_0);
			il.Emit (OpCodes.Stloc_0);

			foreach (EventInfo ei in thisType.GetEvents(BindingFlags.Public | BindingFlags.Instance)) {
				string expression;
				if (!getDefaultEvent(ei, styling, out expression))
					continue;
				//TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it.
				foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) {
					string trimed = exp.Trim();
					if (trimed.StartsWith ("{", StringComparison.OrdinalIgnoreCase)){
						il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add

						//push eventInfo as 1st arg of compile
						il.Emit (OpCodes.Ldloc_0);
						il.Emit (OpCodes.Call, CompilerServices.miGetType);
						il.Emit (OpCodes.Ldstr, ei.Name);//push event name
						il.Emit (OpCodes.Call, CompilerServices.miGetEvent);
						//push expression as 2nd arg of compile
						il.Emit (OpCodes.Ldstr, trimed.Substring (1, trimed.Length - 2));
						//push null as 3rd arg, currentNode, not known when instanciing
						il.Emit (OpCodes.Ldnull);
						il.Emit (OpCodes.Callvirt, CompilerServices.miCompileDynEventHandler);
						il.Emit (OpCodes.Castclass, ei.EventHandlerType);
						il.Emit (OpCodes.Callvirt, ei.AddMethod);
					}else
						Debug.WriteLine("error in styling, event not handled : " + trimed);
				}
			}

			foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
				if (pi.GetSetMethod () == null)
					continue;
				object defaultValue;
				if (!getDefaultValue (pi, styling, out defaultValue))
					continue;

				CompilerServices.EmitSetValue (il, pi, defaultValue);
			}
			il.Emit(OpCodes.Ret);
			#endregion

			try {
				Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
				Interface.DefaultValuesLoader[styleKey] (this);
			} catch (Exception ex) {
				throw new Exception ("Error applying style <" + styleKey + ">:", ex);
			}
		}
Exemplo n.º 6
0
        public static void ResolveBindings(List <Binding> Bindings)
        {
            if (Bindings == null)
            {
                return;
            }
            if (Bindings.Count == 0)
            {
                return;
            }
            //#if DEBUG_BINDING
            //			Debug.WriteLine ("Resolve Bindings => " + this.ToString ());
            //#endif
            //grouped bindings by Instance of Source
            Dictionary <object, List <Binding> > resolved = new Dictionary <object, List <Binding> > ();

            foreach (Binding b in Bindings)
            {
                if (b.Resolved)
                {
                    continue;
                }
                if (b.Source.Member.MemberType == MemberTypes.Event)
                {
                    if (b.Expression.StartsWith("{"))
                    {
                        CompilerServices.CompileEventSource(b);
                        continue;
                    }
                    if (!b.TryFindTarget())
                    {
                        continue;
                    }
                    //register handler for event
                    if (b.Target.Method == null)
                    {
                        Debug.WriteLine("\tError: Handler Method not found: " + b.ToString());
                        continue;
                    }
                    try {
                        MethodInfo addHandler = b.Source.Event.GetAddMethod();
                        Delegate   del        = Delegate.CreateDelegate(b.Source.Event.EventHandlerType, b.Target.Instance, b.Target.Method);
                        addHandler.Invoke(b.Source.Instance, new object [] { del });

#if DEBUG_BINDING
                        Debug.WriteLine("\tHandler binded => " + b.ToString());
#endif
                        b.Resolved = true;
                    } catch (Exception ex) {
                        Debug.WriteLine("\tERROR: " + ex.ToString());
                    }
                    continue;
                }

                if (!b.TryFindTarget())
                {
                    continue;
                }

                //group Bindings by target instanceq
                List <Binding> bindings = null;
                if (!resolved.TryGetValue(b.Target.Instance, out bindings))
                {
                    bindings = new List <Binding> ();
                    resolved [b.Target.Instance] = bindings;
                }
                bindings.Add(b);
                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
            //IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ());
            foreach (List <Binding> grouped in resolved.Values)
            {
                int  i           = 0;
                Type source_Type = grouped [0].Target.Instance.GetType();

                DynamicMethod dm = null;
                ILGenerator   il = null;

                System.Reflection.Emit.Label [] jumpTable = null;
                System.Reflection.Emit.Label    endMethod = new System.Reflection.Emit.Label();

                #region Retrieve EventHandler parameter type
                //EventInfo ei = targetType.GetEvent ("ValueChanged");
                //no dynamic update if ValueChanged interface is not implemented
                if (source_Type.GetInterfaces().Contains(typeof(IValueChange)))
                {
                    dm = new DynamicMethod(grouped [0].CreateNewDynMethodId(),
                                           MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
                                           CallingConventions.Standard,
                                           typeof(void),
                                           args,
                                           target_Type, true);

                    il = dm.GetILGenerator(256);

                    endMethod = il.DefineLabel();
                    jumpTable = new System.Reflection.Emit.Label [grouped.Count];
                    for (i = 0; i < grouped.Count; i++)
                    {
                        jumpTable [i] = il.DefineLabel();
                    }
                    il.DeclareLocal(typeof(string));
                    il.DeclareLocal(typeof(object));

                    il.Emit(OpCodes.Nop);
                    il.Emit(OpCodes.Ldarg_0);
                    //il.Emit(OpCodes.Isinst, sourceType);
                    //push new value onto stack
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Ldfld, fiNewValue);
                    il.Emit(OpCodes.Stloc_1);
                    //push name
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Ldfld, fiMbName);
                    il.Emit(OpCodes.Stloc_0);
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Brfalse, endMethod);
                }
                #endregion

                i = 0;
                foreach (Binding b in grouped)
                {
                    #region initialize target with actual value
                    object targetValue = null;
                    if (b.Target.Member != null)
                    {
                        if (b.Target.Member.MemberType == MemberTypes.Property)
                        {
                            targetValue = b.Target.Property.GetGetMethod().Invoke(b.Target.Instance, null);
                        }
                        else if (b.Target.Member.MemberType == MemberTypes.Field)
                        {
                            targetValue = b.Target.Field.GetValue(b.Target.Instance);
                        }
                        else if (b.Target.Member.MemberType == MemberTypes.Method)
                        {
                            MethodInfo mthSrc = b.Target.Method;
                            if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))
                            {
                                targetValue = mthSrc.Invoke(null, new object [] { b.Target.Instance });
                            }
                            else
                            {
                                targetValue = mthSrc.Invoke(b.Target.Instance, null);
                            }
                        }
                        else
                        {
                            throw new Exception("unandled source member type for binding");
                        }
                    }
                    else if (string.IsNullOrEmpty(b.Expression))
                    {
                        targetValue = grouped [0].Target.Instance;                        //empty binding exp=> bound to target object by default
                    }
                    //TODO: handle other dest type conversions
                    if (b.Source.Property.PropertyType == typeof(string))
                    {
                        if (targetValue == null)
                        {
                            //set default value
                        }
                        else
                        {
                            targetValue = targetValue.ToString();
                        }
                    }
                    try {
                        if (targetValue != null)
                        {
                            b.Source.Property.GetSetMethod().Invoke
                                (b.Source.Instance, new object [] { b.Source.Property.PropertyType.Cast(targetValue) });
                        }
                        else
                        {
                            b.Source.Property.GetSetMethod().Invoke
                                (b.Source.Instance, new object [] { targetValue });
                        }
                    } catch (Exception ex) {
                        Debug.WriteLine(ex.ToString());
                    }
                    #endregion

                    //if no dyn update, skip jump table
                    if (il == null)
                    {
                        continue;
                    }

                    il.Emit(OpCodes.Ldloc_0);
                    if (b.Target.Member != null)
                    {
                        il.Emit(OpCodes.Ldstr, b.Target.Member.Name);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldstr, b.Expression.Split('/').LastOrDefault());
                    }
                    il.Emit(OpCodes.Ldc_I4_4);                     //StringComparison.Ordinal
                    il.Emit(OpCodes.Callvirt, stringEquals);
                    il.Emit(OpCodes.Brtrue, jumpTable [i]);
                    i++;
                }

                if (il == null)
                {
                    continue;
                }

                il.Emit(OpCodes.Br, endMethod);

                i = 0;
                foreach (Binding b in grouped)
                {
                    il.MarkLabel(jumpTable [i]);


                    //load 2 times to check first for null
                    il.Emit(OpCodes.Ldloc_1);
                    il.Emit(OpCodes.Ldloc_1);

                    System.Reflection.Emit.Label labSetValue = il.DefineLabel();
                    il.Emit(OpCodes.Brtrue, labSetValue);
                    //if null
                    il.Emit(OpCodes.Unbox_Any, b.Source.Property.PropertyType);
                    il.Emit(OpCodes.Callvirt, b.Source.Property.GetSetMethod());
                    il.Emit(OpCodes.Br, endMethod);

                    il.MarkLabel(labSetValue);
                    //new value not null

                    //by default, source value type is deducted from target member type to allow
                    //memberless binding, if targetMember exists, it will be used to determine target
                    //value type for conversion
                    Type sourceValueType = b.Source.Property.PropertyType;
                    if (b.Target.Member != null)
                    {
                        if (b.Target.Member.MemberType == MemberTypes.Property)
                        {
                            sourceValueType = b.Target.Property.PropertyType;
                        }
                        else if (b.Target.Member.MemberType == MemberTypes.Field)
                        {
                            sourceValueType = b.Target.Field.FieldType;
                        }
                        else
                        {
                            throw new Exception("unhandle target member type in binding");
                        }
                    }



                    if (b.Source.Property.PropertyType == typeof(string))
                    {
                        MemberReference tostring = new MemberReference(b.Source.Instance);
                        if (!tostring.TryFindMember("ToString"))
                        {
                            throw new Exception("ToString method not found");
                        }
                        il.Emit(OpCodes.Callvirt, tostring.Method);
                    }
                    else if (!sourceValueType.IsValueType)
                    {
                        il.Emit(OpCodes.Castclass, sourceValueType);
                    }
                    else if (b.Source.Property.PropertyType != sourceValueType)
                    {
                        il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod(b.Source.Property.PropertyType));
                    }
                    else
                    {
                        il.Emit(OpCodes.Unbox_Any, b.Source.Property.PropertyType);
                    }

                    il.Emit(OpCodes.Callvirt, b.Source.Property.GetSetMethod());

                    //il.BeginCatchBlock (typeof (Exception));
                    //il.Emit (OpCodes.Pop);
                    //il.EndExceptionBlock ();

                    il.Emit(OpCodes.Br, endMethod);
                    i++;
                }
                il.MarkLabel(endMethod);
                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 });
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Parse child node an generate corresponding msil
        /// </summary>
        void readChildren(IMLReader reader, Type crowType, bool templateLoading = false)
        {
            MethodInfo miAddChild    = null;
            bool       endTagReached = false;

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.EndElement:
                    endTagReached = true;
                    break;

                case XmlNodeType.Element:
                    //Templates
                    if (reader.Name == "Template" ||
                        reader.Name == "ItemTemplate")
                    {
                        reader.Skip();
                        continue;
                    }

                    if (miAddChild == null)
                    {
                        if (typeof(Group).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(Group).GetMethod("AddChild");
                        }
                        else if (typeof(Container).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(Container).GetMethod("SetChild");
                        }
                        else if (typeof(TemplatedContainer).IsAssignableFrom(crowType) && !templateLoading)
                        {
                            miAddChild = typeof(TemplatedContainer).GetProperty("Content").GetSetMethod();
                        }
                        else if (typeof(TemplatedGroup).IsAssignableFrom(crowType) && !templateLoading)
                        {
                            miAddChild = typeof(TemplatedGroup).GetMethod("AddItem",
                                                                          BindingFlags.Instance | BindingFlags.Public);
                        }
                        else if (typeof(TemplatedControl).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(TemplatedControl).GetMethod("loadTemplate",
                                                                            BindingFlags.Instance | BindingFlags.NonPublic);
                        }
                        else if (typeof(PrivateContainer).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(PrivateContainer).GetMethod("SetChild",
                                                                            BindingFlags.Instance | BindingFlags.NonPublic);
                        }
                    }
                    //push current instance on stack for parenting
                    //loc_0 will be used for child
                    reader.il.Emit(OpCodes.Ldloc_0);

                    Type t = Type.GetType("Crow." + reader.Name);
                    if (t == null)
                    {
                        Assembly a = Assembly.GetEntryAssembly();
                        foreach (Type expT in a.GetExportedTypes())
                        {
                            if (expT.Name == reader.Name)
                            {
                                t = expT;
                            }
                        }
                    }
                    if (t == null)
                    {
                        throw new Exception(reader.Name + " type not found");
                    }

                    reader.il.Emit(OpCodes.Newobj, t.GetConstructors() [0]); //TODO:search parameterless ctor
                    reader.il.Emit(OpCodes.Stloc_0);                         //child is now loc_0
                    CompilerServices.emitSetCurInterface(il);

                    reader.emitLoader(t);

                    reader.il.Emit(OpCodes.Ldloc_0);                     //load child on stack for parenting
                    if (miAddChild == null)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                    reader.il.Emit(OpCodes.Callvirt, miAddChild);
                    reader.il.Emit(OpCodes.Stloc_0);                     //reset local to current go
                    reader.il.Emit(OpCodes.Ldloc_0);                     //save current go onto the stack if child has to be added
                    break;
                }
                if (endTagReached)
                {
                    break;
                }
            }
        }
Exemplo n.º 8
0
        void emitLoader(Type crowType)
        {
            string tmpXml = ReadOuterXml();

            il.Emit(OpCodes.Ldloc_0);             //save current go onto the stack if child has to be added

            #region Template and ItemTemplates loading
            if (typeof(TemplatedControl).IsAssignableFrom(crowType))
            {
                //if its a template, first read template elements
                using (IMLReader reader = new IMLReader(il, tmpXml)) {
                    string templatePath = reader.GetAttribute("Template");
                    //string itemTemplatePath = reader.GetAttribute ("ItemTemplate");

                    List <string[]> itemTemplateIds = new List <string[]> ();
                    bool            inlineTemplate  = false;
                    reader.Read();
                    int depth = reader.Depth + 1;
                    while (reader.Read())
                    {
                        if (!reader.IsStartElement() || reader.Depth > depth)
                        {
                            continue;
                        }
                        if (reader.Name == "Template")
                        {
                            inlineTemplate = true;
                            reader.Read();

                            readChildren(reader, crowType, true);
                        }
                        else if (reader.Name == "ItemTemplate")
                        {
                            string dataType = "default", datas = "", path = "";
                            while (reader.MoveToNextAttribute())
                            {
                                if (reader.Name == "DataType")
                                {
                                    dataType = reader.Value;
                                }
                                else if (reader.Name == "Data")
                                {
                                    datas = reader.Value;
                                }
                                else if (reader.Name == "Path")
                                {
                                    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 });
                            }
                        }
                    }

                    if (!inlineTemplate)
                    {
                        reader.il.Emit(OpCodes.Ldloc_0);                         //Load  this templateControl ref
                        if (string.IsNullOrEmpty(templatePath))
                        {
                            reader.il.Emit(OpCodes.Ldnull);                             //default template loading
                        }
                        else
                        {
                            reader.il.Emit(OpCodes.Ldarg_1);                             //load currentInterface
                            reader.il.Emit(OpCodes.Ldstr, templatePath);                 //Load template path string
                            reader.il.Emit(OpCodes.Callvirt,                             //call Interface.Load(path)
                                           typeof(Interface).GetMethod("Load", BindingFlags.Instance | BindingFlags.Public));
                        }
                        reader.il.Emit(OpCodes.Callvirt,                         //load template
                                       crowType.GetMethod("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic));
                    }
                    foreach (string[] iTempId in itemTemplateIds)
                    {
                        reader.il.Emit(OpCodes.Ldloc_0);                      //load TempControl ref
                        reader.il.Emit(OpCodes.Ldfld,                         //load ItemTemplates dic field
                                       typeof(TemplatedGroup).GetField("ItemTemplates"));
                        reader.il.Emit(OpCodes.Ldstr, iTempId[0]);            //load key
                        reader.il.Emit(OpCodes.Ldstr, iTempId[1]);            //load value
                        reader.il.Emit(OpCodes.Callvirt,
                                       typeof(Interface).GetMethod("GetItemTemplate"));
                        reader.il.Emit(OpCodes.Callvirt,
                                       typeof(Dictionary <string, ItemTemplate>).GetMethod("set_Item",
                                                                                           new Type[] { typeof(string), typeof(ItemTemplate) }));

                        if (!string.IsNullOrEmpty(iTempId [2]))
                        {
                            //expand delegate creation
                            reader.il.Emit(OpCodes.Ldloc_0);                          //load TempControl ref
                            reader.il.Emit(OpCodes.Ldfld,                             //load ItemTemplates dic field
                                           typeof(TemplatedGroup).GetField("ItemTemplates"));
                            reader.il.Emit(OpCodes.Ldstr, iTempId [0]);               //load key
                            reader.il.Emit(OpCodes.Callvirt,
                                           typeof(Dictionary <string, ItemTemplate>).GetMethod("get_Item",
                                                                                               new Type[] { typeof(string) }));
                            reader.il.Emit(OpCodes.Ldloc_0);                             //load root of treeView
                            reader.il.Emit(OpCodes.Callvirt,
                                           typeof(ItemTemplate).GetMethod("CreateExpandDelegate"));
                        }
                    }
                }
            }
            #endregion

            using (IMLReader reader = new IMLReader(il, tmpXml)){
                reader.Read();

                #region Styling and default values loading
                if (reader.HasAttributes)
                {
                    string style = reader.GetAttribute("Style");
                    if (!string.IsNullOrEmpty(style))
                    {
                        PropertyInfo pi = crowType.GetProperty("Style");
                        CompilerServices.EmitSetValue(reader.il, pi, style);
                    }
                }
                reader.il.Emit(OpCodes.Ldloc_0);
                reader.il.Emit(OpCodes.Callvirt, typeof(GraphicObject).GetMethod("loadDefaultValues"));
                #endregion

                #region Attributes reading
                if (reader.HasAttributes)
                {
                    MethodInfo miAddBinding = typeof(GraphicObject).GetMethod("BindMember");

                    while (reader.MoveToNextAttribute())
                    {
                        if (reader.Name == "Style")
                        {
                            continue;
                        }

                        MemberInfo mi = crowType.GetMember(reader.Name).FirstOrDefault();
                        if (mi == null)
                        {
                            throw new Exception("Member '" + reader.Name + "' not found in " + crowType.Name);
                        }
                        if (mi.MemberType == MemberTypes.Event)
                        {
                            CompilerServices.emitBindingCreation(reader.il, reader.Name, reader.Value);
                            continue;
                        }
                        PropertyInfo pi = mi as PropertyInfo;
                        if (pi == null)
                        {
                            throw new Exception("Member '" + reader.Name + "' not found in " + crowType.Name);
                        }

                        if (reader.Value.StartsWith("{"))
                        {
                            CompilerServices.emitBindingCreation(reader.il, reader.Name, reader.Value.Substring(1, reader.Value.Length - 2));
                        }
                        else
                        {
                            CompilerServices.EmitSetValue(reader.il, pi, reader.Value);
                        }
                    }
                    reader.MoveToElement();
                }
                #endregion

                if (reader.IsEmptyElement)
                {
                    reader.il.Emit(OpCodes.Pop);                     //pop saved ref to current object
                    return;
                }

                readChildren(reader, crowType);
            }
            il.Emit(OpCodes.Pop);             //pop saved ref to current object
        }
Exemplo n.º 9
0
        /// <summary>
        /// check type of current object on the stack and convert to dest type,
        /// use loc_0 so store it as object!!!
        /// </summary>
        internal static void emitConvert(ILGenerator il, Type dstType)
        {
            System.Reflection.Emit.Label endConvert = il.DefineLabel();
            System.Reflection.Emit.Label convert    = il.DefineLabel();

            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Isinst, dstType);
            il.Emit(OpCodes.Brfalse, convert);

            if (dstType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, dstType);
            }
            else
            {
                il.Emit(OpCodes.Isinst, dstType);
            }
            il.Emit(OpCodes.Br, endConvert);

            il.MarkLabel(convert);

            if (dstType == typeof(string))
            {
                System.Reflection.Emit.Label emitNullStr = il.DefineLabel();
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brfalse, emitNullStr);
                il.Emit(OpCodes.Callvirt, CompilerServices.miObjToString);
                il.Emit(OpCodes.Br, endConvert);
                il.MarkLabel(emitNullStr);
                il.Emit(OpCodes.Pop);                 //remove null string from stack
                il.Emit(OpCodes.Ldstr, "");           //replace with empty string
            }
            else if (dstType.IsPrimitive)
            {
                //il.Emit (OpCodes.Unbox_Any, dstType);
                il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod(dstType));
            }
            else if (dstType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, dstType);
            }
            else
            {
                il.Emit(OpCodes.Stloc_0);                  //save orig value in loc0
                //first check if not null
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brfalse, endConvert);
                il.Emit(OpCodes.Callvirt, miGetType);
                il.Emit(OpCodes.Ldtoken, dstType);                 //push destination property type for testing
                il.Emit(OpCodes.Call, CompilerServices.miGetTypeFromHandle);
                il.Emit(OpCodes.Call, miGetImplOp);
                il.Emit(OpCodes.Dup);
                convert = il.DefineLabel();
                il.Emit(OpCodes.Brtrue, convert);
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Isinst, dstType);
                il.Emit(OpCodes.Br, endConvert);

                il.MarkLabel(convert);
                il.Emit(OpCodes.Ldnull);                 //null instance for invoke
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Newarr, CompilerServices.TObject);
                il.Emit(OpCodes.Dup);                              //duplicate the array ref
                il.Emit(OpCodes.Ldc_I4_0);                         //push the index 0
                il.Emit(OpCodes.Ldloc_0);                          //push the orig value to convert
                il.Emit(OpCodes.Stelem, CompilerServices.TObject); //set the array element at index 0
                il.Emit(OpCodes.Callvirt, miMIInvoke);
            }

            il.MarkLabel(endConvert);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Emit MSIL for conversion from orig type to dest type
        /// </summary>
        internal static void emitConvert(ILGenerator il, Type origType, Type destType)
        {
            if (destType == CompilerServices.TObject)
            {
                return;
            }
            if (destType == typeof(string))
            {
                System.Reflection.Emit.Label emitNullStr = il.DefineLabel();
                System.Reflection.Emit.Label endConvert  = il.DefineLabel();
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brfalse, emitNullStr);
                il.Emit(OpCodes.Callvirt, CompilerServices.miObjToString);
                il.Emit(OpCodes.Br, endConvert);
                il.MarkLabel(emitNullStr);
                il.Emit(OpCodes.Pop);                 //remove null string from stack
                il.Emit(OpCodes.Ldstr, "");           //replace with empty string
                il.MarkLabel(endConvert);
            }
            else if (origType.IsValueType)
            {
                if (destType != origType)
                {
                    MethodInfo miIO = getImplicitOp(origType, destType);
                    if (miIO != null)
                    {
                        System.Reflection.Emit.Label emitCreateDefault = il.DefineLabel();
                        System.Reflection.Emit.Label emitContinue      = il.DefineLabel();
                        LocalBuilder lbStruct = il.DeclareLocal(origType);
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brfalse, emitCreateDefault);
                        il.Emit(OpCodes.Unbox_Any, origType);
                        il.Emit(OpCodes.Br, emitContinue);
                        il.MarkLabel(emitCreateDefault);
                        il.Emit(OpCodes.Pop);                         //pop null value
                        il.Emit(OpCodes.Ldloca, lbStruct);
                        il.Emit(OpCodes.Initobj, origType);
                        il.Emit(OpCodes.Ldloc, lbStruct);
                        il.MarkLabel(emitContinue);
                        il.Emit(OpCodes.Call, miIO);
                    }
                    else
                    {
                        il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod(destType));
                    }
                }
                else
                {
                    il.Emit(OpCodes.Unbox_Any, destType);                     //TODO:double check this
                }
            }
            else
            {
                if (destType.IsAssignableFrom(origType))
                {
                    il.Emit(OpCodes.Castclass, destType);
                }
                else
                {
                    //implicit conversion can't be defined from or to object base class,
                    //so we will check if object underlying type is one of the implicit converter of destType
                    if (origType == TObject)                      //test all implicit converter to destType on obj
                    {
                        System.Reflection.Emit.Label emitTestNextImpOp;
                        System.Reflection.Emit.Label emitImpOpFound = il.DefineLabel();
                        foreach (MethodInfo mi in destType.GetMethods(BindingFlags.Public | BindingFlags.Static))
                        {
                            if (mi.Name == "op_Implicit")
                            {
                                if (mi.GetParameters() [0].ParameterType == destType)
                                {
                                    continue;
                                }
                                emitTestNextImpOp = il.DefineLabel();
                                il.Emit(OpCodes.Dup);
                                il.Emit(OpCodes.Isinst, mi.GetParameters() [0].ParameterType);
                                il.Emit(OpCodes.Brfalse, emitTestNextImpOp);
                                if (mi.GetParameters() [0].ParameterType.IsValueType)
                                {
                                    il.Emit(OpCodes.Unbox_Any, mi.GetParameters() [0].ParameterType);
                                }
                                else
                                {
                                    il.Emit(OpCodes.Isinst, mi.GetParameters() [0].ParameterType);
                                }

                                il.Emit(OpCodes.Call, mi);
                                il.Emit(OpCodes.Br, emitImpOpFound);

                                il.MarkLabel(emitTestNextImpOp);
                            }
                        }
                        //il.Emit (OpCodes.Br, emitImpOpNotFound);
                        il.MarkLabel(emitImpOpFound);
                    }
                    else                        //search both orig and dest types for implicit operators
                    {
                        MethodInfo miIO = getImplicitOp(origType, destType);
                        if (miIO != null)
                        {
                            il.Emit(OpCodes.Call, miIO);
                        }
                    }
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Creates the expand delegate.
        /// </summary>
        /// <param name="host">Host.</param>
        public void CreateExpandDelegate(TemplatedGroup host)
        {
            Type dataType = null;

            //if (host.DataTest == "TypeOf"){
            dataType = CompilerServices.tryGetType(strDataType);
//				if (dataType == null) {
//					Debug.WriteLine ("ItemTemplate error: DataType not found: {0}.", strDataType);
//					return;
//				}
//			}
            Type tmpGrpType = typeof(TemplatedGroup);
            Type evtType    = typeof(EventHandler);

            //PropertyInfo piData = tmpGrpType.GetProperty ("Data");

            MethodInfo evtInvoke = evtType.GetMethod("Invoke");

            ParameterInfo [] evtParams       = evtInvoke.GetParameters();
            Type             handlerArgsType = evtParams [1].ParameterType;

            Type [] args = { CompilerServices.TObject, CompilerServices.TObject, handlerArgsType };

            #region Expand dyn meth
            //DM is bound to templatedGroup root (arg0)
            //arg1 is the sender of the expand event
            DynamicMethod dm = new DynamicMethod("dyn_expand_" + fetchMethodName,
                                                 typeof(void), args, typeof(TemplatedGroup), true);

            System.Reflection.Emit.Label gotoEnd;
            System.Reflection.Emit.Label ifDataIsNull;
            System.Reflection.Emit.Label gotoItemsContainerNotFound;

            ILGenerator il = dm.GetILGenerator(256);
            il.DeclareLocal(typeof(GraphicObject));

            gotoEnd      = il.DefineLabel();
            ifDataIsNull = il.DefineLabel();
            gotoItemsContainerNotFound = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_1);                 //load sender of expand event
            il.Emit(OpCodes.Ldstr, "ItemsContainer"); //load name to find
            il.Emit(OpCodes.Callvirt, CompilerServices.miFindByName);
            il.Emit(OpCodes.Stloc_0);                 //save items container as loc0

            //ensure ItemsContainer is not null
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Brfalse, gotoItemsContainerNotFound);

            //check that node is not already expanded
            il.Emit(OpCodes.Ldarg_0);             //push root TemplatedGroup into the stack
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, CompilerServices.miIsAlreadyExpanded);
            il.Emit(OpCodes.Brtrue, gotoEnd);
//			il.Emit (OpCodes.Ldloc_0);
//			il.Emit (OpCodes.Callvirt, piData.GetGetMethod ());
//			il.Emit (OpCodes.Brfalse, ifDataIsNull);
//			il.Emit (OpCodes.Br, gotoEnd);

//			il.MarkLabel(ifDataIsNull);

            //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes?
//			FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates");
//			il.Emit (OpCodes.Ldloc_0);
//			il.Emit (OpCodes.Ldarg_0);
//			il.Emit (OpCodes.Ldfld, fiTemplates);
//			il.Emit (OpCodes.Stfld, fiTemplates);

            //call 'fetchMethodName' from the dataSource to build the sub nodes list
            //il.Emit (OpCodes.Ldarg_0);//load root templatedGroop

            il.Emit(OpCodes.Ldarg_0);                                    //push root TemplatedGroup into the stack
            il.Emit(OpCodes.Ldarg_1);                                    //load sender node of expand
            il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); //get the dataSource of the sender



            if (fetchMethodName != "self")              //special keyword self allows the use of recurent list<<<
            {
                if (dataType == null)
                {
                    //dataTest was not = TypeOF, so we have to get the type of data
                    //dynamically and fetch

                    il.Emit(OpCodes.Ldstr, fetchMethodName);
                    il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch);
                }
                else
                {
                    emitGetSubData(il, dataType);
                }
            }
            //set 'return' from the fetch method as 'data' of the list
            //il.Emit (OpCodes.Callvirt, piData.GetSetMethod ());
            il.Emit(OpCodes.Ldloc_0);             //load second arg of loadPage, the sender node
            il.Emit(OpCodes.Ldstr, dataTest);     //load 3rd arg, dataTest kind on subitems
            il.Emit(OpCodes.Callvirt, CompilerServices.miLoadPage);
            il.Emit(OpCodes.Br, gotoEnd);

            il.MarkLabel(gotoItemsContainerNotFound);
            il.EmitWriteLine("ItemsContainer not found in ItemTemplate for " + host.ToString());


            il.MarkLabel(gotoEnd);
            il.Emit(OpCodes.Ret);

            Expand = (EventHandler)dm.CreateDelegate(evtType, host);
            #endregion

            #region Items counting dyn method
            //dm is unbound, arg0 is instance of Item container to expand
            dm = new DynamicMethod("dyn_count_" + fetchMethodName,
                                   typeof(bool), new Type[] { CompilerServices.TObject }, true);
            il = dm.GetILGenerator(256);

            //get the dataSource of the arg0
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource);

            if (fetchMethodName != "self")              //special keyword self allows the use of recurent list<<<
            {
                if (dataType == null)
                {
                    //dataTest was not = TypeOF, so we have to get the type of data
                    //dynamically and fetch

                    il.Emit(OpCodes.Ldstr, fetchMethodName);
                    il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch);
                }
                else
                {
                    emitGetSubData(il, dataType);
                }
            }

            il.Emit(OpCodes.Callvirt, CompilerServices.miGetColCount);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Cgt);
            il.Emit(OpCodes.Ret);
            HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate(typeof(BooleanTestOnInstance));
            #endregion
        }