Dynamic() public static method

Creates a DynamicExpression that represents a dynamic operation bound by the provided CallSiteBinder.
The DelegateType property of the result will be inferred from the types of the arguments and the specified return type.
public static Dynamic ( CallSiteBinder binder, Type returnType ) : DynamicExpression
binder CallSiteBinder The runtime binder for the dynamic operation.
returnType Type The result type of the dynamic expression.
return DynamicExpression
Ejemplo n.º 1
0
        private object CastResult(object result, Type targetType)
        {
            if (result == null || result == DependencyProperty.UnsetValue || result == System.Windows.Data.Binding.DoNothing || targetType == null || targetType == typeof(object))
            {
                return(result);
            }

            if (targetType == typeof(string))
            {
                return(result.ToString());
            }

            Func <object, object> cast;

            if (!castFunctions.TryGetValue(targetType, out cast))
            {
                ParameterExpression par = Expression.Parameter(typeof(object));
                cast = Expression.Lambda <Func <object, object> >(Expression.Convert(Expression.Dynamic(Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, typeof(object)), targetType, par), typeof(object)), par).Compile();
                castFunctions.TryAdd(targetType, cast);
            }
            if (cast != null)
            {
                try
                {
                    result = cast(result);
                }
                catch
                {
                    castFunctions[targetType] = null;
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
            protected override MSA.Expression /*!*/ VisitDynamic(MSA.DynamicExpression /*!*/ node)
            {
                var callAction = node.Binder as RubyCallAction;

                if (callAction != null)
                {
                    var args = new MSA.Expression[node.Arguments.Count];

                    for (int i = 0; i < args.Length; i++)
                    {
                        args[i] = node.Arguments[i];
                    }

                    Debug.Assert(args.Length > 0);
                    int last = args.Length - 1;

                    args[last] = typeof(TracingRubyCallAction).GetMethod("EnterCallSite").MakeGenericMethod(args[last].Type).OpCall(
                        args[last],
                        Ast.Constant(_sourceId),
                        Ast.Constant(_sites[node].Start.Index)
                        );

                    return(Ast.Dynamic(
                               new TracingRubyCallAction(callAction.MethodName, callAction.Signature),
                               node.Type,
                               args
                               ));
                }
                else
                {
                    return(base.VisitDynamic(node));
                }
            }
Ejemplo n.º 3
0
        public override Expression /*!*/ ConvertExpression(Expression /*!*/ expr, ParameterInfo info, Type /*!*/ toType)
        {
            Type fromType = expr.Type;

            // block:
            if (fromType == typeof(MissingBlockParam))
            {
                Debug.Assert(toType == typeof(BlockParam) || toType == typeof(MissingBlockParam));
                return(Ast.Constant(null));
            }

            if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam))
            {
                return(Ast.Constant(null));
            }

            // protocol conversions:
            if (info != null && info.IsDefined(typeof(DefaultProtocolAttribute), false))
            {
                var action = ProtocolConversionAction.TryGetConversionAction(toType);
                if (action != null)
                {
                    // TODO: once we work with MetaObjects, we could inline these dynamic sites:
                    return(Ast.Dynamic(action, toType, ScopeExpression, expr));
                }

                throw new InvalidOperationException(String.Format("No default protocol conversion for type {0}.", toType));
            }

            return(Binder.ConvertExpression(expr, toType, ConversionResultKind.ExplicitCast, ScopeExpression));
        }
Ejemplo n.º 4
0
 internal MSAst GetIndex(MSAst target, params MSAst[] arguments)
 {
     return(MSAst.Dynamic(
                _binder.GetIndex(arguments.Length),
                typeof(object),
                ArrayUtils.Insert(
                    target,
                    MSAst.Constant(arguments, typeof(MSAst[])),
                    arguments)));
 }
Ejemplo n.º 5
0
 internal MSAst InvokeQueryMethod(MSAst target, string methodName, MSAst[] arguments)
 {
     return(MSAst.Dynamic(
                new SxeQueryMethodBinder(_binder.Binder, methodName, false, new CallInfo(arguments.Length)),
                typeof(object),
                ArrayUtils.Insert(
                    target,
                    //MSAst.Constant(typeArguments, typeof(Type[])),
                    arguments)));
 }
Ejemplo n.º 6
0
 internal MSAst Invoke(MSAst target, Type[] typeArguments, MSAst[] arguments)
 {
     return(MSAst.Dynamic(
                _binder.Invoke(arguments.Length),
                typeof(object),
                ArrayUtils.Insert(
                    target,
                    //MSAst.Constant(typeArguments, typeof(Type[])),
                    arguments)));
 }
