diff options
| author | j-p <jp.bruyere@live.be> | 2018-12-11 23:20:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-11 23:20:54 +0100 |
| commit | eef19b533a0e2ce17f2762d3acfc5990496eaaa0 (patch) | |
| tree | 6f09101bd8097c1a4ca6a216597bb5d4941453fa /src/IML | |
| parent | 65820f61457262b631eba35283c55135aecbc5f2 (diff) | |
| parent | f6732851fe211e22ff91716ac83dffc0cf09d620 (diff) | |
Merge pull request #44 from jpbruyere/xlib
Xlib
Diffstat (limited to 'src/IML')
| -rw-r--r-- | src/IML/BindingDefinition.cs | 90 | ||||
| -rw-r--r-- | src/IML/BindingMember.cs | 191 | ||||
| -rw-r--r-- | src/IML/EventBinding.cs | 45 | ||||
| -rw-r--r-- | src/IML/IMLContext.cs | 230 | ||||
| -rw-r--r-- | src/IML/MemberAddress.cs | 116 | ||||
| -rw-r--r-- | src/IML/Node.cs | 101 | ||||
| -rw-r--r-- | src/IML/NodeAddress.cs | 148 | ||||
| -rw-r--r-- | src/IML/NodeStack.cs | 50 | ||||
| -rw-r--r-- | src/IML/Reader.cs | 223 |
9 files changed, 0 insertions, 1194 deletions
diff --git a/src/IML/BindingDefinition.cs b/src/IML/BindingDefinition.cs deleted file mode 100644 index 075b80b3..00000000 --- a/src/IML/BindingDefinition.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// BindingDefinition.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; - -namespace Crow.IML -{ - /// <summary> - /// store binding source and target addresses and member names - /// </summary> - public class BindingDefinition - { - public NodeAddress SourceNA = null; - public string SourceMember = ""; - public NodeAddress TargetNA = null; - public string TargetMember = ""; - public string TargetName = ""; - public bool TwoWay = false; - - #region CTOR - public BindingDefinition (NodeAddress _sourceNA, string _sourceMember){ - SourceNA = _sourceNA; - SourceMember = _sourceMember; - } - public BindingDefinition (NodeAddress _sourceNA, string _sourceMember, NodeAddress _targetNA, string _targetMember, string _targetName = "", bool _twoWay = false) - { - SourceNA = _sourceNA; - SourceMember = _sourceMember; - TargetNA = _targetNA; - TargetMember = _targetMember; - TargetName = _targetName; - TwoWay = _twoWay; - } - #endregion - - public bool IsDataSourceBinding { get { return TargetNA == null; }} - public bool IsTemplateBinding { get { return IsDataSourceBinding ? false : TargetNA.Count == 0; }} - public bool HasUnresolvedTargetName { get { return !string.IsNullOrEmpty(TargetName); }} - public MemberAddress SourceMemberAddress { get { return new MemberAddress (SourceNA, SourceMember);}} - public MemberAddress TargetMemberAddress { get { return new MemberAddress (TargetNA, TargetMember);}} - - /// <summary> - /// replace the target node address with corresponding named node address, and clear the target name once resolved - /// </summary> - /// <param name="newTargetNA">Named Node</param> - public void ResolveTargetName(NodeAddress newTargetNA){ - TargetNA = newTargetNA; - TargetName = ""; - } - - public override string ToString () - { - string tmp = string.Format ("Source:{0}.{1}", SourceNA, SourceMember); - if (TwoWay) - tmp += " <=> "; - else - tmp += " <= "; - - if (string.IsNullOrEmpty (TargetName)) - tmp += string.Format ("Target:{0}.{1}]", TargetNA, TargetMember); - else - tmp += string.Format ("Target:{0}.{1}.{2}]", TargetNA, TargetName, TargetMember); - return tmp; - } - } -} - diff --git a/src/IML/BindingMember.cs b/src/IML/BindingMember.cs deleted file mode 100644 index 4a2b2c61..00000000 --- a/src/IML/BindingMember.cs +++ /dev/null @@ -1,191 +0,0 @@ -// -// BindingMember.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Reflection.Emit; - -namespace Crow.IML -{ - /// <summary> - /// Binding expression parser. - /// - /// Valid tokens in binding expression: - /// - '../' => 1 level up in graphic tree - /// - './' or '/' => template root level - /// - '.Name1.Name2' current level properties - /// - 'name.prop' named descendant in graphic tree, search with 'FindByName' method of GraphicObject - /// </summary> - public class BindingMember - { - /// <summary> - /// true if expression was enclosed in ' - /// </summary> - public bool IsStringConstant = false; - /// <summary> - /// Nb level to go up, '-1' for template root - /// </summary> - public int LevelsUp; - /// <summary> - /// Remaining string after '/' split, splitted on '.' - /// </summary> - public string[] Tokens; - - /// <summary> - /// Target the template's root node, expression was in the form './name[.name[...]]' or '/name[.name[...]]' - /// </summary> - public bool IsTemplateBinding { get { return LevelsUp < 0; }} - - /// <summary> - /// No level change and expression was '.name' - /// </summary> - /// <value><c>true</c> if this instance is current node property; otherwise, <c>false</c>.</value> - public bool IsCurrentNodeProperty { - get { - return LevelsUp == 0 && ( Tokens.Length == 2 && string.IsNullOrEmpty(Tokens[0])); - } - } - /// <summary> - /// no level change, and only a single name in Tokens[], that's dataSource member if property binding - /// </summary> - public bool IsSingleName { get { return LevelsUp == 0 && Tokens.Length == 1; }} - - #region CTOR - /// <summary> - /// Initializes a new instance of BindingMember. - /// </summary> - public BindingMember (){} - /// <summary> - /// Initializes a new instance of BindingMember by parsing the string passed as argument - /// </summary> - /// <param name="expression">binding expression</param> - public BindingMember (string expression){ - if (string.IsNullOrEmpty (expression)) - return; - - string[] splitedExp = expression.Trim().Split ('/'); - - int ptr = 0; - if (splitedExp.Length == 1) { - if (splitedExp [0].StartsWith ("\'")) { - if (!splitedExp [0].EndsWith ("\'")) - throw new Exception (string.Format - ("IML:malformed string constant in binding expression: {0}", splitedExp [0])); - Tokens = new string[] { splitedExp [0].Substring (1, splitedExp [0].Length - 2) }; - IsStringConstant = true; - return; - } - } else if (string.IsNullOrEmpty (splitedExp [0])) { - ptr++; - } else { - if (splitedExp [0] == ".") {//template root - LevelsUp = -1; - ptr++; - } else { - while (splitedExp [ptr] == "..") - ptr++; - LevelsUp = ptr; - } - } - if (ptr != splitedExp.Length - 1) - throw new Exception ("invalid expresion: " + expression); - Tokens = splitedExp [ptr].Split ('.'); - } - #endregion - - /// <summary> - /// Emits the MSIL instructions to get the target of the binding expression - /// </summary> - /// <param name="il">current MSIL generator</param> - /// <param name="cancel">cancel branching in MSIL if something go wrong</param> - public void emitGetTarget(ILGenerator il, System.Reflection.Emit.Label cancel){ - - if (IsTemplateBinding) { - System.Reflection.Emit.Label nextLogicParent = il.DefineLabel (); - il.MarkLabel (nextLogicParent); - il.Emit (OpCodes.Callvirt, CompilerServices.miGetLogicalParent); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brfalse, cancel); - il.Emit (OpCodes.Isinst, typeof(TemplatedControl)); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brfalse, nextLogicParent); - } else if (LevelsUp > 0) {//go upward in logical tree - il.Emit (OpCodes.Ldc_I4, LevelsUp);//push arg 2 of goUpLevels - il.Emit (OpCodes.Callvirt, CompilerServices.miGoUpLevels); - //test if null - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brfalse, cancel); - } - - if (!string.IsNullOrEmpty (Tokens [0])) {//find by name - il.Emit (OpCodes.Ldstr, Tokens [0]); - il.Emit (OpCodes.Callvirt, CompilerServices.miFindByName); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brfalse, cancel); - } - - for (int i = 1; i < Tokens.Length -1; i++) { - System.Reflection.Emit.Label miOK = il.DefineLabel (); - il.Emit (OpCodes.Dup);//duplicate instance - il.Emit (OpCodes.Ldstr, Tokens [i]);//load member name - il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brtrue, miOK); - il.Emit (OpCodes.Pop);//pop dup instance - il.Emit (OpCodes.Br, cancel); - il.MarkLabel (miOK); - il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brfalse, cancel); - } - } - /// <summary> - /// Emit the MSIL instructions to get the target property of the binding expression - /// </summary> - /// <param name="il">current MSIL generator</param> - /// <param name="cancel">cancel branching in MSIL if something go wrong</param> - public void emitGetProperty(ILGenerator il, System.Reflection.Emit.Label cancel) { - System.Reflection.Emit.Label miOK = il.DefineLabel (); - il.Emit (OpCodes.Dup);//duplicate instance - il.Emit (OpCodes.Ldstr, Tokens [Tokens.Length -1]);//load member name - il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brtrue, miOK); - il.Emit (OpCodes.Pop);//pop dup instance - il.Emit (OpCodes.Br, cancel); - il.MarkLabel (miOK); - il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx); - } - /// <summary> - /// Emit the MSIL instructions to set the target property of the binding expression - /// </summary> - /// <param name="il">current MSIL generator</param> - public void emitSetProperty(ILGenerator il) { - il.Emit (OpCodes.Ldstr, Tokens [Tokens.Length -1]);//load member name - il.Emit (OpCodes.Call, CompilerServices.miSetValWithRefx); - } - } -} - diff --git a/src/IML/EventBinding.cs b/src/IML/EventBinding.cs deleted file mode 100644 index 41e0c96a..00000000 --- a/src/IML/EventBinding.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// EventBinding.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Reflection; - -namespace Crow.IML -{ - public class EventBinding : BindingDefinition - { - public EventInfo SourceEvent; - - #region CTOR - public EventBinding (NodeAddress _sourceNA, EventInfo _sourceEvt, NodeAddress _targetNA, string _targetMember, string _targetName = "") - : base (_sourceNA, _sourceEvt.Name, _targetNA, _targetMember, _targetName) - { - SourceEvent = _sourceEvt; - } - #endregion - } -} - diff --git a/src/IML/IMLContext.cs b/src/IML/IMLContext.cs deleted file mode 100644 index aa4dee2f..00000000 --- a/src/IML/IMLContext.cs +++ /dev/null @@ -1,230 +0,0 @@ -// -// Context.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; -using System.Xml; - -namespace Crow.IML -{ - public class DataSourceBinding { - public bool TwoWay; - public MemberAddress Source; - public string DataSourceMember; - } - /// <summary> - /// Context while parsing IML, this will store what's needed only while parsing and not during instancing - /// </summary> - public class IMLContext - { - public XmlReader reader = null; - public int curLine = 0; - public Type RootType = null; - - public DynamicMethod dm = null; - public ILGenerator il = null; - //public SubNodeType curSubNodeType; - public NodeStack nodesStack = new NodeStack (); - - /// <summary> store addresses of named node for name resolution at end of parsing </summary> - public Dictionary<string, List<NodeAddress>> Names = new Dictionary<string, List<NodeAddress>>(); - /// <summary> Store non datasource binding (in tree and template) by origine and orig member </summary> - public Dictionary<NodeAddress, Dictionary<string, List<MemberAddress>>> Bindings = - new Dictionary<NodeAddress, Dictionary<string, List<MemberAddress>>>(); - /// <summary> Store binding with name in target, will be resolved at end of parsing </summary> - public List<BindingDefinition> UnresolvedTargets = new List<BindingDefinition>(); - - - public IMLContext (Type rootType) - { - RootType = rootType; - dm = new DynamicMethod ("dyn_instantiator", - CompilerServices.TObject, new Type [] { typeof (Instantiator), typeof (Interface) }, true); - il = dm.GetILGenerator (256); - - il.DeclareLocal (typeof (GraphicObject)); - il.Emit (OpCodes.Nop); - //set local GraphicObject to root object - ConstructorInfo ci = rootType.GetConstructor ( - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, - null, Type.EmptyTypes, null); - if (ci == null) - throw new Exception ("No default parameterless constructor found in " + rootType.Name); - il.Emit (OpCodes.Newobj, ci); - il.Emit (OpCodes.Stloc_0); - CompilerServices.emitSetCurInterface (il); - } - - public NodeAddress CurrentNodeAddress { - get { - Node[] n = nodesStack.ToArray (); - Array.Reverse (n); - return new NodeAddress(n); - } - } - public Type CurrentNodeType { - get { return nodesStack.Peek().CrowType; } - } - public void StorePropertyBinding(NodeAddress origNA, string origMember, NodeAddress destNA, string destMember){ - Dictionary<string, List<MemberAddress>> nodeBindings = null; - if (Bindings.ContainsKey (origNA)) - nodeBindings = Bindings [origNA]; - else { - nodeBindings = new Dictionary<string, List<MemberAddress>> (); - Bindings [origNA] = nodeBindings; - } - - if (!nodeBindings.ContainsKey (origMember)) - nodeBindings [origMember] = new List<MemberAddress> (); - nodeBindings [origMember].Add (new MemberAddress (destNA, destMember)); - } - public void StorePropertyBinding(BindingDefinition bindDef){ - if (bindDef.HasUnresolvedTargetName) { - UnresolvedTargets.Add (bindDef); - return; - } - StorePropertyBinding (bindDef.TargetNA, bindDef.TargetMember, bindDef.SourceNA, bindDef.SourceMember); - if (bindDef.TwoWay) - StorePropertyBinding (bindDef.SourceNA, bindDef.SourceMember, bindDef.TargetNA, bindDef.TargetMember); - } - public void StoreCurrentName(string name){ - if (!Names.ContainsKey(name)) - Names[name] = new List<NodeAddress>(); - Names[name].Add(CurrentNodeAddress); - } - public void ResolveNamedTargets(){//TODO:methodinfo fetching is redundant with early parsing - foreach (BindingDefinition bd in UnresolvedTargets) { - if (bd.HasUnresolvedTargetName) { - try { - ResolveName (bd); - } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine (ex.ToString ()); - continue; - } - } - - if (bd is EventBinding) { - emitHandlerMethodAddition (bd as EventBinding); - continue; - } - - MemberInfo miSource = bd.SourceMemberAddress.member; - if (miSource == null) - throw new Exception ("Source member '" + bd.SourceMember + "' not found"); - StorePropertyBinding (bd); - } - } - public void ResolveName (BindingDefinition bd){ - - if (!Names.ContainsKey (bd.TargetName)) - throw new Exception ("Target Name '" + bd.TargetName + "' not found"); - - NodeAddress resolvedNA = null; - foreach (NodeAddress na in Names[bd.TargetName]) { - bool naMatch = true; - for (int i = 0; i < bd.TargetNA.Count; i++) { - if (bd.TargetNA [i] != na [i]) { - naMatch = false; - break; - } - } - if (naMatch) { - resolvedNA = na; - break; - } - } - - if (resolvedNA == null) - throw new Exception ("Target Name '" + bd.TargetName + "' not found"); - - bd.ResolveTargetName (resolvedNA); - } - - /// <summary> - /// Emits cached delegate handler addition in the context of instantiator (ctx) - /// </summary> - public void emitCachedDelegateHandlerAddition(int index, EventInfo evt, NodeAddress address = null){ - il.Emit(OpCodes.Ldloc_0);//load ref to current graphic object - CompilerServices.emitGetInstance (il, address); - il.Emit(OpCodes.Ldarg_0);//load ref to this instanciator onto the stack - il.Emit(OpCodes.Ldfld, CompilerServices.fiCachedDel); - il.Emit(OpCodes.Ldc_I4, index);//load delegate index - il.Emit(OpCodes.Callvirt, CompilerServices.miGetDelegateListItem); - il.Emit(OpCodes.Callvirt, evt.AddMethod);//call add event - } - /// <summary> - /// Emits the handler method addition, done at end of parsing, Loc_0 is root node instance - /// </summary> - /// <param name="bd">Bd.</param> - /// <param name="evt">passed as arg to prevent refetching it for the 3rd time</param> - public void emitHandlerMethodAddition(EventBinding bd){ - - //fetch source instance with address for handler addition (as 1st arg of handler.add) - il.Emit (OpCodes.Ldloc_0);//push root - CompilerServices.emitGetInstance (il, bd.SourceNA); - - il.Emit (OpCodes.Ldloc_0); - CompilerServices.emitGetInstance (il, bd.TargetNA); - - string[] membs = bd.TargetMember.Split ('.'); - for (int i = 0; i < membs.Length - 1; i++) { - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Ldstr, membs[i]); - il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx); - il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx); - } - - //load handlerType of sourceEvent to create handler delegate (1st arg) - il.Emit (OpCodes.Ldtoken, bd.SourceEvent.EventHandlerType); - il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle); - //load methodInfo (3rd arg) - il.Emit (OpCodes.Ldstr, membs[membs.Length-1]); - il.Emit (OpCodes.Callvirt, CompilerServices.miCreateDel); - il.Emit (OpCodes.Callvirt, bd.SourceEvent.AddMethod);//call add event - } -// public void emitHandlerMethodAddition(EventBinding bd){ -// //fetch source instance with address for handler addition (as 1st arg of handler.add) -// il.Emit (OpCodes.Ldloc_0);//push root -// CompilerServices.emitGetInstance (il, bd.SourceNA); -// -// //load handlerType of sourceEvent to create handler delegate (1st arg) -// il.Emit (OpCodes.Ldtoken, bd.SourceEvent.EventHandlerType); -// il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle); -// //load target the where the method is defined (2nd arg) -// il.Emit (OpCodes.Ldloc_0); -// CompilerServices.emitGetInstance (il, bd.TargetNA); -// //load methodInfo (3rd arg) -// il.Emit (OpCodes.Ldstr, bd.TargetMember); -// -// il.Emit (OpCodes.Callvirt, CompilerServices.miCreateDel); -// -// il.Emit (OpCodes.Callvirt, bd.SourceEvent.AddMethod);//call add event -// } -// - } -}
\ No newline at end of file diff --git a/src/IML/MemberAddress.cs b/src/IML/MemberAddress.cs deleted file mode 100644 index f27a8b87..00000000 --- a/src/IML/MemberAddress.cs +++ /dev/null @@ -1,116 +0,0 @@ -// -// MemberAddress.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Linq; -using System.Reflection; - -namespace Crow.IML -{ - /// <summary> - /// Address member of a node - /// </summary> - public struct MemberAddress - { - public string memberName; - public MemberInfo member; - public NodeAddress Address; - - public PropertyInfo Property { get { return member as PropertyInfo; }} - public bool IsTemplateBinding { get { return Address == null ? false : Address.Count == 0; }} -// public string Name { -// get { return memberName; } -// set { memberName = value; } -// } - - public MemberAddress (NodeAddress _address, string _member, bool findMember = true) - { - Address = _address; - memberName = _member; - member = null; - - if (Address == null) - return; - if (Address.Count == 0) - return; - - if (!findMember) - return; - if (!tryFindMember ()) - throw new Exception ("Member Not Found: " + memberName); - } - public MemberAddress (NodeAddress _address, MemberInfo _member) - { - Address = _address; - member = _member; - memberName = ""; - - if (member != null) - memberName = member.Name; - } - - #region Equality Compare - public override bool Equals (object obj) - { - return obj is MemberAddress && this == (MemberAddress)obj; - } - public override int GetHashCode () - { - return Address.GetHashCode () ^ member.GetHashCode (); - } - public static bool operator == (MemberAddress x, MemberAddress y) - { - return x.Address == y.Address && x.memberName == y.memberName; - } - public static bool operator != (MemberAddress x, MemberAddress y) - { - return !(x == y); - } - #endregion - - bool tryFindMember () - { - if (member != null) - throw new Exception ("member already found"); - if (Address == null) - return false; - if (Address.Count == 0) - return false; - Type t = Address.LastOrDefault ().CrowType; - 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 (); - string mn = memberName; - member = CompilerServices.GetExtensionMethods (a, t).Where (em => em.Name == mn).FirstOrDefault (); - } - #endregion - - return member != null; - } - } -} diff --git a/src/IML/Node.cs b/src/IML/Node.cs deleted file mode 100644 index 2ca90e8c..00000000 --- a/src/IML/Node.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Node.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Reflection; -using System.Reflection.Emit; -using System.Collections.Generic; - -namespace Crow.IML -{ - /// <summary> - /// IML Node are defined with a type and the index in the parent, - /// </summary> - public struct Node - { - #region CTOR - public Node (Type crowType, int _index = 0) - { - CrowType = crowType; - Index = _index; - } - #endregion - - /// <summary> Current node type</summary> - public Type CrowType; - /// <summary> Index in parent, -1 for template</summary> - public int Index; - - /// <summary> - /// retrieve the child addition method depending on the type of this node - /// </summary> - /// <returns>The child addition method</returns> - /// <param name="childIdx">child index or, template root node has index == -1</param> - public MethodInfo GetAddMethod(int childIdx){ - if (typeof (Group).IsAssignableFrom (CrowType)) - return CompilerServices.miAddChild; - if (typeof (Container).IsAssignableFrom (CrowType)) - return CompilerServices.miSetChild; - if (typeof (TemplatedContainer).IsAssignableFrom (CrowType)) - return childIdx < 0 ? CompilerServices.miLoadTmp : CompilerServices.piContent.GetSetMethod(); - if (typeof (TemplatedGroup).IsAssignableFrom (CrowType)) - return childIdx < 0 ? CompilerServices.miLoadTmp : CompilerServices.miAddItem; - if (typeof (TemplatedControl).IsAssignableFrom (CrowType)) - return CompilerServices.miLoadTmp; - return null; - } - - #region Equality Compare - public override bool Equals (object obj) - { - if (obj == null) - return false; - Node n = (Node)obj; - return CrowType == n.CrowType && Index == n.Index; - } - public override int GetHashCode () - { - return CrowType.GetHashCode () ^ Index.GetHashCode (); - } - #endregion - - public bool HasTemplate { - get { return typeof (TemplatedControl).IsAssignableFrom (CrowType);} - } - public bool IsTemplatedGroup { - get { return typeof (TemplatedGroup).IsAssignableFrom (CrowType);} - } - - 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 deleted file mode 100644 index 450a9d2d..00000000 --- a/src/IML/NodeAddress.cs +++ /dev/null @@ -1,148 +0,0 @@ -// -// NodeAddress.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; - -namespace Crow.IML -{ - /// <summary> - /// Node address is a list of nodes from root to leaf defining a unique node - /// </summary> - public class NodeAddress : List<Node> - { - #region CTOR - public NodeAddress (Node[] nodes) : base(nodes) {} - #endregion - - public Type NodeType { get { return Count == 0 ? null : this[this.Count -1].CrowType; }} - - /// <summary> - /// Gets the node adress from binding expression starting from this node - /// and return in expression remaining part - /// </summary> - public NodeAddress ResolveExpression (ref string expression){ - int ptr = this.Count - 1; - string[] splitedExp = expression.Split ('/'); - - if (splitedExp.Length < 2)//dataSource binding - return null; - - if (!string.IsNullOrEmpty (splitedExp [0])) {//else bind on current node - //return new NodeAddress (this.Take(ptr+1).ToArray()); - if (splitedExp [0] == ".") {//search template root - ptr--; - while (ptr >= 0) { - if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType)) - break; - ptr--; - } - } else if (splitedExp [0] == "..") { //search starting at current node - int levelUp = splitedExp.Length - 1; - if (levelUp > ptr + 1) - throw new Exception ("Binding error: try to bind outside IML source"); - ptr -= levelUp; - } - } - expression = splitedExp [splitedExp.Length - 1]; - //TODO:change Template special address identified with Nodecount = 0 to something not using array count to 0, - //here linq is working without limits checking in compile option - //but defining a 0 capacity array with limits cheking enabled, cause 'out of memory' error - return new NodeAddress (this.Take(ptr+1).ToArray());//[ptr+1]; - //Array.Copy (sourceAddr.ToArray (), targetNode, ptr + 1); - //return new NodeAddress (targetNode); - } - /// <summary> - /// get BindingDefinition from binding expression - /// </summary> - public BindingDefinition GetBindingDef(string sourceMember, string expression){ - BindingDefinition bindingDef = new BindingDefinition(this, sourceMember); - if (string.IsNullOrEmpty (expression)) { - return bindingDef; - } else { - if (expression.StartsWith ("²")) { - bindingDef.TwoWay = true; - expression = expression.Substring (1); - } - - string exp = expression; - bindingDef.TargetNA = this.ResolveExpression (ref exp); - - string [] bindTrg = exp.Split ('.'); - - if (bindTrg.Length == 0) - throw new Exception ("invalid binding expression: " + expression); - if (bindTrg.Length == 1) - bindingDef.TargetMember = bindTrg [0]; - else { - if (!string.IsNullOrEmpty(bindTrg[0]))//searchByName - bindingDef.TargetName = bindTrg[0]; - - bindingDef.TargetMember = exp.Substring (bindTrg[0].Length + 1); - } - } - - return bindingDef; - } - - #region Object overrides - public override bool Equals (object obj) - { - if (obj == null) - return false; - - NodeAddress na = (NodeAddress)obj; - return this.SequenceEqual (na); - } - public override int GetHashCode () - { - unchecked { - int hash = 19; - foreach (Node n in this) - hash = hash * 31 + (n == null ? 0 : n.GetHashCode ()); - return hash; - } - } - public override string ToString () - { - string tmp = ""; - foreach (Node n in this) - tmp += string.Format ("{0};", n.Index); - return tmp; - } - #endregion - } - - public class NamedNodeAddress : NodeAddress { - public string Name; - public NamedNodeAddress(string name, Node[] nodes) : base(nodes){ - Name = name; - } - } -} diff --git a/src/IML/NodeStack.cs b/src/IML/NodeStack.cs deleted file mode 100644 index 80e9156f..00000000 --- a/src/IML/NodeStack.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// NodeStack.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; - -namespace Crow.IML -{ - public class NodeStack : Stack<Node> - { - public NodeStack () : base() - { - } - public void IncrementCurrentNodeIndex(){ - Node n = this.Pop(); - this.Push (new Node (n.CrowType, n.Index + 1)); - } - public void DecrementCurrentNodeIndex(){ - Node n = this.Pop(); - this.Push (new Node (n.CrowType, n.Index - 1)); - } - public void ResetCurrentNodeIndex(){ - this.Push (new Node (this.Pop().CrowType)); - } - } -} - diff --git a/src/IML/Reader.cs b/src/IML/Reader.cs deleted file mode 100644 index 7a0c8405..00000000 --- a/src/IML/Reader.cs +++ /dev/null @@ -1,223 +0,0 @@ -// -// IMLReader.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// 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 <http://www.gnu.org/licenses/>. -using System; -using System.Xml; -using System.IO; -using System.Reflection; -using System.Reflection.Emit; -using System.Linq; -using System.Collections.Generic; - -namespace Crow.IML2 -{ - public class Reader : XmlTextReader - { - static List<Type> CrowTypes = new List<Type> (); - - public enum SubNodeType{ - None, - Child, - Children, - Template, - Content, - Items, - ItemTemplate - } - - //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<Node> nodes = new List<Node> (); - // 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 Context context; - - InstanciatorInvoker loader = null; - DynamicMethod dm = null; - - ILGenerator il { get { return context.il; }} - - /// <summary> - /// Finalize instatiator MSIL and return LoaderInvoker delegate - /// </summary> - public InstanciatorInvoker GetLoader(){ - if (loader != null) - return loader; - - il.Emit(OpCodes.Ret); - loader = (InstanciatorInvoker)dm.CreateDelegate (typeof(InstanciatorInvoker)); - return loader; - } - - protected int curDepth { - get { return context.nodesStack.Count - 1;} - } - protected Node curNode { - get { return context.nodesStack.Peek(); } - } - //protected Stack<int> curTemplateDepth = new Stack<int>(new int[] {0}); //current template root depth - - #region CTOR - public Reader (string path) - : this(Interface.GetStreamFromPath (path)){ - } - public Reader (Stream stream) - : base(stream) - { - createInstantiator (); - } - /// <summary> - /// Used to parse xmlFrament with same code generator linked - /// If ilGen=null, a new Code Generator will be created. - /// </summary> - public Reader (Context ctx, string xmlFragment) - : base(xmlFragment, XmlNodeType.Element,null){ - - context = ctx; -// -// if (IMLCtx != null) -// return; -// -// createInstantiator(); - } - #endregion - - - void createBindingDelegates(){ -// foreach (Dictionary<string, MemberAddress> pb in IMLCtx.PropertyBindings) { -// -// } - } - - - void registerPropertyBinding(string origNode, string origProp, MemberAddress ma){ - if (!context.PropertyBindings.ContainsKey(origNode)) - context.PropertyBindings [origNode] = new Dictionary<string, MemberAddress> (); - 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 (context.nodesStack.ToArray (), srcProperty)); - return; - } - -// if (expression.StartsWith ("²")) { -// expression = expression.Substring (1); -// TwoWayBinding = true; -// } -// - string [] bindingExp = expression.Split ('/'); - - - if (bindingExp.Length == 1) { - registerPropertyBinding ("DS", bindingExp [0], - new MemberAddress (context.nodesStack.ToArray (), srcProperty)); - return; - } - - string targetName = ""; - string nodeId = ""; - Node[] target = context.nodesStack.ToArray (); - - int nodeIdx = target.Length - 1;//index of target in nodeStack - int ptr = 0;//pointer in bindingExp splitted on '/' - -// //if exp start with '/' => WidgetName.property - if (string.IsNullOrEmpty (bindingExp [0])) { - string[] bindTrg = bindingExp [1].Split ('.'); - if (bindTrg.Length == 1) { - nodeId = Node.AddressToString (target); - targetName = bindTrg [0]; - }else if (bindTrg.Length == 2) { - nodeId = context.Names [bindTrg [0]]; - targetName = bindTrg [1]; - } else - throw new Exception ("Syntax error in binding, expected 'go dot member'"); - } else { - if (bindingExp [0] == ".") { //template binding - //parse nodes up until template node - while (nodeIdx > 0) { - if (target [nodeIdx].Type == SubNodeType.Template) - break; - nodeIdx--; - } - ptr++; - } else { - while (ptr < bindingExp.Length - 1) { - if (bindingExp [ptr] == "..") - nodeIdx--; - else - break; - ptr++; - } - } - Node[] origine = new Node[nodeIdx + 1]; - try { - Array.Copy (target, origine, nodeIdx + 1); - - int destLength = target.Length - nodeIdx; - Node[] dest = new Node[destLength]; - Array.Copy (target, nodeIdx, dest, 0, destLength); - - } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine (ex.ToString ()); - } - - - nodeId = Node.AddressToString (origine); - targetName = bindingExp [ptr]; - } - - registerPropertyBinding (nodeId, targetName, new MemberAddress (context.nodesStack.ToArray (), srcProperty)); - } - - } -} - |