Exemplo n.º 1
0
        public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (target.Value is QsValue)
            {
                QsValue v      = (QsValue)target.Value;
                int     rvalue = 0;

                if (v is QsScalar)
                {
                    rvalue = (int)((QsScalar)v).NumericalQuantity.Value;
                }

                if (v is QsVector)
                {
                    rvalue = (int)((QsVector)v)[0].NumericalQuantity.Value;
                }

                if (v is QsMatrix)
                {
                    rvalue = (int)((QsMatrix)v)[0, 0].NumericalQuantity.Value;
                }

                return(target.Clone(Expression.Constant(rvalue, typeof(int))));
            }
            else
            {
                return(target.Clone(Expression.Constant(0, typeof(int))));
            }
        }
        public static DynamicMetaObject Restrict(this DynamicMetaObject self, Type type)
        {
            ContractUtils.RequiresNotNull(self, "self");
            ContractUtils.RequiresNotNull(type, "type");

            IRestrictedMetaObject rmo = self as IRestrictedMetaObject;

            if (rmo != null)
            {
                return(rmo.Restrict(type));
            }

            if (type == self.Expression.Type)
            {
                if (type.IsSealed ||
                    self.Expression.NodeType == ExpressionType.New ||
                    self.Expression.NodeType == ExpressionType.NewArrayBounds ||
                    self.Expression.NodeType == ExpressionType.NewArrayInit)
                {
                    return(self.Clone(self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, type))));
                }
            }

            if (type == typeof(DynamicNull))
            {
                return(self.Clone(
                           AstUtils.Constant(null),
                           self.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(self.Expression, null))
                           ));
            }

            Expression converted;

            // if we're converting to a value type just unbox to preserve
            // object identity.  If we're converting from Enum then we're
            // going to a specific enum value and an unbox is not allowed.
            if (type.IsValueType && self.Expression.Type != typeof(Enum))
            {
                converted = Expression.Unbox(
                    self.Expression,
                    CompilerHelpers.GetVisibleType(type)
                    );
            }
            else
            {
                converted = AstUtils.Convert(
                    self.Expression,
                    CompilerHelpers.GetVisibleType(type)
                    );
            }

            return(self.Clone(converted, self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, type))));
        }
Exemplo n.º 3
0
        internal static DynamicMetaObject /*!*/ ConvertComArgument(DynamicMetaObject /*!*/ arg)
        {
            Expression          expr = arg.Expression;
            BindingRestrictions restrictions;

            if (arg.Value != null)
            {
                Type type = arg.Value.GetType();
                if (type == typeof(BigInteger))
                {
                    expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(BigInteger)), typeof(double));
                }
                else if (type == typeof(MutableString))
                {
                    // TODO: encoding?
                    expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(MutableString)), typeof(string));
                }
                else if (type == typeof(RubySymbol))
                {
                    // TODO: encoding?
                    expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(RubySymbol)), typeof(string));
                }
                restrictions = BindingRestrictions.GetTypeRestriction(arg.Expression, type);
            }
            else
            {
                restrictions = BindingRestrictions.GetExpressionRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null)));
            }
            return(arg.Clone(expr, restrictions));
        }
Exemplo n.º 4
0
            public override DynamicMetaObject /*!*/ FallbackConvert(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion)
            {
#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryConvert(this, target, out result))
                {
                    return(result);
                }
#endif
                return(target.Clone(Ast.NewArrayInit(typeof(object), target.Expression)));
            }
