private DynamicMetaObject AddDynamicTestAndDefer(DynamicMetaObjectBinder binder, ExpandoClass @class, ExpandoClass?originalClass, DynamicMetaObject succeeds) { var ifTestSucceeds = succeeds.Expression; if (originalClass == null) { return(new DynamicMetaObject ( Expression.Condition ( Expression.Call ( null, _expandoCheckVersion, GetLimitedSelf(), Expression.Constant(@class, typeof(object)) ), ifTestSucceeds, binder.GetUpdateExpression(ifTestSucceeds.Type) ), GetRestrictions().Merge(succeeds.Restrictions) )); } // we are accessing a member which has not yet been defined on this class. // We force a class promotion after the type check. If the class changes the // promotion will fail and the set/delete will do a full lookup using the new // class to discover the name. Debug.Assert(originalClass != @class); ifTestSucceeds = Expression.Block ( Expression.Call ( null, _expandoPromoteClass, GetLimitedSelf(), Expression.Constant(originalClass, typeof(object)), Expression.Constant(@class, typeof(object)) ), succeeds.Expression ); return(new DynamicMetaObject ( Expression.Condition ( Expression.Call ( null, _expandoCheckVersion, GetLimitedSelf(), Expression.Constant(originalClass, typeof(object)) ), ifTestSucceeds, binder.GetUpdateExpression(ifTestSucceeds.Type) ), GetRestrictions().Merge(succeeds.Restrictions) )); }
internal DynamicMetaObject /*!*/ CreateMetaObject(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ returnType) { Debug.Assert(ControlFlowBuilder == null, "Control flow required but not built"); var restrictions = _restrictions; var expr = _error ? Ast.Throw(_result, returnType) : AstUtils.Convert(_result, returnType); if (_condition != null) { var deferral = binder.GetUpdateExpression(returnType); expr = Ast.Condition(_condition, expr, deferral); } if (_temps != null || _initializations != null) { AddInitialization(expr); if (_temps != null) { expr = Ast.Block(_temps, _initializations); } else { expr = Ast.Block(_initializations); } } Clear(); RubyBinder.DumpRule(binder, restrictions, expr); return(new DynamicMetaObject(expr, restrictions)); }
internal static DynamicMetaObject /*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder /*!*/ operation, DynamicMetaObject /*!*/ res, DynamicMetaObject /*!*/[] args, ValidationInfo typeTest, Type deferType, params ParameterExpression[] temps) { if (typeTest != null) { if (typeTest.Test != null) { // add the test and a validator if persent Expression defer = operation.GetUpdateExpression(deferType ?? typeof(object)); Type bestType = BindingHelpers.GetCompatibleType(defer.Type, res.Expression.Type); res = new DynamicMetaObject( Ast.Condition( typeTest.Test, AstUtils.Convert(res.Expression, bestType), AstUtils.Convert(defer, bestType) ), res.Restrictions ); } } if (temps.Length > 0) { // finally add the scoped variables res = new DynamicMetaObject( Ast.Block(temps, res.Expression), res.Restrictions, null ); } return(res); }
private Expression ConversionFallback(DynamicMetaObjectBinder /*!*/ convertToAction) { if (convertToAction is PythonConversionBinder cb) { return(GetConversionFailedReturnValue(cb, this).Expression); } return(convertToAction.GetUpdateExpression(typeof(object))); }
DynamicMetaObject Restrict(Expression expression, DynamicMetaObjectBinder binder, BindingRestrictions additional) { return(new DynamicMetaObject( Expression.Condition( Expression.Equal( Expression.Property(LimitedInstance, (PropertyInfo)Utils.GetMember(() => Value.Version)), Expression.Constant(Value.Version) ), expression, binder.GetUpdateExpression(expression.Type) ), BindingRestrictions.GetInstanceRestriction(Expression, Value).Merge(additional) )); }
internal static Expression MaybeDebase(DynamicMetaObjectBinder binder, Func <Expression, Expression> generator, DynamicMetaObject target) { ParameterExpression expression; if (!(target.Value is PSObject)) { return(generator(target.Expression)); } object obj2 = PSObject.Base(target.Value); return(Expression.Block(new ParameterExpression[] { expression = Expression.Parameter(typeof(object), "value") }, new Expression[] { Expression.Assign(expression, Expression.Call(CachedReflectionInfo.PSObject_Base, target.Expression)), Expression.Condition((obj2 == null) ? ((Expression)Expression.AndAlso(Expression.Equal(expression, ExpressionCache.NullConstant), Expression.Not(Expression.Equal(target.Expression, ExpressionCache.AutomationNullConstant)))) : ((Expression)Expression.TypeEqual(expression, obj2.GetType())), generator(expression), binder.GetUpdateExpression(binder.ReturnType)) })); }
private Expression ConversionFallback(DynamicMetaObjectBinder/*!*/ convertToAction) { PythonConversionBinder cb = convertToAction as PythonConversionBinder; if (cb != null) { return GetConversionFailedReturnValue(cb, this).Expression; } return convertToAction.GetUpdateExpression(typeof(object)); }
internal static DynamicMetaObject/*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder/*!*/ operation, DynamicMetaObject/*!*/ res, DynamicMetaObject/*!*/[] args, ValidationInfo typeTest, Type deferType, params ParameterExpression[] temps) { if (typeTest != null) { if (typeTest.Test != null) { // add the test and a validator if persent Expression defer = operation.GetUpdateExpression(deferType ?? typeof(object)); Type bestType = BindingHelpers.GetCompatibleType(defer.Type, res.Expression.Type); res = new DynamicMetaObject( Ast.Condition( typeTest.Test, AstUtils.Convert(res.Expression, bestType), AstUtils.Convert(defer, bestType) ), res.Restrictions ); } } if (temps.Length > 0) { // finally add the scoped variables res = new DynamicMetaObject( Ast.Block(temps, res.Expression), res.Restrictions, null ); } return res; }
private DynamicMetaObject AddDynamicTestAndDefer(DynamicMetaObjectBinder binder, ExpandoClass klass, ExpandoClass originalClass, DynamicMetaObject succeeds) { Expression ifTrue = succeeds.Expression; if (originalClass != null) { ifTrue = Expression.Block(Expression.Call(null, typeof(RuntimeOps).GetMethod("ExpandoPromoteClass"), this.GetLimitedSelf(), Expression.Constant(originalClass, typeof(object)), Expression.Constant(klass, typeof(object))), succeeds.Expression); } return(new DynamicMetaObject(Expression.Condition(Expression.Call(null, typeof(RuntimeOps).GetMethod("ExpandoCheckVersion"), this.GetLimitedSelf(), Expression.Constant(originalClass ?? klass, typeof(object))), ifTrue, binder.GetUpdateExpression(ifTrue.Type)), this.GetRestrictions().Merge(succeeds.Restrictions))); }