From e93ebc73fdf0e09b3391336a5697794593f5669e Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Tue, 8 Nov 2016 16:39:31 +0100 Subject: [PATCH] IML parser wip --- Crow.csproj | 429 +++++++++++++++++------ src/CompilerServices/CompilerServices.cs | 14 +- src/IML/Context.cs | 43 +++ src/IML/MemberAddress.cs | 57 +++ src/IML/Node.cs | 90 +++++ src/IML/NodeAddress.cs | 42 +++ src/IML/Reader.cs | 234 ++++--------- 7 files changed, 645 insertions(+), 264 deletions(-) create mode 100644 src/IML/Context.cs create mode 100644 src/IML/MemberAddress.cs create mode 100644 src/IML/Node.cs create mode 100644 src/IML/NodeAddress.cs diff --git a/Crow.csproj b/Crow.csproj index a4b6a0c6..147537f4 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -39,111 +39,325 @@ __linux__;MEASURE_TIME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -286,9 +500,12 @@ - + + + PreserveNewest + diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 48f95a8a..d8f113e2 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -27,6 +27,15 @@ namespace Crow GetMethod ("get_Item", new Type[] { typeof(string) }); public static FieldInfo fldItemTemplates = typeof(TemplatedGroup).GetField("ItemTemplates"); public static MethodInfo miCreateExpDel = typeof(ItemTemplate).GetMethod ("CreateExpandDelegate"); + public static MethodInfo miLoadDefaultVals = typeof (GraphicObject).GetMethod ("loadDefaultValues"); + public static PropertyInfo piStyle = typeof (GraphicObject).GetProperty ("Style"); + #region tree handling methods + internal static MethodInfo miSetChild = typeof (Container).GetMethod ("SetChild"); + internal static MethodInfo miAddChild = typeof (Group).GetMethod ("AddChild"); + internal static MethodInfo miLoadTmp = typeof (TemplatedControl).GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic); + internal static MethodInfo miSetContent = typeof (TemplatedContainer).GetProperty ("Content").GetSetMethod (); + internal static MethodInfo miAddItem = typeof (TemplatedGroup).GetMethod ("AddItem", BindingFlags.Instance | BindingFlags.Public); + #endregion #region ValueChange Reflexion member info static EventInfo eiValueChange = typeof (IValueChange).GetEvent ("ValueChanged"); @@ -37,7 +46,10 @@ namespace Crow static MethodInfo miValueChangeAdd = eiValueChange.GetAddMethod (); #endregion - + /// + /// Loc0 is the current graphic object and arg1 of loader is the current interface + /// + /// Il. public static void emitSetCurInterface(ILGenerator il){ il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Ldarg_1); diff --git a/src/IML/Context.cs b/src/IML/Context.cs new file mode 100644 index 00000000..2b505e06 --- /dev/null +++ b/src/IML/Context.cs @@ -0,0 +1,43 @@ +// +// Context.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using System.Reflection.Emit; + +namespace Crow.IML +{ + /// + /// Context while parsing IML + /// + public class Context + { + public ILGenerator il = null; + //public SubNodeType curSubNodeType; + public Stack nodesStack = new Stack (); + + public Dictionary Names = new Dictionary (); + public Dictionary> PropertyBindings = new Dictionary> (); + + public Context () + { + } + } +} \ No newline at end of file diff --git a/src/IML/MemberAddress.cs b/src/IML/MemberAddress.cs new file mode 100644 index 00000000..85a346e4 --- /dev/null +++ b/src/IML/MemberAddress.cs @@ -0,0 +1,57 @@ +// +// MemberAddress.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace Crow.IML +{ + /// + /// Address member of a node + /// + public struct MemberAddress + { + public NodeAddress Address; + public string Name; + + public MemberAddress (NodeAddress _address, string _member) + { + Address = _address; + Name = _member; + } + + #region Equality Compare + public override bool Equals (object obj) + { + return obj is MemberAddress && this == (MemberAddress)obj; + } + public override int GetHashCode () + { + return Address.GetHashCode () ^ Name.GetHashCode (); + } + public static bool operator == (MemberAddress x, MemberAddress y) + { + return x.Address == y.Address && x.Name == y.Name; + } + public static bool operator != (MemberAddress x, MemberAddress y) + { + return !(x == y); + } + #endregion + } +} diff --git a/src/IML/Node.cs b/src/IML/Node.cs new file mode 100644 index 00000000..9bc8f82a --- /dev/null +++ b/src/IML/Node.cs @@ -0,0 +1,90 @@ +// +// Node.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Reflection; + +namespace Crow.IML +{ + /// + /// IML Node are the elements of the interface XML, + /// + public class Node + { + public Type CrowType; + /// + /// Indexer for group child, -1 for template + /// + public int Index; + + public Node (Type crowType, int _index = 0) + { + CrowType = crowType; + Index = _index; + } + + #region Equality Compare + public override bool Equals (object obj) + { + return obj is Node && this == (Node)obj; + } + public override int GetHashCode () + { + return CrowType.GetHashCode () ^ Index.GetHashCode (); + } + public static bool operator == (Node x, Node y) + { + return x.CrowType == y.CrowType && x.Index == y.Index; + } + public static bool operator != (Node x, Node y) + { + return !(x == y); + } + #endregion + + public bool IsTemplate { + get { return typeof (TemplatedControl).IsAssignableFrom (CrowType) && Index == 0; } + } + public MethodInfo AddMethod { + get { + if (typeof (Group).IsAssignableFrom (CrowType)) + return CompilerServices.miAddChild; + if (typeof (Container).IsAssignableFrom (CrowType)) + return CompilerServices.miSetChild; + if (typeof (TemplatedContainer).IsAssignableFrom (CrowType)) + return Index == 0 ? CompilerServices.miLoadTmp : CompilerServices.miSetContent; + if (typeof (TemplatedGroup).IsAssignableFrom (CrowType)) + return Index == 0 ? CompilerServices.miLoadTmp : CompilerServices.miAddItem; + if (typeof (TemplatedControl).IsAssignableFrom (CrowType)) + return CompilerServices.miLoadTmp; + return null; + } + } + + public static implicit operator string (Node sn) + { + return sn.ToString (); + } + public override string ToString () + { + return string.Format ("{0}.{1}", CrowType.FullName, Index); + } + } +} diff --git a/src/IML/NodeAddress.cs b/src/IML/NodeAddress.cs new file mode 100644 index 00000000..4b906975 --- /dev/null +++ b/src/IML/NodeAddress.cs @@ -0,0 +1,42 @@ +// +// NodeAddress.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Crow.IML +{ + public class NodeAddress : List + { + public override bool Equals (object obj) + { + return obj is NodeAddress && this == obj as NodeAddress; + } + public static bool operator == (NodeAddress x, NodeAddress y) + { + return x.SequenceEqual (y); + } + public static bool operator != (NodeAddress x, NodeAddress y) + { + return !(x == y); + } + } +} diff --git a/src/IML/Reader.cs b/src/IML/Reader.cs index eeed4176..e4dbc3cb 100644 --- a/src/IML/Reader.cs +++ b/src/IML/Reader.cs @@ -29,15 +29,9 @@ using System.Collections.Generic; namespace Crow.IML { public class Reader : XmlTextReader - { - static MethodInfo[] miAddChild = new MethodInfo[]{ - typeof(Container).GetMethod ("SetChild"), - typeof(Group).GetMethod ("AddChild"), - typeof(TemplatedControl).GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic), - typeof(TemplatedContainer).GetProperty ("Content").GetSetMethod (), - typeof(TemplatedGroup).GetMethod ("AddItem", BindingFlags.Instance | BindingFlags.Public), - //typeof(PrivateContainer).GetMethod ("SetChild", BindingFlags.Instance | BindingFlags.NonPublic) - }; + { + static List CrowTypes = new List (); + public enum SubNodeType{ None, Child, @@ -47,102 +41,47 @@ namespace Crow.IML Items, ItemTemplate } - public class Node { - public SubNodeType Type; - public int Index; - - public Node(){} - public Node(SubNodeType snt, int _index = 0){ - Type = snt; - Index = _index; - } - public static implicit operator SubNodeType(Node sn){ - return sn.Type; - } - public static implicit operator string(Node sn){ - return sn.ToString (); - } - public static implicit operator Node(SubNodeType sn){ - return new Node (sn); - } - public override bool Equals (object obj) - { - return obj is Node && this == (Node)obj; - } - public override int GetHashCode() - { - return Type.GetHashCode() ^ Index.GetHashCode(); - } - public static bool operator ==(Node x, Node y) - { - return x.Type == y.Type && x.Index == y.Index; - } - public static bool operator !=(Node x, Node y) - { - return !(x == y); - } - public override string ToString () - { - return string.Format ("{0}.{1}", (int)Type, Index); - } - public static Node Parse(string str){ - string[] tmp = str.Trim ().Split ('.'); - switch (tmp.Length) { - case 1: - return new Node ((SubNodeType)int.Parse (tmp [0])); - case 2: - return new Node ((SubNodeType)int.Parse (tmp [0]), int.Parse (tmp[1])); - case 0: - default: - return new Node (); - } - } - public static string AddressToString(Node[] address){ - string tmp = ""; - foreach (Node n in address) { - tmp += n.ToString () + ";"; - } - return string.IsNullOrEmpty(tmp) ? tmp : tmp.Substring (0, tmp.Length - 1); - } - public static Node[] AddressFromString(string address) { - List nodes = new List (); - string[] tmp = address.Split (';'); - for (int i = 0; i < tmp.Length; i++) - nodes.Add (Node.Parse (tmp [i])); - return nodes.ToArray(); - } - } -// public class PropertyBinding { -// public string OriginePropertyName = ""; -// public MemberAddress Destination; -// } - public class MemberAddress { - public Node[] DestinationNode = null; - public string DestinationProperty = ""; - - public MemberAddress (){} - public MemberAddress (Node[] _node, string _property){ - DestinationNode = _node; - DestinationProperty = _property; - } - } - InstanciatorInvoker loader = null; - DynamicMethod dm = null; - - public class IMLContext { - public ILGenerator il = null; - public SubNodeType curSubNodeType; - public Stack nodesStack = new Stack(); - - public Dictionary Names = new Dictionary(); - public Dictionary> PropertyBindings = new Dictionary>(); - } + //public static Node Parse(string str){ + // string[] tmp = str.Trim ().Split ('.'); + // switch (tmp.Length) { + // case 1: + // return new Node ((SubNodeType)int.Parse (tmp [0])); + // case 2: + // return new Node ((SubNodeType)int.Parse (tmp [0]), int.Parse (tmp[1])); + // case 0: + // default: + // return new Node (); + // } + //} + //public static string AddressToString(Node[] address){ + // string tmp = ""; + // foreach (Node n in address) { + // tmp += n.ToString () + ";"; + // } + // return string.IsNullOrEmpty(tmp) ? tmp : tmp.Substring (0, tmp.Length - 1); + //} + //public static Node[] AddressFromString(string address) { + // List nodes = new List (); + // string[] tmp = address.Split (';'); + // for (int i = 0; i < tmp.Length; i++) + // nodes.Add (Node.Parse (tmp [i])); + // return nodes.ToArray(); + //} + + + // public class PropertyBinding { + // public string OriginePropertyName = ""; + // public MemberAddress Destination; + // } public Type RootType = null; - public IMLContext IMLCtx; + public Context context; - ILGenerator il { get { return IMLCtx.il; }} + InstanciatorInvoker loader = null; + DynamicMethod dm = null; + + ILGenerator il { get { return context.il; }} /// /// Finalize instatiator MSIL and return LoaderInvoker delegate @@ -157,10 +96,10 @@ namespace Crow.IML } protected int curDepth { - get { return IMLCtx.nodesStack.Count - 1;} + get { return context.nodesStack.Count - 1;} } protected Node curNode { - get { return IMLCtx.nodesStack.Peek(); } + get { return context.nodesStack.Peek(); } } //protected Stack curTemplateDepth = new Stack(new int[] {0}); //current template root depth @@ -177,10 +116,10 @@ namespace Crow.IML /// Used to parse xmlFrament with same code generator linked /// If ilGen=null, a new Code Generator will be created. /// - public Reader (IMLContext ctx, string xmlFragment) + public Reader (Context ctx, string xmlFragment) : base(xmlFragment, XmlNodeType.Element,null){ - IMLCtx = ctx; + context = ctx; // // if (IMLCtx != null) // return; @@ -190,8 +129,8 @@ namespace Crow.IML #endregion void createInstantiator(){ - IMLCtx = new IMLContext(); - readRootType(); + context = new Context(); + RootType = findRootType(); InitEmitter(); emitLoader(RootType); Read();//close tag @@ -212,7 +151,7 @@ namespace Crow.IML CallingConventions.Standard, typeof(void),new Type[] {typeof(object), typeof(Interface)}, RootType, true); - IMLCtx.il = dm.GetILGenerator(256); + context.il = dm.GetILGenerator(256); il.DeclareLocal(typeof(GraphicObject)); il.Emit(OpCodes.Nop); //set local GraphicObject to root object passed as 1st argument @@ -221,34 +160,21 @@ namespace Crow.IML CompilerServices.emitSetCurInterface (il); } void emitLoader(Type crowType){ - - - if (typeof(Group).IsAssignableFrom (crowType)) - IMLCtx.curSubNodeType = SubNodeType.Children; - else if (typeof(Container).IsAssignableFrom (crowType)) - IMLCtx.curSubNodeType = SubNodeType.Child; - else if (typeof(TemplatedContainer).IsAssignableFrom (crowType)) - IMLCtx.curSubNodeType = SubNodeType.Content; - else if (typeof(TemplatedGroup).IsAssignableFrom (crowType)) - IMLCtx.curSubNodeType = SubNodeType.Items; - else if (typeof(TemplatedControl).IsAssignableFrom (crowType)) - IMLCtx.curSubNodeType = SubNodeType.Template; - else - IMLCtx.curSubNodeType = SubNodeType.None; + Node expectedNode = new Node (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 (IMLCtx.curSubNodeType >= SubNodeType.Template) { + if (expectedNode.IsTemplate) { //if its a template, first read template elements - using (Reader reader = new Reader (IMLCtx, tmpXml)) { + using (Reader reader = new Reader (context, tmpXml)) { + List itemTemplateIds = new List (); + bool inlineTemplate = false; string templatePath = reader.GetAttribute ("Template"); - List itemTemplateIds = new List (); - bool inlineTemplate = false; reader.Read (); int depth = reader.Depth + 1; while (reader.Read ()) { @@ -257,9 +183,9 @@ namespace Crow.IML if (reader.Name == "Template") { inlineTemplate = true; reader.Read (); - IMLCtx.nodesStack.Push(SubNodeType.Template); + context.nodesStack.Push (expectedNode); readChildren (reader); - IMLCtx.nodesStack.Pop(); + context.nodesStack.Pop(); } else if (reader.Name == "ItemTemplate") { string dataType = "default", datas = "", path = ""; while (reader.MoveToNextAttribute ()) { @@ -291,8 +217,8 @@ namespace Crow.IML } } - if (!inlineTemplate) { - reader.il.Emit (OpCodes.Ldloc_0);//Load this templateControl ref + if (!inlineTemplate) {//load from path or default template + reader.il.Emit (OpCodes.Ldloc_0);//Load current templatedControl ref if (string.IsNullOrEmpty (templatePath)) { reader.il.Emit (OpCodes.Ldnull);//default template loading }else{ @@ -301,11 +227,7 @@ namespace Crow.IML reader.il.Emit (OpCodes.Callvirt,//call Interface.Load(path) CompilerServices.miIFaceLoad); } - MethodInfo mitmp = crowType.GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic); - if (mitmp == null) - System.Diagnostics.Debugger.Break(); - reader.il.Emit (OpCodes.Callvirt,//load template - mitmp); + reader.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadTmp);//load template } //copy item templates (review this) foreach (string[] iTempId in itemTemplateIds) { @@ -327,22 +249,21 @@ namespace Crow.IML } } } + expectedNode.Index++; } #endregion - using (Reader reader = new Reader(IMLCtx,tmpXml)){ + using (Reader reader = new Reader (context, 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); - } + if (!string.IsNullOrEmpty (style)) + CompilerServices.EmitSetValue (reader.il, CompilerServices.piStyle, style); } reader.il.Emit (OpCodes.Ldloc_0); - reader.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues")); + reader.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadDefaultVals); #endregion #region Attributes reading @@ -364,9 +285,9 @@ namespace Crow.IML throw new Exception ("Member '" + reader.Name + "' not found in " + crowType.Name); if (pi.Name == "Name") - IMLCtx.Names.Add(reader.Value, Node.AddressToString(IMLCtx.nodesStack.ToArray())); + context.Names.Add(reader.Value, Node.AddressToString(context.nodesStack.ToArray())); - if (reader.Value.StartsWith ("{")) { + if (reader.Value.StartsWith ("{", StringComparison.OrdinalIgnoreCase)) { readPropertyBinding(reader.Name, reader.Value.Substring (1, reader.Value.Length - 2)); //CompilerServices.emitBindingCreation (reader.il, reader.Name, reader.Value.Substring (1, reader.Value.Length - 2)); @@ -382,21 +303,21 @@ namespace Crow.IML reader.il.Emit (OpCodes.Pop);//pop saved ref to current object return; } - IMLCtx.nodesStack.Push (IMLCtx.curSubNodeType); + context.nodesStack.Push (expectedNode); readChildren (reader); - IMLCtx.nodesStack.Pop (); + context.nodesStack.Pop (); } il.Emit (OpCodes.Pop);//pop saved ref to current object } void registerPropertyBinding(string origNode, string origProp, MemberAddress ma){ - if (!IMLCtx.PropertyBindings.ContainsKey(origNode)) - IMLCtx.PropertyBindings [origNode] = new Dictionary (); - IMLCtx.PropertyBindings [origNode] [origProp] = ma; + if (!context.PropertyBindings.ContainsKey(origNode)) + context.PropertyBindings [origNode] = new Dictionary (); + context.PropertyBindings [origNode] [origProp] = ma; } void readPropertyBinding(string srcProperty, string expression){ //if binding exp = '{}' => binding is done on datasource if (string.IsNullOrEmpty (expression)) { - registerPropertyBinding ("DS", "", new MemberAddress (IMLCtx.nodesStack.ToArray (), srcProperty)); + registerPropertyBinding ("DS", "", new MemberAddress (context.nodesStack.ToArray (), srcProperty)); return; } @@ -410,13 +331,13 @@ namespace Crow.IML if (bindingExp.Length == 1) { registerPropertyBinding ("DS", bindingExp [0], - new MemberAddress (IMLCtx.nodesStack.ToArray (), srcProperty)); + new MemberAddress (context.nodesStack.ToArray (), srcProperty)); return; } string targetName = ""; string nodeId = ""; - Node[] target = IMLCtx.nodesStack.ToArray (); + Node[] target = context.nodesStack.ToArray (); int nodeIdx = target.Length - 1;//index of target in nodeStack int ptr = 0;//pointer in bindingExp splitted on '/' @@ -428,7 +349,7 @@ namespace Crow.IML nodeId = Node.AddressToString (target); targetName = bindTrg [0]; }else if (bindTrg.Length == 2) { - nodeId = IMLCtx.Names [bindTrg [0]]; + nodeId = context.Names [bindTrg [0]]; targetName = bindTrg [1]; } else throw new Exception ("Syntax error in binding, expected 'go dot member'"); @@ -467,7 +388,7 @@ namespace Crow.IML targetName = bindingExp [ptr]; } - registerPropertyBinding (nodeId, targetName, new MemberAddress (IMLCtx.nodesStack.ToArray (), srcProperty)); + registerPropertyBinding (nodeId, targetName, new MemberAddress (context.nodesStack.ToArray (), srcProperty)); } /// /// Parse child node an generate corresponding msil @@ -510,11 +431,11 @@ namespace Crow.IML reader.emitLoader (t); reader.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting - reader.il.Emit (OpCodes.Callvirt, miAddChild [(int)IMLCtx.nodesStack.Peek ().Type -1]); + reader.il.Emit (OpCodes.Callvirt, miAddChild [(int)context.nodesStack.Peek ().Type -1]); 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 - IMLCtx.nodesStack.Peek ().Index++; + context.nodesStack.Peek ().Index++; break; } @@ -526,7 +447,7 @@ namespace Crow.IML /// read first node to set GraphicObject class for loading /// and let reader position on that node /// - Type readRootType () + Type findRootType () { string root = "Object"; while (Read()) { @@ -544,7 +465,6 @@ namespace Crow.IML t = expT; } } - RootType = t; return t; } } -- 2.47.3