Ejemplo n.º 7
0
 public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                DynamicExpression.Dynamic(
                    _context.CreateInvokeBinder(CallInfo),
                    typeof(object),
                    GetArgs(target, args)
                    ),
                target.Restrictions.Merge(BindingRestrictions.Combine(args))
                ));
 }
Ejemplo n.º 8
0
        internal MSAst Operator(ExpressionType op, MSAst left, MSAst right)
        {
            var returnType = ((op == ExpressionType.IsTrue) || (op == ExpressionType.IsFalse)) ? typeof(bool) : typeof(object);

            if (right == null)
            {
                return(MSAst.Dynamic(
                           _binder.UnaryOperation(op),
                           returnType,
                           left));
            }
            return(MSAst.Dynamic(
                       _binder.BinaryOperation(op),
                       returnType,
                       left,
                       right));
        }
Ejemplo n.º 9
0
        public void BinaryOperation()
        {
            var expected =
                LinqExpression.Dynamic(
                    Binder.BinaryOperation(
                        CSharpBinderFlags.None,
                        Linq.ExpressionType.Add,
                        null,
                        new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            }),
                    typeof(object),
                    LinqExpression.Constant(2L),
                    LinqExpression.Constant(3L));

            const string actual = @"
@prefix : <http://example.com/> .
@prefix xt: <http://example.com/ExpressionTypes/> .

:s
    :dynamicBinder [
        a :BinaryOperation ;
        :binderExpressionType xt:Add ;
        :binderArguments (
            []
            []
        ) ;
    ] ;
    :dynamicReturnType [
        :typeName ""System.Object"" ;
    ] ;
    :dynamicArguments (
        [
            :constantValue 2 ;
        ]
        [
            :constantValue 3 ;
        ]
    ) ;
.
";

            ShouldBe(actual, expected);
        }
Ejemplo n.º 10
0
        public void Dynamic_InvokeMember()
        {
            var expression =
                LinqExpression.Dynamic(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "ToString",
                        null,
                        null,
                        new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            }),
                    typeof(object),
                    LinqExpression.Constant(0L));

            ShouldRoundrip(expression);
        }
Ejemplo n.º 11
0
        internal MSAst InvokeStaticMember(MSAst target, string memberName, Type[] typeArguments, MSAst[] arguments)
        {
            var newArgs = ArrayUtils.Insert(
                //MSAst.Constant(typeof(Enumerable)),
                target,
                arguments);

            var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
                CSharpBinderFlags.None,
                memberName,
                typeArguments,
                typeof(QueryClause.QueryExpressionInvocation),
                newArgs.Select((e, i) => CSharpArgumentInfo.Create(((i == 1) ? CSharpArgumentInfoFlags.None : CSharpArgumentInfoFlags.UseCompileTimeType) | ((i == 0) ? CSharpArgumentInfoFlags.IsStaticType : ((i == 1) ? CSharpArgumentInfoFlags.None : CSharpArgumentInfoFlags.UseCompileTimeType)), null)));

            return(MSAst.Dynamic(
                       binder,
                       typeof(object),
                       newArgs));
        }
Ejemplo n.º 12
0
        public void Dynamic_BinaryOperation()
        {
            var expression =
                LinqExpression.Dynamic(
                    Binder.BinaryOperation(
                        CSharpBinderFlags.None,
                        Linq.ExpressionType.Add,
                        null,
                        new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            }),
                    typeof(object),
                    LinqExpression.Constant(2L),
                    LinqExpression.Constant(3L));

            ShouldRoundrip(expression);
        }
Ejemplo n.º 13
0
        internal MSAst InvokeMember(MSAst target, string memberName, Type[] typeArguments, MSAst[] arguments)
        {
            var newArgs = ArrayUtils.Insert(
                //MSAst.Constant(typeof(Enumerable)),
                target,
                arguments);

            var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
                CSharpBinderFlags.None,
                memberName,
                Enumerable.Empty <Type>(),
                null,
                arguments.Select((e, i) => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)));

            return(MSAst.Dynamic(
                       binder,
                       typeof(object),
                       newArgs));
        }
Ejemplo n.º 14
0
        public void InvokeMember()
        {
            var expected =
                LinqExpression.Dynamic(
                    Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        "ToString",
                        null,
                        null,
                        new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            }),
                    typeof(object),
                    LinqExpression.Constant(0L));

            const string actual = @"
@prefix : <http://example.com/> .

:s
    :dynamicBinder [
        a :InvokeMember ;
        :binderName ""ToString"";
        :binderArguments (
            []
        ) ;
    ] ;
    :dynamicReturnType [
        :typeName ""System.Object"" ;
    ] ;
    :dynamicArguments (
        [
            :constantValue 0 ;
        ]
    ) ;
