Contains the mapping information for a single Combo Binder. This includes the original meta-binder and the mapping of parameters, sub-sites, and constants into the binding.
        public override bool Equals(object obj) {
            ComboBinder other = obj as ComboBinder;
            if (other != null) {
                if (_metaBinders.Length != other._metaBinders.Length) {
                    return false;
                }

                for (int i = 0; i < _metaBinders.Length; i++) {
                    BinderMappingInfo self = _metaBinders[i];
                    BinderMappingInfo otherBinders = other._metaBinders[i];

                    if (!self.Binder.Equals(otherBinders.Binder) ||
                        self.MappingInfo.Count != otherBinders.MappingInfo.Count) {
                        return false;
                    }

                    for (int j = 0; j < self.MappingInfo.Count; j++) {
                        if (!self.MappingInfo[j].Equals(otherBinders.MappingInfo[j])) {
                            return false;
                        }
                    }
                }
                return true;
            }

            return false;
        }
        private DynamicMetaObject[] GetArguments(DynamicMetaObject[] args, IList<DynamicMetaObject> results, int metaBinderIndex) {
            BinderMappingInfo indices = _metaBinders[metaBinderIndex];

            DynamicMetaObject[] res = new DynamicMetaObject[indices.MappingInfo.Count];
            for (int i = 0; i < res.Length; i++) {
                ParameterMappingInfo mappingInfo = indices.MappingInfo[i];

                if (mappingInfo.IsAction) {
                    // input is the result of a previous bind
                    res[i] = results[mappingInfo.ActionIndex];
                } else if (mappingInfo.IsParameter) {
                    // input is one of the original arguments
                    res[i] = args[mappingInfo.ParameterIndex];
                } else {
                    // input is a constant
                    res[i] = new DynamicMetaObject(
                        mappingInfo.Constant,
                        BindingRestrictions.Empty,
                        mappingInfo.Constant.Value
                    );
                }
            }

            return res;
        }
Example #3
0
        public override DynamicMetaObject Bind(DynamicMetaObject target, params DynamicMetaObject[] args)
        {
            args = ArrayUtils.Insert(target, args);

            List <DynamicMetaObject>   results      = new List <DynamicMetaObject>(_metaBinders.Length);
            List <Expression>          steps        = new List <Expression>();
            List <ParameterExpression> temps        = new List <ParameterExpression>();
            BindingRestrictions        restrictions = BindingRestrictions.Empty;

            for (int i = 0; i < _metaBinders.Length; i++)
            {
                BinderMappingInfo curBinder = _metaBinders[i];

                DynamicMetaObject[] tmpargs = GetArguments(args, results, i);
                DynamicMetaObject   next    = curBinder.Binder.Bind(tmpargs[0], ArrayUtils.RemoveFirst(tmpargs));
                if (i != 0)
                {
                    // If the rule contains an embedded "update", replace it with a defer
                    var visitor = new ReplaceUpdateVisitor {
                        Binder = curBinder.Binder, Arguments = tmpargs
                    };
                    next = new DynamicMetaObject(visitor.Visit(next.Expression), next.Restrictions);
                }

                restrictions = restrictions.Merge(next.Restrictions);
                if (next.Expression.NodeType == ExpressionType.Throw)
                {
                    // end of the line... the expression is throwing, none of the other
                    // binders will have an opportunity to run.
                    steps.Add(next.Expression);
                    break;
                }

                ParameterExpression tmp = Expression.Variable(next.Expression.Type, "comboTemp" + i.ToString());
                temps.Add(tmp);

                steps.Add(Expression.Assign(tmp, next.Expression));
                results.Add(new DynamicMetaObject(tmp, next.Restrictions));
            }

            return(new DynamicMetaObject(
                       Expression.Block(
                           temps.ToArray(),
                           steps.ToArray()
                           ),
                       restrictions
                       ));
        }
Example #4
0
        public override MetaObject Bind(MetaObject target, params MetaObject[] args)
        {
            args = ArrayUtils.Insert(target, args);

            List <MetaObject>          results = new List <MetaObject>(_metaBinders.Length);
            List <Expression>          steps   = new List <Expression>();
            List <ParameterExpression> temps   = new List <ParameterExpression>();
            Restrictions restrictions          = Restrictions.Empty;

            for (int i = 0; i < _metaBinders.Length; i++)
            {
                BinderMappingInfo curBinder = _metaBinders[i];

                MetaObject[] tmpargs = GetArguments(args, results, i);
                MetaObject   next    = curBinder.Binder.Bind(tmpargs[0], ArrayUtils.RemoveFirst(tmpargs));

                if (next.Expression.NodeType == ExpressionType.Throw)
                {
                    // end of the line... the expression is throwing, none of the other
                    // binders will have an opportunity to run.
                    steps.Add(next.Expression);
                    break;
                }

                ParameterExpression tmp = Expression.Variable(next.Expression.Type, "comboTemp" + i.ToString());
                temps.Add(tmp);

                steps.Add(Expression.Assign(tmp, next.Expression));
                results.Add(new MetaObject(tmp, next.Restrictions));
                restrictions = restrictions.Merge(next.Restrictions);
            }

            return(new MetaObject(
                       Expression.Block(
                           temps.ToArray(),
                           steps.ToArray()
                           ),
                       restrictions
                       ));
        }