/// <summary>
        /// Helper to produce an error when a conversion cannot occur
        /// </summary>
        private DynamicMetaObject MakeErrorTarget(Type toType, ConversionResultKind kind, BindingRestrictions restrictions, DynamicMetaObject arg)
        {
            DynamicMetaObject target;

            switch (kind)
            {
            case ConversionResultKind.ImplicitCast:
            case ConversionResultKind.ExplicitCast:
                target = MakeError(
                    MakeConversionError(toType, arg.Expression),
                    restrictions,
                    toType
                    );
                break;

            case ConversionResultKind.ImplicitTry:
            case ConversionResultKind.ExplicitTry:
                target = new DynamicMetaObject(
                    GetTryConvertReturnValue(toType),
                    restrictions
                    );
                break;

            default:
                throw new InvalidOperationException(kind.ToString());
            }

            return(target);
        }
Exemplo n.º 2
0
        // TODO: revisit
        /// <summary>
        /// Converts the provided expression to the given type.  The expression is safe to evaluate multiple times.
        /// </summary>
        public virtual Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            ContractUtils.RequiresNotNull(expr, "expr");
            ContractUtils.RequiresNotNull(toType, "toType");

            Type exprType = expr.Type;

            if (toType == typeof(object))
            {
                if (exprType.IsValueType())
                {
                    return(AstUtils.Convert(expr, toType));
                }
                else
                {
                    return(expr);
                }
            }

            if (toType.IsAssignableFrom(exprType))
            {
                return(expr);
            }

            return(Expression.Convert(expr, CompilerHelpers.GetVisibleType(toType)));
        }
Exemplo n.º 3
0
        /// <summary>Helper to produce the rule for converting T to Nullable of T</summary>
        private static MSAst MakeConvertingToTToNullableOfTTarget(Type toType, ConversionResultKind kind, MSAst arg)
        {
            var valueType = toType.GetGenericArguments()[0];

            // ConvertSelfToT -> Nullable<T>
            if (kind == ConversionResultKind.ExplicitCast)
            {
                // if the conversion to T fails we just throw
                var conversion = ConvertExpression(arg, valueType);

                return(MSAst.New(
                           toType.GetConstructor(new[] { valueType }),
                           conversion));
            }
            else
            {
                var conversion = ConvertExpression(arg, valueType);

                // if the conversion to T succeeds then produce the nullable<T>, otherwise return default(retType)

                return(MSAst.Condition(
                           MSAst.NotEqual(
                               conversion,
                               AstUtils.Constant(null)),
                           MSAst.New(
                               toType.GetConstructor(new[] { valueType }),
                               MSAst.Convert(
                                   conversion,
                                   valueType)),
                           GetTryConvertReturnValue(toType)));
            }
        }
Exemplo n.º 4
0
        public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg, OverloadResolverFactory resolverFactory, DynamicMetaObject errorSuggestion) {
            ContractUtils.RequiresNotNull(toType, "toType");
            ContractUtils.RequiresNotNull(arg, "arg");

            Type knownType = arg.GetLimitType();

            // try all the conversions - first look for conversions against the expression type,
            // these can be done w/o any additional tests.  Then look for conversions against the 
            // restricted type.
            BindingRestrictions typeRestrictions = arg.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg.Expression, arg.GetLimitType()));

            DynamicMetaObject res = 
                TryConvertToObject(toType, arg.Expression.Type, arg, typeRestrictions) ??
                TryAllConversions(resolverFactory, toType, kind, arg.Expression.Type, typeRestrictions, arg) ??
                TryAllConversions(resolverFactory, toType, kind, arg.GetLimitType(), typeRestrictions, arg) ??
                errorSuggestion ??
                MakeErrorTarget(toType, kind, typeRestrictions, arg);

            if ((kind == ConversionResultKind.ExplicitTry || kind == ConversionResultKind.ImplicitTry) && toType.IsValueType) {
                res = new DynamicMetaObject(
                    AstUtils.Convert(
                        res.Expression,
                        typeof(object)
                    ),
                    res.Restrictions
                );
            }
            return res;
        }
Exemplo n.º 5
0
        /// <summary>Helper to produce a conversion rule by calling the helper method to do the convert</summary>
        private static MSAst MakeConversionTarget(
            ConversionResultKind kind, MethodTracker method, Type fromType, bool isImplicit, MSAst arg)
        {
            var param = AstUtils.Convert(arg, fromType);

            return(MakeConversionTargetWorker(kind, method, isImplicit, param));
        }
Exemplo n.º 6
0
        /// <summary>Helper to produce an error when a conversion cannot occur</summary>
        private static MSAst MakeErrorTarget(Type toType, ConversionResultKind kind, MSAst arg)
        {
            MSAst target;

            switch (kind)
            {
            case ConversionResultKind.ImplicitCast:
            case ConversionResultKind.ExplicitCast:
                //target = DefaultBinder.MakeError(
                //    _binder.Binder.MakeConversionError(toType, arg),
                //    toType);
                target = arg;
                break;

            case ConversionResultKind.ImplicitTry:
            case ConversionResultKind.ExplicitTry:
                target = GetTryConvertReturnValue(toType);
                break;

            default:
                throw new InvalidOperationException(kind.ToString());
            }

            return(target);
        }
