Ejemplo n.º 1
0
        private DynamicMetaObject TryPythonConversion(DynamicMetaObjectBinder conversion, Type type)
        {
            if (!type.IsEnum)
            {
                switch (type.GetTypeCode())
                {
                case TypeCode.Object:
                    if (type == typeof(Complex))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__complex__", "ConvertToComplex",
                                                      (() => MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat",
                                                                                    (() => FallbackConvert(conversion)),
                                                                                    (x) => Ast.Call(null, typeof(PythonOps).GetMethod(nameof(PythonOps.ConvertFloatToComplex)), x))),
                                                      (x) => x));
                    }
                    else if (type == typeof(BigInteger))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__long__", "ConvertToLong"));
                    }
                    else if (type == typeof(IEnumerable))
                    {
                        return(PythonConversionBinder.ConvertToIEnumerable(conversion, Restrict(Value.GetType())));
                    }
                    else if (type == typeof(IEnumerator))
                    {
                        return(PythonConversionBinder.ConvertToIEnumerator(conversion, Restrict(Value.GetType())));
                    }
                    else if (type.IsSubclassOf(typeof(Delegate)))
                    {
                        return(MakeDelegateTarget(conversion, type, Restrict(Value.GetType())));
                    }
                    break;

                case TypeCode.Int32:
                    if (!typeof(Extensible <int>).IsAssignableFrom(LimitType))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__int__", "ConvertToInt"));
                    }
                    break;

                case TypeCode.Double:
                    return(MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat"));

                case TypeCode.Boolean:
                    return(PythonProtocol.ConvertToBool(
                               conversion,
                               this
                               ));

                case TypeCode.String:
                    if (!typeof(Extensible <string>).IsAssignableFrom(LimitType))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__str__", "ConvertToString"));
                    }
                    break;
                }
            }

            return(null);
        }
Ejemplo n.º 2
0
        private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ action, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args)
        {
            ValidationInfo typeTest = BindingHelpers.GetValidationInfo(this, Value.PythonType);

            if (Value is PythonType)
            {
                PythonContext context = PythonContext.GetPythonContext(action);
                // optimization for meta classes.  Don't dispatch to type.__call__ if it's inherited,
                // instead produce a normal type call rule.
                PythonTypeSlot callSlot, typeCallSlot;
                if (Value.PythonType.TryResolveMixedSlot(context.SharedContext, "__call__", out callSlot) &&
                    TypeCache.PythonType.TryResolveSlot(context.SharedContext, "__call__", out typeCallSlot) &&
                    callSlot == typeCallSlot)
                {
                    return(InvokeFallback(action, codeContext, args));
                }
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       action,
                       PythonProtocol.Call(action, this, args) ?? InvokeFallback(action, codeContext, args),
                       args,
                       typeTest
                       ));
        }
Ejemplo n.º 3
0
 internal DynamicMetaObject /*!*/ InvokeFallback(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, CallSignature sig, DynamicMetaObject errorSuggestion)
 {
     return
         (PythonProtocol.Call(this, target, args) ??
          Context.Binder.Create(sig, target, args, AstUtils.Constant(_context.SharedContext)) ??
          Context.Binder.Call(sig, errorSuggestion, new PythonOverloadResolverFactory(Context.Binder, AstUtils.Constant(_context.SharedContext)), target, args));
 }
Ejemplo n.º 4
0
        private DynamicMetaObject /*!*/ MakeToBoolConversion(DynamicMetaObject /*!*/ self)
        {
            DynamicMetaObject res;

            if (self.HasValue)
            {
                self = self.Restrict(self.GetRuntimeType());
            }

            // Optimization: if we already boxed it to a bool, and now
            // we're unboxing it, remove the unnecessary box.
            if (self.Expression.NodeType == ExpressionType.Convert && self.Expression.Type == typeof(object))
            {
                var convert = (UnaryExpression)self.Expression;
                if (convert.Operand.Type == typeof(bool))
                {
                    return(new DynamicMetaObject(convert.Operand, self.Restrictions));
                }
            }

            if (self.GetLimitType() == typeof(DynamicNull))
            {
                // None has no __nonzero__ and no __len__ but it's always false
                res = MakeNoneToBoolConversion(self);
            }
            else if (self.GetLimitType() == typeof(bool))
            {
                // nothing special to convert from bool to bool
                res = self;
            }
            else if (typeof(IStrongBox).IsAssignableFrom(self.GetLimitType()))
            {
                // Explictly block conversion of References to bool
                res = MakeStrongBoxToBoolConversionError(self);
            }
            else if (self.GetLimitType().IsPrimitive || self.GetLimitType().IsEnum)
            {
                // optimization - rather than doing a method call for primitives and enums generate
                // the comparison to zero directly.
                res = MakePrimitiveToBoolComparison(self);
            }
            else
            {
                // anything non-null that doesn't fall under one of the above rules is true.  So we
                // fallback to the base Python conversion which will check for __nonzero__ and
                // __len__.  The fallback is handled by our ConvertTo site binder.
                return
                    (PythonProtocol.ConvertToBool(this, self) ??
                     new DynamicMetaObject(
                         AstUtils.Constant(true),
                         self.Restrictions
                         ));
            }

            return(res);
        }
