public static Dynamic ( CallSiteBinder binder, Type returnType ) : |
||
binder | CallSiteBinder | The runtime binder for the dynamic operation. |
returnType | Type | The result type of the dynamic expression. |
return |
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); }
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)); } }
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)); }
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))); }
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))); }
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))); }
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)) )); }
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)); }
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); }
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); }
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)); }
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); }
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)); }
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); }
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); } }
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 ) ); }
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); }
internal MSAst GetIndex(MSAst target, MSAst index) { return(MSAst.Dynamic(_binder.GetIndex(1), typeof(object), target, index)); }
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)); }