Exemplo n.º 7
0
        private static Expression /*!*/ AddExtensibleSelfCheck(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, Expression /*!*/ callExpr)
        {
            ParameterExpression  tmp     = Ast.Variable(callExpr.Type, "tmp");
            ConversionResultKind resKind = GetResultKind(convertToAction);
            Type retType = (resKind == ConversionResultKind.ExplicitTry || resKind == ConversionResultKind.ImplicitTry) ? typeof(object) : toType;

            callExpr = Ast.Block(
                new ParameterExpression[] { tmp },
                Ast.Block(
                    Ast.Assign(tmp, callExpr),
                    Ast.Condition(
                        Ast.Equal(tmp, self.Expression),
                        AstUtils.Convert(
                            Ast.Property(
                                AstUtils.Convert(self.Expression, self.GetLimitType()),
                                self.GetLimitType().GetProperty("Value")
                                ),
                            retType
                            ),
                        Ast.Dynamic(
                            new PythonConversionBinder(
                                PythonContext.GetPythonContext(convertToAction),
                                toType,
                                GetResultKind(convertToAction)
                                ),
                            retType,
                            tmp
                            )
                        )
                    )
                );
            return(callExpr);
        }
Exemplo n.º 8
0
        public override Expression/*!*/ ConvertExpression(Expression/*!*/ expr, Type/*!*/ toType, ConversionResultKind kind, Expression context) {
            ContractUtils.RequiresNotNull(expr, "expr");
            ContractUtils.RequiresNotNull(toType, "toType");

            Type exprType = expr.Type;

            if (toType == typeof(object)) {
                if (exprType.IsValueType) {
                    return AstUtils.Convert(expr, toType);
                } else {
                    return expr;
                }
            }

            if (toType.IsAssignableFrom(exprType)) {
                return expr;
            }

            Type visType = CompilerHelpers.GetVisibleType(toType);

            if (exprType == typeof(PythonType) && visType == typeof(Type)) {
                return AstUtils.Convert(expr, visType); // use the implicit conversion
            }

            return Binders.Convert(
                context,
                _context.DefaultBinderState,
                visType,
                visType == typeof(char) ? ConversionResultKind.ImplicitCast : kind,
                expr
            );
        }
Exemplo n.º 9
0
        public ConversionBinder(BinderState/*!*/ state, Type/*!*/ type, ConversionResultKind resultKind)
            : base(type, resultKind == ConversionResultKind.ExplicitCast || resultKind == ConversionResultKind.ExplicitTry) {
            Assert.NotNull(state, type);

            _state = state;
            _kind = resultKind;
        }
Exemplo n.º 10
0
        internal SxeConvertBinder Convert(Type type, ConversionResultKind resultKind, OverloadResolverFactory resolverFactory)
        {
            if (_conversionBinders == null)
            {
                Interlocked.CompareExchange(
                    ref _conversionBinders,
                    new Dictionary <Type, SxeConvertBinder> [(int)ConversionResultKind.ExplicitTry + 1], // max conversion result kind
                    null
                    );
            }

            if (_conversionBinders[(int)resultKind] == null)
            {
                Interlocked.CompareExchange(
                    ref _conversionBinders[(int)resultKind],
                    new Dictionary <Type, SxeConvertBinder>(),
                    null
                    );
            }

            var binders = _conversionBinders[(int)resultKind];

            lock (binders)
            {
                SxeConvertBinder result;
                if (!binders.TryGetValue(type, out result))
                {
                    binders[type] = result = new SxeConvertBinder(this, type, resultKind, resolverFactory);
                }
                return(result);
            }
        }
Exemplo n.º 11
0
        internal DynamicMetaObjectBinder ConvertAndReturnObject(Type type, ConversionResultKind resultKind)
        {
            if (_convertRetObjectBinders == null)
            {
                Interlocked.CompareExchange(
                    ref _convertRetObjectBinders,
                    new Dictionary <Type, DynamicMetaObjectBinder> [(int)ConversionResultKind.ExplicitTry + 1], // max conversion result kind
                    null);
            }

            if (_convertRetObjectBinders[(int)resultKind] == null)
            {
                Interlocked.CompareExchange(
                    ref _convertRetObjectBinders[(int)resultKind],
                    new Dictionary <Type, DynamicMetaObjectBinder>(),
                    null);
            }

            var binder = _convertRetObjectBinders[(int)resultKind];

            lock (binder)
            {
                DynamicMetaObjectBinder result;
                if (!binder.TryGetValue(type, out result))
                {
                    binder[type] = result = new SxeConvertBinder(this, type, resultKind, _binder.Context.OverloadResolver);
                }

                return(result);
            }
        }
Exemplo n.º 12
0
        public override Ast ConvertExpression(Ast expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            Type exprType = expr.Type;
            Type visType = CompilerHelpers.GetVisibleType(toType);

            if (typeof(IFn).IsAssignableFrom(exprType) && typeof(Delegate).IsAssignableFrom(visType))
                return Ast.Call(typeof(Converter).GetMethod("ConvertToDelegate"), Ast.Convert(expr, typeof(IFn)), Expression.Constant(visType));

            // Follow through on our promise to convert IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            if (toType.IsGenericType && ! toType.IsAssignableFrom(expr.Type))
            {
                // The following is inspired by IronPython.Runtime.Binding.Python.ConversionBinder.FallbackConvert
                Type genTo = toType.GetGenericTypeDefinition();
                if ( genTo == typeof(IList<>))
                {
                    return MakeToGenericConversion(expr,toType,typeof(IList<object>),typeof(ListGenericWrapper<>));
                }
                else if (genTo == typeof(IDictionary<,>))
                {
                    return MakeToGenericConversion(expr,toType,typeof(IDictionary<object,object>),typeof(DictionaryGenericWrapper<,>));
                }
                else if (genTo == typeof(IEnumerable<>))
                {   
                    return MakeToGenericConversion(expr, toType, typeof(IEnumerable),typeof(IEnumerableOfTWrapper<>));
                }
            }

            return base.ConvertExpression(expr, toType, kind, resolverFactory);
        }
        public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg, OverloadResolverFactory resolverFactory, DynamicMetaObject errorSuggestion)
        {
            ContractUtils.RequiresNotNull(toType, nameof(toType));
            ContractUtils.RequiresNotNull(arg, nameof(arg));

            // try all the conversions - first look for conversions against the expression type,
            // these can be done w/o any additional tests.  Then look for conversions against the
            // restricted type.
            BindingRestrictions typeRestrictions = arg.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg.Expression, arg.GetLimitType()));

            DynamicMetaObject res =
                TryConvertToObject(toType, arg.Expression.Type, arg, typeRestrictions) ??
                TryAllConversions(resolverFactory, toType, kind, arg.Expression.Type, typeRestrictions, arg) ??
                TryAllConversions(resolverFactory, toType, kind, arg.GetLimitType(), typeRestrictions, arg) ??
                errorSuggestion ??
                MakeErrorTarget(toType, kind, typeRestrictions, arg);

            if ((kind == ConversionResultKind.ExplicitTry || kind == ConversionResultKind.ImplicitTry) && toType.IsValueType)
            {
                res = new DynamicMetaObject(
                    AstUtils.Convert(
                        res.Expression,
                        typeof(object)
                        ),
                    res.Restrictions
                    );
            }
            return(res);
        }