Exemplo n.º 5
0
        /// <summary> if a member-injector is defined-on or registered-for this type call it </summary>
        private bool MakeOperatorSetMemberBody(SetOrDeleteMemberInfo memInfo, DynamicMetaObject self, DynamicMetaObject target, Type type, string name)
        {
            if (self != null)
            {
                MethodInfo setMem = GetMethod(type, name);
                if (setMem != null)
                {
                    ParameterExpression tmp = Ast.Variable(target.Expression.Type, "setValue");
                    memInfo.Body.AddVariable(tmp);

                    var callMo = MakeCallExpression(
                        memInfo.ResolutionFactory,
                        setMem,
                        self.Clone(AstUtils.Convert(self.Expression, type)),
                        new DynamicMetaObject(AstUtils.Constant(memInfo.Name), BindingRestrictions.Empty, memInfo.Name),
                        target.Clone(tmp)
                        );

                    var call = Ast.Block(Ast.Assign(tmp, target.Expression), callMo.Expression);

                    if (setMem.ReturnType == typeof(bool))
                    {
                        memInfo.Body.AddCondition(
                            call,
                            tmp
                            );
                    }
                    else
                    {
                        memInfo.Body.FinishCondition(Ast.Block(call, AstUtils.Convert(tmp, typeof(object))));
                    }

                    return(setMem.ReturnType != typeof(bool));
                }
            }

            return(false);
        }
        private static DynamicMetaObject/*!*/ GetGetOrDeleteSlice(PythonContext state, DynamicMetaObject/*!*/[]/*!*/ args) {
            DynamicMetaObject[] newArgs = (DynamicMetaObject[])args.Clone();
            for (int i = 1; i < newArgs.Length; i++) {
                if (!IsIndexType(state, newArgs[i])) {
                    newArgs[i] = newArgs[i].Restrict(newArgs[i].GetLimitType());
                }
            }

            return new DynamicMetaObject(
                Ast.Call(
                    typeof(PythonOps).GetMethod("MakeSlice"),
                    AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 1), typeof(object)),
                    AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 2), typeof(object)),
                    AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 3), typeof(object))
                ),
                BindingRestrictions.Combine(newArgs)
            );
        }
        private static DynamicMetaObject MakeUnindexableError(DynamicMetaObjectBinder operation, PythonIndexType op, DynamicMetaObject/*!*/[] types, DynamicMetaObject indexedType, PythonContext state) {
            DynamicMetaObject[] newTypes = (DynamicMetaObject[])types.Clone();
            newTypes[0] = indexedType;

            PythonTypeSlot dummySlot;
            if (op != PythonIndexType.GetItem &&
                op != PythonIndexType.GetSlice &&
                DynamicHelpers.GetPythonType(indexedType.Value).TryResolveSlot(state.SharedContext, "__getitem__", out dummySlot)) {
                // object supports indexing but not setting/deletion
                if (op == PythonIndexType.SetItem || op == PythonIndexType.SetSlice) {
                    return TypeError(operation, "'{0}' object does not support item assignment", newTypes);
                } else {
                    return TypeError(operation, "'{0}' object doesn't support item deletion", newTypes);
                }
            }
            return TypeError(operation, "'{0}' object is unsubscriptable", newTypes);
        }
        /// <summary>
        /// Python has three protocols for slicing:
        ///    Simple Slicing x[i:j]
        ///    Extended slicing x[i,j,k,...]
        ///    Long Slice x[start:stop:step]
        /// 
        /// The first maps to __*slice__ (get, set, and del).  
        ///    This takes indexes - i, j - which specify the range of elements to be
        ///    returned.  In the slice variants both i, j must be numeric data types.  
        /// The 2nd and 3rd are both __*item__.  
        ///    This receives a single index which is either a Tuple or a Slice object (which 
        ///    encapsulates the start, stop, and step values) 
        /// 
        /// This is in addition to a simple indexing x[y].
        /// 
        /// For simple slicing and long slicing Python generates Operators.*Slice.  For
        /// the extended slicing and simple indexing Python generates a Operators.*Item
        /// action.
        /// 
        /// Extended slicing maps to the normal .NET multi-parameter input.  
        /// 
        /// So our job here is to first determine if we're to call a __*slice__ method or
        /// a __*item__ method.  
        /// </summary>
        private static DynamicMetaObject/*!*/ MakeIndexerOperation(DynamicMetaObjectBinder/*!*/ operation, PythonIndexType op, DynamicMetaObject/*!*/[]/*!*/ types, DynamicMetaObject errorSuggestion) {
            string item, slice;
            DynamicMetaObject indexedType = types[0].Restrict(types[0].GetLimitType());
            PythonContext state = PythonContext.GetPythonContext(operation);
            BuiltinFunction itemFunc = null;
            PythonTypeSlot itemSlot = null;
            bool callSlice = false;
            int mandatoryArgs;

            GetIndexOperators(op, out item, out slice, out mandatoryArgs);

            if (types.Length == mandatoryArgs + 1 && IsSlice(op) && HasOnlyNumericTypes(operation, types, op == PythonIndexType.SetSlice)) {
                // two slice indexes, all int arguments, need to call __*slice__ if it exists
                callSlice = BindingHelpers.TryGetStaticFunction(state, slice, indexedType, out itemFunc);
                if (itemFunc == null || !callSlice) {
                    callSlice = MetaPythonObject.GetPythonType(indexedType).TryResolveSlot(state.SharedContext, slice, out itemSlot);
                }
            }

            if (!callSlice) {
                // 1 slice index (simple index) or multiple slice indexes or no __*slice__, call __*item__, 
                if (!BindingHelpers.TryGetStaticFunction(state, item, indexedType, out itemFunc)) {
                    MetaPythonObject.GetPythonType(indexedType).TryResolveSlot(state.SharedContext, item, out itemSlot);
                }
            }

            // make the Callable object which does the actual call to the function or slot
            Callable callable = Callable.MakeCallable(state, op, itemFunc, itemSlot);
            if (callable == null) {
                return errorSuggestion ?? MakeUnindexableError(operation, op, types, indexedType, state);
            }

            // prepare the arguments and make the builder which will
            // call __*slice__ or __*item__
            DynamicMetaObject[] args;
            IndexBuilder builder;
            if (callSlice) {
                // we're going to call a __*slice__ method, we pass the args as is.
                Debug.Assert(IsSlice(op));

                builder = new SliceBuilder(types, callable);

                // slicing is dependent upon the types of the arguments (HasNumericTypes) 
                // so we must restrict them.
                args = ConvertArgs(types);
            } else {
                // we're going to call a __*item__ method.
                builder = new ItemBuilder(types, callable);
                if (IsSlice(op)) {
                    // we need to create a new Slice object.
                    args = GetItemSliceArguments(state, op, types);
                } else {
                    // no need to restrict the arguments.  We're not
                    // a slice and so restrictions are not necessary
                    // here because it's not dependent upon our types.
                    args = (DynamicMetaObject[])types.Clone();

                    // but we do need to restrict based upon the type
                    // of object we're calling on.
                    args[0] = types[0].Restrict(types[0].GetLimitType());
                }

            }

            return builder.MakeRule(operation, state, args);
        }
Exemplo n.º 9
0
 public static DynamicMetaObject Clone(this DynamicMetaObject self, BindingRestrictions newRestrictions)
 {
     return(self.Clone(self.Expression, newRestrictions));
 }
Exemplo n.º 10
0
 public static DynamicMetaObject Clone(this DynamicMetaObject self, Expression newExpression)
 {
     return(self.Clone(newExpression, self.Restrictions));
 }