Ejemplo n.º 5
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            switch (action.Operation)
            {
            case PythonOperationKind.CallSignatures:
                return(PythonProtocol.MakeCallSignatureOperation(this, Value.Template.Targets));
            }

            return(null);
        }
Ejemplo n.º 6
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Operation " + action.Operation);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Operation");
            switch (action.Operation) {
                case PythonOperationKind.CallSignatures:
                    return PythonProtocol.MakeCallSignatureOperation(this, Value.Targets);
            }

            return null;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Fallback - performs the default binding operation if the object isn't recognized
        /// as being invokable.
        /// </summary>
        internal DynamicMetaObject /*!*/ Fallback(Expression codeContext, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            if (target.NeedsDeferral())
            {
                return(Defer(args));
            }

            return(PythonProtocol.Call(this, target, args) ??
                   Context.Binder.Create(Signature, target, args, codeContext) ??
                   Context.Binder.Call(Signature, new PythonOverloadResolverFactory(Context.Binder, codeContext), target, args));
        }
Ejemplo n.º 8
0
        public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
        {
#if !SILVERLIGHT
            DynamicMetaObject com;
            if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetIndex(this, target, BindingHelpers.GetComArguments(indexes), out com))
            {
                return(com);
            }
#endif
            return(PythonProtocol.Index(this, PythonIndexType.GetItem, ArrayUtils.Insert(target, indexes), errorSuggestion));
        }
Ejemplo n.º 9
0
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            if (target is IPythonOperable op)
            {
                DynamicMetaObject res = op.BindOperation(this, ArrayUtils.Insert(target, args));
                if (res != null)
                {
                    return(res);
                }
            }

            return(PythonProtocol.Operation(this, ArrayUtils.Insert(target, args)));
        }
Ejemplo n.º 10
0
        public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
        {
#if FEATURE_COM
            DynamicMetaObject com;
            if (Microsoft.Scripting.ComInterop.ComBinder.TryBindSetIndex(this, target, BindingHelpers.GetComArguments(indexes), BindingHelpers.GetComArgument(value), out com))
            {
                return(com);
            }
#endif

            DynamicMetaObject[] finalArgs = new DynamicMetaObject[indexes.Length + 2];
            finalArgs[0] = target;
            for (int i = 0; i < indexes.Length; i++)
            {
                finalArgs[i + 1] = indexes[i];
            }
            finalArgs[finalArgs.Length - 1] = value;

            return(PythonProtocol.Index(this, PythonIndexType.SetItem, finalArgs, errorSuggestion));
        }
Ejemplo n.º 11
0
 public override DynamicMetaObject /*!*/ BindSetIndex(SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass SetIndex" + indexes.Length);
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass SetIndex");
     return(PythonProtocol.Index(binder, PythonIndexType.SetItem, ArrayUtils.Insert(this, ArrayUtils.Append(indexes, value))));
 }
Ejemplo n.º 12
0
 public override DynamicMetaObject /*!*/ BindUnaryOperation(UnaryOperationBinder /*!*/ binder)
 {
     return(PythonProtocol.Operation(binder, this, null));
 }
Ejemplo n.º 13
0
 public override DynamicMetaObject /*!*/ BindDeleteIndex(DeleteIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes)
 {
     return(PythonProtocol.Index(binder, PythonIndexType.DeleteItem, ArrayUtils.Insert(this, indexes)));
 }
Ejemplo n.º 14
0
 public override DynamicMetaObject /*!*/ BindSetIndex(SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value)
 {
     return(PythonProtocol.Index(binder, PythonIndexType.SetItem, ArrayUtils.Insert(this, ArrayUtils.Append(indexes, value))));
 }
Ejemplo n.º 15
0
 public override DynamicMetaObject FallbackDeleteIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
 {
     return(PythonProtocol.Index(this, PythonIndexType.DeleteItem, ArrayUtils.Insert(target, indexes), errorSuggestion));
 }
Ejemplo n.º 16
0
 public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
 {
     return(PythonProtocol.Index(this, PythonIndexType.DeleteSlice, ArrayUtils.Insert(target, args)));
 }
 public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
 {
     return(PythonProtocol.Operation(this, target, arg, errorSuggestion));
 }
Ejemplo n.º 18
0
 public override DynamicMetaObject /*!*/ BindUnaryOperation(UnaryOperationBinder /*!*/ binder)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass UnaryOperation" + binder.Operation);
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass UnaryOperation");
     return(PythonProtocol.Operation(binder, this, null));
 }
Ejemplo n.º 19
0
 public override DynamicMetaObject /*!*/ BindDeleteIndex(DeleteIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass DeleteIndex" + indexes.Length);
     PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass DeleteIndex");
     return(PythonProtocol.Index(binder, PythonIndexType.DeleteItem, ArrayUtils.Insert(this, indexes)));
 }