Exemplo n.º 14
0
        public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type toType, ConversionResultKind kind) {
            if (toType.IsSubclassOf(typeof(Delegate))) {
                return MakeDelegateTarget(binder, toType, Restrict(typeof(Method)));
            }

            return FallbackConvert(binder);
        }
Exemplo n.º 15
0
        public override Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            ContractUtils.RequiresNotNull(expr, "expr");
            ContractUtils.RequiresNotNull(toType, "toType");

            Type exprType = expr.Type;

            if (toType == typeof(object))
            {
                if (exprType.IsValueType())
                    return Utils.Convert(expr, toType);
                else
                    return expr;
            }

            if (toType.IsAssignableFrom(exprType))
                return expr;

            Type visType = Context.Binder.PrivateBinding ? toType : CompilerHelpers.GetVisibleType(toType);

            return Binders.Convert(
                _context,
                visType,
                kind,
                expr
            );
        }
Exemplo n.º 16
0
 public static MSAst Convert(BinderState binder, Type type, ConversionResultKind resultKind, MSAst target, OverloadResolverFactory resolverFactory)
 {
     return(MSAst.Dynamic(
                binder.Convert(type, resultKind, resolverFactory),
                type,
                target));
 }
Exemplo n.º 17
0
        /// <summary>Checks if there's a conversion to/from Nullable of T.</summary>
        private static MSAst TryNullableConversion(Type toType, ConversionResultKind kind, Type knownType, MSAst arg)
        {
            if (toType.IsGenericType && (toType.GetGenericTypeDefinition() == typeof(Nullable <>)))
            {
                if (knownType == typeof(DynamicNull))
                {
                    return(MakeNullToNullableOfTTarget(toType));
                }

                if (knownType == toType.GetGenericArguments()[0])
                {
                    return(MakeTToNullableOfTTarget(toType, knownType, arg));
                }

                if ((kind == ConversionResultKind.ExplicitCast) || (kind == ConversionResultKind.ExplicitTry))
                {
                    if (knownType != typeof(object))
                    {
                        // when doing an explicit cast we'll do things like int -> Nullable<float>
                        return(MakeConvertingToTToNullableOfTTarget(toType, kind, arg));
                    }
                }
            }

            return(null);
        }
Exemplo n.º 18
0
        public override Ast ConvertExpression(Ast expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            Type exprType = expr.Type;
            Type visType  = CompilerHelpers.GetVisibleType(toType);

            if (typeof(IFn).IsAssignableFrom(exprType) && typeof(Delegate).IsAssignableFrom(visType))
            {
                return(Ast.Call(typeof(Converter).GetMethod("ConvertToDelegate"), Ast.Convert(expr, typeof(IFn)), Expression.Constant(visType)));
            }

            // Follow through on our promise to convert IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            if (toType.IsGenericType && !toType.IsAssignableFrom(expr.Type))
            {
                // The following is inspired by IronPython.Runtime.Binding.Python.ConversionBinder.FallbackConvert
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == typeof(IList <>))
                {
                    return(MakeToGenericConversion(expr, toType, typeof(IList <object>), typeof(ListGenericWrapper <>)));
                }
                else if (genTo == typeof(IDictionary <,>))
                {
                    return(MakeToGenericConversion(expr, toType, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>)));
                }
                else if (genTo == typeof(IEnumerable <>))
                {
                    return(MakeToGenericConversion(expr, toType, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>)));
                }
            }

            return(base.ConvertExpression(expr, toType, kind, resolverFactory));
        }
Exemplo n.º 19
0
 /// <summary>
 /// Backwards compatible Convert for the old sites that need to flow CodeContext
 /// </summary>
 public static Expression/*!*/ Convert(Expression/*!*/ codeContext, PythonContext/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) {
     return Ast.Dynamic(
         binder.Convert(type, resultKind),
         type,
         target
     );
 }