.
";

            ShouldBe(actual, expected);
        }
Ejemplo n.º 15
0
        private static void BuildOverriddenInitializerCall(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, RubyMemberInfo /*!*/ initializer)
        {
            var instanceExpr = metaBuilder.Result;

            metaBuilder.Result = null;

            var instanceVariable = metaBuilder.GetTemporary(instanceExpr.Type, "#instance");

            // We know an exact type of the new instance and that there is no singleton for that instance.
            // We also have the exact method we need to call ("initialize" is a RubyMethodInfo).
            // => no tests are necessary:
            args.SetTarget(instanceVariable, null);

            if (initializer is RubyMethodInfo)
            {
                initializer.BuildCall(metaBuilder, args, Symbols.Initialize);
            }
            else
            {
                // TODO: we need more refactoring of RubyMethodGroupInfo.BuildCall to be able to inline this:
                metaBuilder.Result = Ast.Dynamic(
                    RubyCallAction.Make("initialize",
                                        new RubyCallSignature(args.Signature.ArgumentCount, args.Signature.Flags | RubyCallFlags.HasImplicitSelf)
                                        ),
                    typeof(object),
                    args.GetCallSiteArguments(instanceVariable)
                    );
            }

            if (!metaBuilder.Error)
            {
                // PropagateRetrySingleton(instance = new <type>(), instance.initialize(<args>))
                metaBuilder.Result = Methods.PropagateRetrySingleton.OpCall(
                    Ast.Assign(instanceVariable, instanceExpr),
                    metaBuilder.Result
                    );
                RubyMethodInfo.ApplyBlockFlowHandlingInternal(metaBuilder, args);
            }
        }
Ejemplo n.º 16
0
        internal void SetRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(args.SimpleArgumentCount == 0 && !args.Signature.HasBlock && !args.Signature.HasSplattedArgument && !args.Signature.HasRhsArgument);
            Debug.Assert(args.Signature.HasScope);

            var ec = args.RubyContext;

            // implicit conversions should only depend on a static type:
            if (TryImplicitConversion(metaBuilder, args))
            {
                if (args.Target == null)
                {
                    metaBuilder.AddRestriction(Ast.Equal(args.TargetExpression, Ast.Constant(null, args.TargetExpression.Type)));
                }
                else
                {
                    metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
                }
                return;
            }

            // check for type version:
            metaBuilder.AddTargetTypeTest(args);

            string     toMethodName            = ToMethodName;
            Expression targetClassNameConstant = Ast.Constant(ec.GetClassOf(args.Target).Name);

            // Kernel#respond_to? method is not overridden => we can optimize
            RubyMemberInfo respondToMethod = ec.ResolveMethod(args.Target, Symbols.RespondTo, true).InvalidateSitesOnOverride();

            if (respondToMethod == null ||
                // the method is defined in library, hasn't been replaced by user defined method (TODO: maybe we should make this check better)
                (respondToMethod.DeclaringModule == ec.KernelModule && respondToMethod is RubyMethodGroupInfo))
            {
                RubyMemberInfo conversionMethod = ec.ResolveMethod(args.Target, toMethodName, false).InvalidateSitesOnOverride();
                if (conversionMethod == null)
                {
                    // error:
                    SetError(metaBuilder, targetClassNameConstant, args);
                    return;
                }
                else
                {
                    // invoke target.to_xxx() and validate it; returns an instance of TTargetType:
                    conversionMethod.BuildCall(metaBuilder, args, toMethodName);

                    if (!metaBuilder.Error && ConversionResultValidator != null)
                    {
                        metaBuilder.Result = ConversionResultValidator.OpCall(targetClassNameConstant, AstFactory.Box(metaBuilder.Result));
                    }
                    return;
                }
            }
            else if (!RubyModule.IsMethodVisible(respondToMethod, false))
            {
                // respond_to? is private:
                SetError(metaBuilder, targetClassNameConstant, args);
                return;
            }

            // slow path: invoke respond_to?, to_xxx and result validation:

            var conversionCallSite = Ast.Dynamic(
                RubyCallAction.Make(toMethodName, RubyCallSignature.WithScope(0)),
                typeof(object),
                args.ScopeExpression, args.TargetExpression
                );

            Expression opCall;

            metaBuilder.Result = Ast.Condition(
                // If

                // respond_to?()
                Methods.IsTrue.OpCall(
                    Ast.Dynamic(
                        RubyCallAction.Make(Symbols.RespondTo, RubyCallSignature.WithScope(1)),
                        typeof(object),
                        args.ScopeExpression, args.TargetExpression, Ast.Constant(SymbolTable.StringToId(toMethodName))
                        )
                    ),

                // Then

                // to_xxx():
                opCall = (ConversionResultValidator == null) ? conversionCallSite :
                         ConversionResultValidator.OpCall(targetClassNameConstant, conversionCallSite),

                // Else

                AstUtils.Convert(
                    (ConversionResultValidator == null) ? args.TargetExpression :
                    Ast.Convert(
                        Ast.Throw(Methods.CreateTypeConversionError.OpCall(targetClassNameConstant, Ast.Constant(TargetTypeName))),
                        typeof(object)
                        ),
                    opCall.Type
                    )
                );
        }
