/// <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; } } }
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 }