Exemplo n.º 20
0
        /// <summary>
        /// Checks if there's a conversion to/from Nullable of T.
        /// </summary>
        private MetaObject TryNullableConversion(Type toType, ConversionResultKind kind, Type knownType, Restrictions restrictions, MetaObject arg)
        {
            if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (knownType == typeof(Null))
                {
                    // null -> Nullable<T>
                    return(MakeNullToNullableOfTTarget(toType, restrictions));
                }
                else if (knownType == toType.GetGenericArguments()[0])
                {
                    return(MakeTToNullableOfTTarget(toType, knownType, restrictions, arg));
                }
                else if (kind == ConversionResultKind.ExplicitCast || kind == ConversionResultKind.ExplicitTry)
                {
                    if (knownType != typeof(object))
                    {
                        // when doing an explicit cast we'll do things like int -> Nullable<float>
                        return(MakeConvertingToTToNullableOfTTarget(toType, kind, restrictions, arg));
                    }
                }
            }

            return(null);
        }
Exemplo n.º 21
0
        public static DynamicExpression ConvertTo(ActionBinder binder, Type toType, ConversionResultKind kind, Type actionExpressionType, params Expression[] arguments)
        {
            ContractUtils.RequiresNotNull(toType, "toType");
            ContractUtils.RequiresNotNull(arguments, "arguments");
            ContractUtils.Requires(arguments.Length > 0, "arguments");

            return(Expression.Dynamic(OldConvertToAction.Make(binder, toType, kind), actionExpressionType, arguments));
        }
Exemplo n.º 22
0
 public static Expression Convert(TotemContext state, Type type, ConversionResultKind kind, Expression target)
 {
     return DynamicExpression.Dynamic(
         state.Convert(type, kind),
         type,
         target
     );
 }
Exemplo n.º 23
0
        public PythonConversionBinder(PythonContext /*!*/ context, Type /*!*/ type, ConversionResultKind resultKind)
        {
            Assert.NotNull(context, type);

            _context = context;
            _kind    = resultKind;
            _type    = type;
        }
Exemplo n.º 24
0
 public override Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, Expression context)
 {
     if (toType.IsAssignableFrom(expr.Type))
     {
         return(expr);
     }
     return(Expression.Convert(expr, toType));
 }
Exemplo n.º 25
0
 public override Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, OverloadResolverFactory factory)
 {
     if (toType.IsAssignableFrom(expr.Type))
     {
         return(expr);
     }
     return(Ast.Utils.Convert(expr, toType));
 }
Exemplo n.º 26
0
 /// <summary>
 /// Checks if any conversions are available and if so builds the target for that conversion.
 /// </summary>
 private DynamicMetaObject TryAllConversions(Type toType, ConversionResultKind kind, Type knownType, BindingRestrictions restrictions, DynamicMetaObject arg) {
     return
         TryAssignableConversion(toType, knownType, restrictions, arg) ??           // known type -> known type
         TryExtensibleConversion(toType, knownType, restrictions, arg) ??           // Extensible<T> -> Extensible<T>.Value
         TryUserDefinedConversion(kind, toType, knownType, restrictions, arg) ??    // op_Implicit
         TryImplicitNumericConversion(toType, knownType, restrictions, arg) ??      // op_Implicit
         TryNullableConversion(toType, kind, knownType, restrictions, arg) ??       // null -> Nullable<T> or T -> Nullable<T>
         TryNullConversion(toType, knownType, restrictions);                        // null -> reference type
 }
Exemplo n.º 27
0
 private static CallSite <Func <CallSite, object, T> > MakeConvertSite <T>(ConversionResultKind kind)
 {
     return(CallSite <Func <CallSite, object, T> > .Create(
                DefaultContext.DefaultPythonContext.Convert(
                    typeof(T),
                    kind
                    )
                ));
 }
Exemplo n.º 28
0
        public TotemConversionBinder(TotemContext/*!*/ context, Type/*!*/ type, ConversionResultKind resultKind, bool retObj)
            : base(retObj ? typeof(object) : type, resultKind == ConversionResultKind.ExplicitCast || resultKind == ConversionResultKind.ExplicitTry)
        {
            Assert.NotNull(context);

            _context = context;
            _kind = resultKind;
            _retObject = retObj;
            _type = type;
        }
Exemplo n.º 29
0
 /// <summary>
 /// Checks if any conversions are available and if so builds the target for that conversion.
 /// </summary>
 private MetaObject TryAllConversions(Type toType, ConversionResultKind kind, Type knownType, Restrictions restrictions, MetaObject arg)
 {
     return
         (TryAssignableConversion(toType, knownType, restrictions, arg) ??          // known type -> known type
          TryExtensibleConversion(toType, knownType, restrictions, arg) ??          // Extensible<T> -> Extensible<T>.Value
          TryUserDefinedConversion(kind, toType, knownType, restrictions, arg) ??   // op_Implicit
          TryImplicitNumericConversion(toType, knownType, restrictions, arg) ??     // op_Implicit
          TryNullableConversion(toType, kind, knownType, restrictions, arg) ??      // null -> Nullable<T> or T -> Nullable<T>
          TryNullConversion(toType, knownType, restrictions));                      // null -> reference type
 }
Exemplo n.º 30
0
        public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type toType, ConversionResultKind kind) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Convert " + toType);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Convert");

            if (toType.IsSubclassOf(typeof(Delegate))) {
                return MakeDelegateTarget(binder, toType, Restrict(LimitType));
            }

            return FallbackConvert(binder);
        }
Exemplo n.º 31
0
        public override Ast ConvertExpression(Ast expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            Type exprType = expr.Type;
            Type visType = CompilerHelpers.GetVisibleType(toType);

            if (typeof(IFn).IsAssignableFrom(exprType) && typeof(Delegate).IsAssignableFrom(visType))
                return Ast.Call(typeof(Converter).GetMethod("ConvertToDelegate"), Ast.Convert(expr, typeof(IFn)), Expression.Constant(visType));

            return base.ConvertExpression(expr, toType, kind, resolverFactory);
        }