Ejemplo n.º 17
0
        private object DoConversion(object value, Type targetType, object parameter, Func <object, object[], object, object> func, bool convertingBack, CultureInfo culture)
        {
            if (convertingBack)
            {
                if (_chainedConverter != null)
                {
                    try { value = _chainedConverter.ConvertBack(value, targetType, parameter, culture); }
                    catch (Exception e)
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new ChainedConverterExceptionEventArgs(ConvertExpression, value, targetType, parameter, culture, true, _chainedConverter, this, e));
                        return(DependencyProperty.UnsetValue);
                    }

                    if (value == DependencyProperty.UnsetValue || value == System.Windows.Data.Binding.DoNothing)
                    {
                        return(value);
                    }
                }

                if (ValueType != null && !ValueType.IsInstanceOfType(value))
                {
                    return(System.Windows.Data.Binding.DoNothing);
                }
            }
            else
            {
                if (value == DependencyProperty.UnsetValue || _namedObjectType.IsInstanceOfType(value) || (PType != null && !PType.IsInstanceOfType(value)))
                {
                    return(DependencyProperty.UnsetValue);
                }
            }

            object result = value;

            if (func != null)
            {
                try { result = func(result, _values, parameter); }
                catch (Exception e)
                {
                    LastException = e;
                    ++ExceptionCount;
                    if (Debugger.IsAttached)
                    {
                        Console.WriteLine("QuickMultiConverter Exception (\"" + (convertingBack ? ConvertBackExpression : ConvertExpression) + "\") - " + e.Message + (e.InnerException != null ? " (Inner - " + e.InnerException.Message + ")" : ""));
                    }
                    if (convertingBack)
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new RuntimeSingleConvertExceptionEventArgs(ConvertBackExpression, ConvertBackExpressionDebugView, null, value, _values, parameter, this, e));
                    }
                    else
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new RuntimeSingleConvertExceptionEventArgs(ConvertExpression, ConvertExpressionDebugView, value, null, _values, parameter, this, e));
                    }
                    return(DependencyProperty.UnsetValue);
                }
                finally
                {
                    var dataContainers = convertingBack ? _fromDataContainers : _toDataContainers;
                    if (dataContainers != null)
                    {
                        foreach (var container in dataContainers)
                        {
                            container.Value = null;
                        }
                    }
                }
            }

            if (result == DependencyProperty.UnsetValue || result == System.Windows.Data.Binding.DoNothing)
            {
                return(result);
            }

            if (!convertingBack && _chainedConverter != null)
            {
                try { result = _chainedConverter.Convert(result, targetType, parameter, culture); }
                catch (Exception e)
                {
                    EquationTokenizer.ThrowQuickConverterEvent(new ChainedConverterExceptionEventArgs(ConvertExpression, result, targetType, parameter, culture, false, _chainedConverter, this, e));
                    return(DependencyProperty.UnsetValue);
                }
            }

            if (result == DependencyProperty.UnsetValue || result == System.Windows.Data.Binding.DoNothing || result == null || targetType == null || targetType == typeof(object))
            {
                return(result);
            }

            if (targetType == typeof(string))
            {
                return(result.ToString());
            }

            Func <object, object> cast;

            if (!castFunctions.TryGetValue(targetType, out cast))
            {
                ParameterExpression par = Expression.Parameter(typeof(object));
                cast = Expression.Lambda <Func <object, object> >(Expression.Convert(Expression.Dynamic(Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, typeof(object)), targetType, par), typeof(object)), par).Compile();
                castFunctions.TryAdd(targetType, cast);
            }
            if (cast != null)
            {
                try
                {
                    result = cast(result);
                }
                catch
                {
                    castFunctions[targetType] = null;
                }
            }
            return(result);
        }
Ejemplo n.º 18
0
 internal MSAst GetIndex(MSAst target, MSAst index)
 {
     return(MSAst.Dynamic(_binder.GetIndex(1), typeof(object), target, index));
 }
Ejemplo n.º 19
0
        internal MSAst GetMember(MSAst target, string memberName)
        {
            var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, memberName, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });

            return(MSAst.Dynamic(binder, typeof(object), target));
        }