public void MergeCombinesDeeper() { foreach (bool w in new[] { false, true }) { BindingRestrictions bW = BindingRestrictions.GetExpressionRestriction(Expression.Constant(w)); foreach (bool x in new[] { false, true }) { BindingRestrictions bX = BindingRestrictions.GetExpressionRestriction(Expression.Constant(x)); foreach (bool y in new[] { false, true }) { BindingRestrictions bY = BindingRestrictions.GetExpressionRestriction(Expression.Constant(y)); BindingRestrictions merged = bW.Merge(bX).Merge(bY); Assert.Equal(w & x & y, Expression.Lambda <Func <bool> >(merged.ToExpression()).Compile()()); foreach (bool z in new[] { false, true }) { BindingRestrictions bZ = BindingRestrictions.GetExpressionRestriction( Expression.Constant(z)); merged = bW.Merge(bX).Merge(bY).Merge(bZ); Assert.Equal( w & x & y & z, Expression.Lambda <Func <bool> >(merged.ToExpression()).Compile()()); } } } } }
public void EmptyRestiction() { BindingRestrictions empty = BindingRestrictions.Empty; BindingRestrictionsProxyProxy view = GetDebugViewObject(empty); Assert.True(view.IsEmpty); BindingRestrictions[] restrictions = view.Restrictions; Assert.Equal(1, restrictions.Length); Assert.Same(empty, restrictions[0]); Assert.Same(empty.ToExpression(), view.Test); Assert.Equal(empty.ToExpression().ToString(), view.ToString()); }
public void MergedRestrictionsProperties() { var exps = new Expression[] { Expression.Constant(false), Expression.Constant(true), Expression.Equal(Expression.Constant(2), Expression.Constant(3)) }; BindingRestrictions br = BindingRestrictions.Empty; var restrictions = new List <BindingRestrictions>(); foreach (var exp in exps) { BindingRestrictions res = BindingRestrictions.GetExpressionRestriction(exp); restrictions.Add(res); br = br.Merge(res); } if (BindingRestrictionsDebugViewType == null) { return; } BindingRestrictionsProxyProxy view = GetDebugViewObject(br); Assert.False(view.IsEmpty); Assert.Equal(br.ToExpression().ToString(), view.ToString()); BindingRestrictions[] viewedRestrictions = view.Restrictions; // Check equal to source restrictions, but not insisting on order. Assert.Equal(3, viewedRestrictions.Length); Assert.True(viewedRestrictions.All(r => restrictions.Contains(r))); }
public void EmptyRestiction() { if (BindingRestrictionsDebugViewType == null) { throw new SkipTestException("Didn't find DebuggerTypeProxyAttribute on BindingRestrictions."); } BindingRestrictions empty = BindingRestrictions.Empty; BindingRestrictionsProxyProxy view = GetDebugViewObject(empty); Assert.True(view.IsEmpty); BindingRestrictions[] restrictions = view.Restrictions; Assert.Equal(1, restrictions.Length); Assert.Same(empty, restrictions[0]); Assert.Same(empty.ToExpression(), view.Test); Assert.Equal(empty.ToExpression().ToString(), view.ToString()); }
public void MergeWithSelfHasSameExpression() { Expression exp = Expression.Constant(true); BindingRestrictions allowAll = BindingRestrictions.GetExpressionRestriction(exp); BindingRestrictions doubled = allowAll.Merge(allowAll); Assert.Same(exp, doubled.ToExpression()); }
public void InstanceRestrictionForNull() { Expression exp = Expression.Default(typeof(Egalitarian)); BindingRestrictions hasNull = BindingRestrictions.GetInstanceRestriction(exp, null); Assert.True(Expression.Lambda <Func <bool> >(hasNull.ToExpression()).Compile()()); BindingRestrictions hasInst = BindingRestrictions.GetInstanceRestriction(exp, new Egalitarian()); Assert.False(Expression.Lambda <Func <bool> >(hasInst.ToExpression()).Compile()()); }
public void AddRestriction(BindingRestrictions /*!*/ restriction) { if (_treatRestrictionsAsConditions) { AddCondition(restriction.ToExpression()); } else { Add(restriction); } }
public void MergeCombines() { foreach (bool x in new[] { false, true }) { foreach (bool y in new[] { false, true }) { BindingRestrictions bX = BindingRestrictions.GetExpressionRestriction(Expression.Constant(x)); BindingRestrictions bY = BindingRestrictions.GetExpressionRestriction(Expression.Constant(y)); BindingRestrictions merged = bX.Merge(bY); Assert.Equal(x & y, Expression.Lambda <Func <bool> >(merged.ToExpression()).Compile()()); } } }
public void InstanceRestrictionRequiresIdentity() { Egalitarian instance = new Egalitarian(); Expression exp = Expression.Constant(instance); BindingRestrictions sameInstance = BindingRestrictions.GetInstanceRestriction(exp, instance); Assert.True(Expression.Lambda <Func <bool> >(sameInstance.ToExpression()).Compile()()); BindingRestrictions diffInstance = BindingRestrictions.GetInstanceRestriction(exp, new Egalitarian()); Assert.False(Expression.Lambda <Func <bool> >(diffInstance.ToExpression()).Compile()()); BindingRestrictions noInstance = BindingRestrictions.GetInstanceRestriction(exp, null); Assert.False(Expression.Lambda <Func <bool> >(noInstance.ToExpression()).Compile()()); }
internal static void DumpRule(CallSiteBinder /*!*/ binder, BindingRestrictions /*!*/ restrictions, Expression /*!*/ expr) { #if DEBUG && FEATURE_FULL_CONSOLE && !CLR2 if (RubyOptions.ShowRules) { var oldColor = Console.ForegroundColor; try { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Rule #{0}: {1}", Interlocked.Increment(ref _ruleCounter), binder); Console.ForegroundColor = ConsoleColor.DarkGray; if (!_DumpingExpression) { var d = (restrictions != BindingRestrictions.Empty) ? Expression.IfThen(restrictions.ToExpression(), expr) : expr; _DumpingExpression = true; try { if (_dumpViewMethod == null) { _dumpViewMethod = typeof(Expression).GetMethod("get_DebugView", BindingFlags.NonPublic | BindingFlags.Instance); } Console.WriteLine(_dumpViewMethod.Invoke(d, ArrayUtils.EmptyObjects)); Console.WriteLine(); } catch { // nop } } } finally { _DumpingExpression = false; Console.ForegroundColor = oldColor; } } #endif }
public void TypeRestrictionFalseForOtherType(object obj, Type type) { BindingRestrictions isType = BindingRestrictions.GetTypeRestriction(Expression.Constant(obj), type); Assert.False(Expression.Lambda <Func <bool> >(isType.ToExpression()).Compile()()); }
public void TypeRestrictionTrueForMatchType(object obj) { BindingRestrictions isType = BindingRestrictions.GetTypeRestriction(Expression.Constant(obj), obj.GetType()); Assert.True(Expression.Lambda <Func <bool> >(isType.ToExpression()).Compile()()); }
/// <summary> /// Performs the runtime binding of the dynamic operation on a set of arguments. /// </summary> /// <param name="args">An array of arguments to the dynamic operation.</param> /// <param name="parameters">The array of <see cref="ParameterExpression"/> instances that represent the parameters of the call site in the binding process.</param> /// <param name="returnLabel">A LabelTarget used to return the result of the dynamic binding.</param> /// <returns> /// An Expression that performs tests on the dynamic operation arguments, and /// performs the dynamic operation if hte tests are valid. If the tests fail on /// subsequent occurrences of the dynamic operation, Bind will be called again /// to produce a new <see cref="Expression"/> for the new argument types. /// </returns> public sealed override Expression Bind(object[] args, ReadOnlyCollection <ParameterExpression> parameters, LabelTarget returnLabel) { ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNull(returnLabel, "returnLabel"); if (args.Length == 0) { throw Error.OutOfRange("args.Length", 1); } if (parameters.Count == 0) { throw Error.OutOfRange("parameters.Count", 1); } if (args.Length != parameters.Count) { throw new ArgumentOutOfRangeException("args"); } // Ensure that the binder's ReturnType matches CallSite's return // type. We do this so meta objects and language binders can // compose trees together without needing to insert converts. Type expectedResult; if (IsStandardBinder) { expectedResult = ReturnType; if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult)) { throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type); } } else { // Even for non-standard binders, we have to at least make sure // it works with the CallSite's type to build the return. expectedResult = returnLabel.Type; } DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]); DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters); DynamicMetaObject binding = Bind(target, metaArgs); if (binding == null) { throw Error.BindingCannotBeNull(); } Expression body = binding.Expression; BindingRestrictions restrictions = binding.Restrictions; // Ensure the result matches the expected result type. if (expectedResult != typeof(void) && !TypeUtils.AreReferenceAssignable(expectedResult, body.Type)) { // // Blame the last person that handled the result: assume it's // the dynamic object (if any), otherwise blame the language. // if (target.Value is IDynamicMetaObjectProvider) { throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult); } else { throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult); } } // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding. // it makes sense to restrict on the target's type in such cases. // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant. if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null) { if (restrictions == BindingRestrictions.Empty) { throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this); } } restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters); // Add the return if (body.NodeType != ExpressionType.Goto) { body = Expression.Return(returnLabel, body); } // Finally, add restrictions if (restrictions != BindingRestrictions.Empty) { body = Expression.IfThen(restrictions.ToExpression(), body); } return(body); }