Exemplo n.º 32
0
 /// <summary>
 /// Backwards compatible Convert for the old sites that need to flow CodeContext
 /// </summary>
 public static Expression/*!*/ Convert(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) {
     return Ast.Dynamic(
         new ConversionBinder(
             binder,
             type,
             resultKind
         ),
         type,
         target
     );
 }
Exemplo n.º 33
0
 /// <summary>
 ///   Helper to produce a conversion rule by calling the method to do the convert.  This version takes the parameter
 ///   to be passed to the conversion function and we call it w/ our own value or w/ our Extensible.Value.
 /// </summary>
 private static MSAst MakeConversionTargetWorker(
     ConversionResultKind kind, MethodTracker method, bool isImplicit, MSAst param)
 {
     return(WrapForThrowingTry(
                kind,
                isImplicit,
                AstUtils.SimpleCallHelper(
                    method.Method,
                    param
                    ),
                method.Method.ReturnType));
 }
Exemplo n.º 34
0
        public override Ast ConvertExpression(Ast expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory)
        {
            Type exprType = expr.Type;
            Type visType  = CompilerHelpers.GetVisibleType(toType);

            if (typeof(IFn).IsAssignableFrom(exprType) && typeof(Delegate).IsAssignableFrom(visType))
            {
                return(Ast.Call(typeof(Converter).GetMethod("ConvertToDelegate"), Ast.Convert(expr, typeof(IFn)), Expression.Constant(visType)));
            }

            return(base.ConvertExpression(expr, toType, kind, resolverFactory));
        }
Exemplo n.º 35
0
        public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type type, Type retType, ConversionResultKind kind) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Conversion " + type.FullName);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Conversion");
            ValidationInfo typeTest = BindingHelpers.GetValidationInfo(this, Value.PythonType);

            return BindingHelpers.AddDynamicTestAndDefer(
                binder,
                TryPythonConversion(binder, type) ?? FallbackConvert(binder),
                new DynamicMetaObject[] { this },
                typeTest,
                retType
            );
        }
Exemplo n.º 36
0
        /// <summary>
        /// Helper that checkes both types to see if either one defines the specified conversion
        /// method.
        /// </summary>
        private DynamicMetaObject TryOneConversion(ConversionResultKind kind, Type toType, Type type, Type fromType, string methodName, bool isImplicit, BindingRestrictions restrictions, DynamicMetaObject arg)
        {
            MemberGroup       conversions = GetMember(MemberRequestKind.Convert, fromType, methodName);
            DynamicMetaObject res         = TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg);

            if (res != null)
            {
                return(res);
            }

            // then on the type we're trying to convert to
            conversions = GetMember(MemberRequestKind.Convert, toType, methodName);
            return(TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg));
        }
 /// <summary>
 /// Helper to produce a conversion rule by calling the method to do the convert.  This version takes the parameter
 /// to be passed to the conversion function and we call it w/ our own value or w/ our Extensible.Value.
 /// </summary>
 private static DynamicMetaObject MakeConversionTargetWorker(ConversionResultKind kind, MethodTracker method, bool isImplicit, BindingRestrictions restrictions, Expression param)
 {
     return(new DynamicMetaObject(
                WrapForThrowingTry(
                    kind,
                    isImplicit,
                    AstUtils.SimpleCallHelper(
                        method.Method,
                        param
                        ),
                    method.Method.ReturnType
                    ),
                restrictions
                ));
 }
Exemplo n.º 38
0
        /// <summary>
        /// Helper that checkes both types to see if either one defines the specified conversion
        /// method.
        /// </summary>
        private MetaObject TryOneConversion(ConversionResultKind kind, Type toType, Type type, Type fromType, string methodName, bool isImplicit, Restrictions restrictions, MetaObject arg)
        {
            OldConvertToAction action = OldConvertToAction.Make(this, toType, kind);

            MemberGroup conversions = GetMember(action, fromType, methodName);
            MetaObject  res         = TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg);

            if (res != null)
            {
                return(res);
            }

            // then on the type we're trying to convert to
            conversions = GetMember(action, toType, methodName);
            return(TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg));
        }
Exemplo n.º 39
0
        public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg) {
            ContractUtils.RequiresNotNull(toType, "toType");
            ContractUtils.RequiresNotNull(arg, "arg");

            Type knownType = arg.GetLimitType();

            // try all the conversions - first look for conversions against the expression type,
            // these can be done w/o any additional tests.  Then look for conversions against the 
            // restricted type.
            BindingRestrictions typeRestrictions = arg.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg.Expression, arg.GetLimitType()));

            return
                TryConvertToObject(toType, arg.Expression.Type, arg) ??
                TryAllConversions(toType, kind, arg.Expression.Type, arg.Restrictions, arg) ??
                TryAllConversions(toType, kind, arg.GetLimitType(), typeRestrictions, arg) ??
                MakeErrorTarget(toType, kind, typeRestrictions, arg);
        }
