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