il.Emit (OpCodes.Ldarg_0); //load sender ref onto the stack, the current node
if (lopParts.Length > 1) {
- NodeAddress lopNA = getNodeAdressFromBindingExp (currentNode, ref operandes [0]);
+ NodeAddress lopNA = currentNode.ResolveExpression (ref operandes [0]);
CompilerServices.emitGetInstance (il, currentNode, lopNA);
lopType = lopNA.NodeType;
}
il.Emit (OpCodes.Ldarg_0); //load sender ref onto the stack
if (lopParts.Length > 1) {
- NodeAddress lopNA = getNodeAdressFromBindingExp (currentNode, ref operandes [0]);
+ NodeAddress lopNA = currentNode.ResolveExpression (ref operandes [0]);
CompilerServices.emitGetInstance (il, currentNode, lopNA);
lopType = lopNA.NodeType;
}
exps.Add(expression);
return exps.ToArray ();
}
-
- /// <summary>
- /// Gets the node adress from binding expression starting at sourceAddr
- /// and return in expression remaining part
- /// </summary>
- internal static NodeAddress getNodeAdressFromBindingExp(NodeAddress sourceAddr, ref string expression){
- int ptr = sourceAddr.Count - 1;
- string[] splitedExp = expression.Split ('/');
-
- if (splitedExp.Length < 2)//dataSource binding
- return null;
-
- if (string.IsNullOrEmpty (splitedExp [0]) || splitedExp [0] == ".") {//search template root
- ptr--;
- while (ptr >= 0) {
- if (typeof(TemplatedControl).IsAssignableFrom (sourceAddr [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 (sourceAddr.Take(ptr+1).ToArray());//[ptr+1];
- //Array.Copy (sourceAddr.ToArray (), targetNode, ptr + 1);
- //return new NodeAddress (targetNode);
- }
-
}
}
/// </summary>
public struct Node
{
- /// <summary> Current node type</summary>
- public Type CrowType;
- /// <summary> Index in parent, -1 for template</summary>
- public int Index;
-
+ #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;
public MethodInfo GetAddMethod(int childIdx){
if (typeof (Group).IsAssignableFrom (CrowType))
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>
{
- public NodeAddress (Node[] nodes) : base(nodes) {
- }
+ #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]) || 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 hash;
}
}
-
public override string ToString ()
{
string tmp = "";
tmp += string.Format ("{0};", n.Index);
return tmp;
}
+ #endregion
}
public class NamedNodeAddress : NodeAddress {
void readPropertyBinding (Context ctx, string sourceMember, string expression)
{
NodeAddress sourceNA = ctx.CurrentNodeAddress;
- BindingDefinition bindingDef = genBindingDef (sourceNA, sourceMember, expression);
+ BindingDefinition bindingDef = sourceNA.GetBindingDef (sourceMember, expression);
#if DEBUG_BINDING
Debug.WriteLine("Property Binding: " + bindingDef.ToString());
ctx.StorePropertyBinding (bindingDef);
}
- /// <summary>
- /// get BindingDefinition from binding expression
- /// </summary>
- BindingDefinition genBindingDef(NodeAddress sourceNA, string sourceMember, string expression){
- BindingDefinition bindingDef = new BindingDefinition(sourceNA, sourceMember);
- if (string.IsNullOrEmpty (expression)) {
- return bindingDef;
- } else {
- if (expression.StartsWith ("²")) {
- bindingDef.TwoWay = true;
- expression = expression.Substring (1);
- }
-
- string exp = expression;
- bindingDef.TargetNA = CompilerServices.getNodeAdressFromBindingExp (sourceNA, 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 Emit Helper
void dataSourceChangedEmitHelper(object dscSource, object dataSource, int dynMethIdx){
if (dataSource is IValueChange)
/// <summary> Emits handler method bindings </summary>
void emitHandlerBinding (Context ctx, EventInfo sourceEvent, string expression){
NodeAddress currentNode = ctx.CurrentNodeAddress;
- BindingDefinition bindingDef = genBindingDef (currentNode, sourceEvent.Name, expression);
+ BindingDefinition bindingDef = currentNode.GetBindingDef (sourceEvent.Name, expression);
#if DEBUG_BINDING
Debug.WriteLine("Event Binding: " + bindingDef.ToString());