Exemplo n.º 40
0
        /// <summary>
        /// Helper to produce the rule for converting T to Nullable of T
        /// </summary>
        private MetaObject MakeConvertingToTToNullableOfTTarget(Type toType, ConversionResultKind kind, Restrictions restrictions, MetaObject arg)
        {
            Type valueType = toType.GetGenericArguments()[0];

            // ConvertSelfToT -> Nullable<T>
            if (kind == ConversionResultKind.ExplicitCast)
            {
                // if the conversion to T fails we just throw
                Expression conversion = ConvertExpression(arg.Expression, valueType, kind, Ast.Constant(null, typeof(CodeContext)));

                return(new MetaObject(
                           Ast.New(
                               toType.GetConstructor(new Type[] { valueType }),
                               conversion
                               ),
                           restrictions
                           ));
            }
            else
            {
                Expression conversion = ConvertExpression(arg.Expression, valueType, kind, Ast.Constant(null, typeof(CodeContext)));

                // if the conversion to T succeeds then produce the nullable<T>, otherwise return default(retType)
                ParameterExpression tmp = Ast.Variable(typeof(object), "tmp");
                return(new MetaObject(
                           Ast.Block(
                               new ParameterExpression[] { tmp },
                               Ast.Condition(
                                   Ast.NotEqual(
                                       Ast.Assign(tmp, conversion),
                                       Ast.Constant(null)
                                       ),
                                   Ast.New(
                                       toType.GetConstructor(new Type[] { valueType }),
                                       Ast.Convert(
                                           tmp,
                                           valueType
                                           )
                                       ),
                                   GetTryConvertReturnValue(toType)
                                   )
                               ),
                           restrictions
                           ));
            }
        }
Exemplo n.º 41
0
        public MetaObject ConvertTo(Type toType, ConversionResultKind kind, MetaObject arg)
        {
            ContractUtils.RequiresNotNull(toType, "toType");
            ContractUtils.RequiresNotNull(arg, "arg");

            Type knownType = arg.LimitType;

            // try all the conversions - first look for conversions against the expression type,
            // these can be done w/o any additional tests.  Then look for conversions against the
            // restricted type.
            Restrictions typeRestrictions = arg.Restrictions.Merge(Restrictions.GetTypeRestriction(arg.Expression, arg.LimitType));

            return
                (TryConvertToObject(toType, arg.Expression.Type, arg) ??
                 TryAllConversions(toType, kind, arg.Expression.Type, arg.Restrictions, arg) ??
                 TryAllConversions(toType, kind, arg.LimitType, typeRestrictions, arg) ??
                 MakeErrorTarget(toType, kind, typeRestrictions, arg));
        }
Exemplo n.º 42
0
        /// <summary>Checks if the conversion can be handled by calling a user-defined conversion method.</summary>
        internal MSAst TryUserDefinedConversion(ConversionResultKind kind, Type toType, Type type, MSAst arg)
        {
            var fromType = GetUnderlyingType(type);

            var res = TryOneConversion(kind, toType, type, fromType, "op_Implicit", true, arg) ??
                      TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, true, arg);

            if (kind == ConversionResultKind.ExplicitCast ||
                kind == ConversionResultKind.ExplicitTry)
            {
                // finally try explicit conversions
                res = res ??
                      TryOneConversion(kind, toType, type, fromType, "op_Explicit", false, arg) ??
                      TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, false, arg);
            }

            return(res);
        }
Exemplo n.º 43
0
        /// <summary>
        /// Checks if the conversion can be handled by calling a user-defined conversion method.
        /// </summary>
        private DynamicMetaObject TryUserDefinedConversion(ConversionResultKind kind, Type toType, Type type, BindingRestrictions restrictions, DynamicMetaObject arg)
        {
            Type fromType = GetUnderlyingType(type);

            DynamicMetaObject res =
                TryOneConversion(kind, toType, type, fromType, "op_Implicit", true, restrictions, arg) ??
                TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, true, restrictions, arg);

            if (kind == ConversionResultKind.ExplicitCast ||
                kind == ConversionResultKind.ExplicitTry)
            {
                // finally try explicit conversions
                res = res ??
                      TryOneConversion(kind, toType, type, fromType, "op_Explicit", false, restrictions, arg) ??
                      TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, false, restrictions, arg);
            }

            return(res);
        }
 /// <summary>
 /// Helper to wrap explicit conversion call into try/catch incase it throws an exception.  If
 /// it throws the default value is returned.
 /// </summary>
 private static Expression WrapForThrowingTry(ConversionResultKind kind, bool isImplicit, Expression ret, Type retType)
 {
     if (!isImplicit && kind == ConversionResultKind.ExplicitTry)
     {
         Expression          convFailed = GetTryConvertReturnValue(retType);
         ParameterExpression tmp        = Expression.Variable(convFailed.Type == typeof(object) ? typeof(object) : ret.Type, "tmp");
         ret = Expression.Block(
             new ParameterExpression[] { tmp },
             AstUtils.Try(
                 Expression.Assign(tmp, AstUtils.Convert(ret, tmp.Type))
                 ).Catch(
                 typeof(Exception),
                 Expression.Assign(tmp, convFailed)
                 ),
             tmp
             );
     }
     return(ret);
 }
Exemplo n.º 45
0
        /// <summary>
        /// Converts the provided expression to the given type.  The expression is safe to evaluate multiple times.
        /// </summary>
        public virtual Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, Expression context)
        {
            ContractUtils.RequiresNotNull(expr, "expr");
            ContractUtils.RequiresNotNull(toType, "toType");

            Type exprType = expr.Type;

            if (toType == typeof(object))
            {
                if (exprType.IsValueType)
                {
                    return(Expression.Convert(expr, toType));
                }
                else
                {
                    return(expr);
                }
            }

            if (toType.IsAssignableFrom(exprType))
            {
                return(expr);
            }

            Type visType = CompilerHelpers.GetVisibleType(toType);

            Expression[] args;
            if (context != null)
            {
                args = new Expression[] { context, expr };
            }
            else
            {
                args = new Expression[] { expr };
            }

            return(Expression.Dynamic(
                       OldConvertToAction.Make(this, visType, kind),
                       visType,
                       args
                       ));
        }
