Example #1
0
            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)
                       ));
            }
Example #2
0
        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));
        }
Example #3
0
        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);
        }
Example #4
0
        private Expression ConversionFallback(DynamicMetaObjectBinder /*!*/ convertToAction)
        {
            if (convertToAction is PythonConversionBinder cb)
            {
                return(GetConversionFailedReturnValue(cb, this).Expression);
            }

            return(convertToAction.GetUpdateExpression(typeof(object)));
        }
Example #5
0
 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)
                ));
 }
Example #6
0
        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)) }));
        }
Example #7
0
        private Expression ConversionFallback(DynamicMetaObjectBinder/*!*/ convertToAction) {
            PythonConversionBinder cb = convertToAction as PythonConversionBinder;
            if (cb != null) {
                return GetConversionFailedReturnValue(cb, this).Expression;
            }

            return convertToAction.GetUpdateExpression(typeof(object));
        }
Example #8
0
        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;
        }
Example #9
0
            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)));
            }