Exemplo n.º 46
0
 /// <summary>
 /// Helper to wrap explicit conversion call into try/catch incase it throws an exception.  If
 /// it throws the default value is returned.
 /// </summary>
 private static Expression WrapForThrowingTry(ConversionResultKind kind, bool isImplicit, Expression ret, Type retType) {
     if (!isImplicit && kind == ConversionResultKind.ExplicitTry) {
         Expression convFailed = GetTryConvertReturnValue(retType);
         ParameterExpression tmp = Ast.Variable(convFailed.Type == typeof(object) ? typeof(object) : ret.Type, "tmp");
         ret = Ast.Block(
                 new ParameterExpression[] { tmp },
                 AstUtils.Try(
                     Ast.Assign(tmp, AstUtils.Convert(ret, tmp.Type))
                 ).Catch(
                     typeof(Exception),
                     Ast.Assign(tmp, convFailed)
                 ),
                 tmp
              );
     }
     return ret;
 }
Exemplo n.º 47
0
        /// <summary>
        /// Helper that checkes both types to see if either one defines the specified conversion
        /// method.
        /// </summary>
        private DynamicMetaObject TryOneConversion(ConversionResultKind kind, Type toType, Type type, Type fromType, string methodName, bool isImplicit, BindingRestrictions restrictions, DynamicMetaObject arg) {
            MemberGroup conversions = GetMember(MemberRequestKind.Convert, fromType, methodName);
            DynamicMetaObject res = TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg);
            if (res != null) {
                return res;
            }

            // then on the type we're trying to convert to
            conversions = GetMember(MemberRequestKind.Convert, toType, methodName);
            return TryUserDefinedConversion(kind, toType, type, conversions, isImplicit, restrictions, arg);
        }
Exemplo n.º 48
0
 public MSAst.Expression/*!*/ Convert(Type/*!*/ type, ConversionResultKind resultKind, MSAst.Expression/*!*/ target) {
     return Globals.Dynamic(
         BinderState.Convert(
             type,
             resultKind
         ),
         type,
         target
     );
 }
Exemplo n.º 49
0
        /// <summary>
        /// Checks if any of the members of the MemberGroup provide the applicable conversion and 
        /// if so uses it to build a conversion rule.
        /// </summary>
        private static DynamicMetaObject TryUserDefinedConversion(ConversionResultKind kind, Type toType, Type type, MemberGroup conversions, bool isImplicit, BindingRestrictions restrictions, DynamicMetaObject arg) {
            Type checkType = GetUnderlyingType(type);

            foreach (MemberTracker mt in conversions) {
                if (mt.MemberType != TrackerTypes.Method) continue;

                MethodTracker method = (MethodTracker)mt;

                if (isImplicit && method.Method.IsDefined(typeof(ExplicitConversionMethodAttribute), true)) {
                    continue;
                }

                if (method.Method.ReturnType == toType) {   // TODO: IsAssignableFrom?  IsSubclass?
                    ParameterInfo[] pis = method.Method.GetParameters();

                    if (pis.Length == 1 && pis[0].ParameterType.IsAssignableFrom(checkType)) {
                        // we can use this method
                        if (type == checkType) {
                            return MakeConversionTarget(kind, method, type, isImplicit, restrictions, arg);
                        } else {
                            return MakeExtensibleConversionTarget(kind, method, type, isImplicit, restrictions, arg);
                        }
                    }
                }
            }
            return null;
        }
Exemplo n.º 50
0
        /// <summary>
        /// Helper to produce the rule for converting T to Nullable of T
        /// </summary>
        private DynamicMetaObject MakeConvertingToTToNullableOfTTarget(OverloadResolverFactory resolverFactory, Type toType, ConversionResultKind kind, BindingRestrictions restrictions, DynamicMetaObject arg) {
            Type valueType = toType.GetGenericArguments()[0];

            // ConvertSelfToT -> Nullable<T>
            if (kind == ConversionResultKind.ExplicitCast) {
                // if the conversion to T fails we just throw
                Expression conversion = ConvertExpression(arg.Expression, valueType, kind, resolverFactory);

                return new DynamicMetaObject(
                    Ast.New(
                        toType.GetConstructor(new Type[] { valueType }),
                        conversion
                    ),
                    restrictions
                );
            } else {
                Expression conversion = ConvertExpression(arg.Expression, valueType, kind, resolverFactory);

                // if the conversion to T succeeds then produce the nullable<T>, otherwise return default(retType)
                ParameterExpression tmp = Ast.Variable(typeof(object), "tmp");
                return new DynamicMetaObject(
                    Ast.Block(
                        new ParameterExpression[] { tmp },
                        Ast.Condition(
                            Ast.NotEqual(
                                Ast.Assign(tmp, conversion),
                                AstUtils.Constant(null)
                            ),
                            Ast.New(
                                toType.GetConstructor(new Type[] { valueType }),
                                Ast.Convert(
                                    tmp,
                                    valueType
                                )
                            ),
                            GetTryConvertReturnValue(toType)
                        )
                    ),
                    restrictions
                );
            }
        }
Exemplo n.º 51
0
        /// <summary>
        /// Checks if the conversion can be handled by calling a user-defined conversion method.
        /// </summary>
        private DynamicMetaObject TryUserDefinedConversion(ConversionResultKind kind, Type toType, Type type, BindingRestrictions restrictions, DynamicMetaObject arg) {
            Type fromType = GetUnderlyingType(type);

            DynamicMetaObject res =
                   TryOneConversion(kind, toType, type, fromType, "op_Implicit", true, restrictions, arg) ??
                   TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, true, restrictions, arg);

            if (kind == ConversionResultKind.ExplicitCast ||
                kind == ConversionResultKind.ExplicitTry) {
                // finally try explicit conversions
                res = res ??
                    TryOneConversion(kind, toType, type, fromType, "op_Explicit", false, restrictions, arg) ??
                    TryOneConversion(kind, toType, type, fromType, "ConvertTo" + toType.Name, false, restrictions, arg);
            }

            return res;
        }
Exemplo n.º 52
0
        /// <summary>
        /// Checks if there's a conversion to/from Nullable of T.
        /// </summary>
        private DynamicMetaObject TryNullableConversion(OverloadResolverFactory factory, Type toType, ConversionResultKind kind, Type knownType, BindingRestrictions restrictions, DynamicMetaObject arg) {
            if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                if (knownType == typeof(DynamicNull)) {
                    // null -> Nullable<T>
                    return MakeNullToNullableOfTTarget(toType, restrictions);
                } else if (knownType == toType.GetGenericArguments()[0]) {
                    return MakeTToNullableOfTTarget(toType, knownType, restrictions, arg);
                } else if (kind == ConversionResultKind.ExplicitCast || kind == ConversionResultKind.ExplicitTry) {
                    if (knownType != typeof(object)) {
                        // when doing an explicit cast we'll do things like int -> Nullable<float>
                        return MakeConvertingToTToNullableOfTTarget(factory, toType, kind, restrictions, arg);
                    }
                }
            }

            return null;
        }
Exemplo n.º 53
0
 /// <summary>
 /// Helper to produce a conversion rule by calling the method to do the convert.  This version takes the parameter
 /// to be passed to the conversion function and we call it w/ our own value or w/ our Extensible.Value.
 /// </summary>
 private static DynamicMetaObject MakeConversionTargetWorker(ConversionResultKind kind, MethodTracker method, bool isImplicit, BindingRestrictions restrictions, Expression param) {
     return new DynamicMetaObject(
         WrapForThrowingTry(
             kind,
             isImplicit,
             AstUtils.SimpleCallHelper(
                 method.Method,
                 param
             ),
             method.Method.ReturnType
         ),
         restrictions
     );
 }
Exemplo n.º 54
0
 /// <summary>
 /// Helper to produce a conversion rule by calling the helper method to do the convert
 /// </summary>
 private static DynamicMetaObject MakeExtensibleConversionTarget(ConversionResultKind kind, MethodTracker method, Type fromType, bool isImplicit, BindingRestrictions restrictions, DynamicMetaObject arg) {
     return MakeConversionTargetWorker(kind, method, isImplicit, restrictions, GetExtensibleValue(fromType, arg));
 }
Exemplo n.º 55
0
        /// <summary>
        /// Helper to produce a conversion rule by calling the helper method to do the convert
        /// </summary>
        private static DynamicMetaObject MakeConversionTarget(ConversionResultKind kind, MethodTracker method, Type fromType, bool isImplicit, BindingRestrictions restrictions, DynamicMetaObject arg) {
            Expression param = AstUtils.Convert(arg.Expression, fromType);

            return MakeConversionTargetWorker(kind, method, isImplicit, restrictions, param);
        }
Exemplo n.º 56
0
        /// <summary>
        /// Helper to produce an error when a conversion cannot occur
        /// </summary>
        private DynamicMetaObject MakeErrorTarget(Type toType, ConversionResultKind kind, BindingRestrictions restrictions, DynamicMetaObject arg) {
            DynamicMetaObject target;

            switch (kind) {
                case ConversionResultKind.ImplicitCast:
                case ConversionResultKind.ExplicitCast:
                    target = MakeError(
                        MakeConversionError(toType, arg.Expression),
                        restrictions,
                        toType
                    );
                    break;
                case ConversionResultKind.ImplicitTry:
                case ConversionResultKind.ExplicitTry:
                    target = new DynamicMetaObject(
                        GetTryConvertReturnValue(toType),
                        restrictions
                    );
                    break;
                default:
                    throw new InvalidOperationException(kind.ToString());
            }

            return target;
        }
Exemplo n.º 57
0
        public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type type, Type retType, ConversionResultKind kind) {
            if (!type.IsEnum) {
                switch (Type.GetTypeCode(type)) {
                    case TypeCode.Boolean:
                        return MakeConvertToBool(binder);
                    case TypeCode.Int32:
                        return MakeConvertToCommon(binder, type, retType, "__int__");
                    case TypeCode.Double:
                        return MakeConvertToCommon(binder, type, retType, "__float__");
                    case TypeCode.String:
                        return MakeConvertToCommon(binder, type, retType, "__str__");
                    case TypeCode.Object:
                        if (type == typeof(BigInteger)) {
                            return MakeConvertToCommon(binder, type, retType, "__long__");
                        } else if (type == typeof(Complex64)) {
                            return MakeConvertToCommon(binder, type, retType, "__complex__");
                        } else if (type == typeof(IEnumerable)) {
                            return MakeConvertToIEnumerable(binder);
                        } else if (type == typeof(IEnumerator)) {
                            return MakeConvertToIEnumerator(binder);
                        } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
                            return MakeConvertToIEnumerable(binder, type, type.GetGenericArguments()[0]);
                        } else if (type.IsSubclassOf(typeof(Delegate))) {
                            return MakeDelegateTarget(binder, type, Restrict(typeof(OldInstance)));
                        }

                        break;
                }
            }

            return FallbackConvert(binder);
        }
Exemplo n.º 58
0
 public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg) {
     return ConvertTo(toType, kind, arg, new DefaultOverloadResolverFactory(this));
 }
Exemplo n.º 59
0
 public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg, OverloadResolverFactory resolverFactory) {
     return ConvertTo(toType, kind, arg, resolverFactory, null);
 }
Exemplo n.º 60
0
 public override Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, OverloadResolverFactory context) {
     throw new InvalidOperationException("OBSOLETE");
 }