public MetaObject(Expression expression, Restrictions restrictions) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.RequiresNotNull(restrictions, "restrictions"); _expression = expression; _restrictions = restrictions; }
/// <summary> /// Checks if the conversion can be handled by a simple cast. /// </summary> private static MetaObject TryAssignableConversion(Type toType, Type type, Restrictions restrictions, MetaObject arg) { if (toType.IsAssignableFrom(type) || (type == typeof(Null) && (toType.IsClass || toType.IsInterface))) { // MakeSimpleConversionTarget handles the ConversionResultKind check return MakeSimpleConversionTarget(toType, restrictions, arg); } return null; }
/// <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 }
internal ComInvokeBinder(IList<ArgumentInfo> arguments, MetaObject[] args, Restrictions restrictions, Expression method, Expression dispatch, ComMethodDesc methodDesc) { ContractUtils.RequiresNotNull(arguments, "arguments"); ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(method, "method"); ContractUtils.RequiresNotNull(dispatch, "dispatch"); ContractUtils.Requires(TypeUtils.AreReferenceAssignable(typeof(ComMethodDesc), method.Type), "method"); ContractUtils.Requires(TypeUtils.AreReferenceAssignable(typeof(IDispatch), dispatch.Type), "dispatch"); _method = method; _dispatch = dispatch; _methodDesc = methodDesc; _arguments = arguments; _args = args; _restrictions = restrictions; // Set Instance to some value so that CallBinderHelper has the right number of parameters to work with _instance = dispatch; }
/// <summary> /// Gets alternate members which are specially recognized by the DLR for specific types when /// all other member lookup fails. /// </summary> private static MethodInfo[] GetFallbackMembers(Type t, OperatorInfo info, MetaObject[] args, out Restrictions restrictions) { // if we have an event we need to make a strongly-typed event handler // TODO: Events, we need to look in the args and pull out the real values if (t == typeof(EventTracker)) { EventTracker et = ((EventTracker)args[0].Value); if (info.Operator == Operators.InPlaceAdd) { restrictions = GetFallbackRestrictions(t, et, args[0]); return new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }; } else if (info.Operator == Operators.InPlaceSubtract) { restrictions = GetFallbackRestrictions(t, et, args[0]); return new MethodInfo[] { typeof(BinderOps).GetMethod("EventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }; } } else if (t == typeof(BoundMemberTracker)) { BoundMemberTracker bmt = ((BoundMemberTracker)args[0].Value); if (bmt.BoundTo.MemberType == TrackerTypes.Event) { EventTracker et = ((EventTracker)bmt.BoundTo); if (info.Operator == Operators.InPlaceAdd) { restrictions = GetFallbackRestrictions(t, et, args[0]); return new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceAdd").MakeGenericMethod(et.Event.EventHandlerType) }; } else if (info.Operator == Operators.InPlaceSubtract) { restrictions = GetFallbackRestrictions(t, et, args[0]); return new MethodInfo[] { typeof(BinderOps).GetMethod("BoundEventTrackerInPlaceRemove").MakeGenericMethod(et.Event.EventHandlerType) }; } } } restrictions = Restrictions.Empty; return new MethodInfo[0]; }
private static MetaObject MakeInvalidParametersRule(CallTypes callType, CallSignature signature, DefaultBinder binder, IList<MetaObject> args, Restrictions restrictions, BindingTarget bt) { Restrictions restriction = MakeSplatTests(callType, signature, true, args); // restrict to the exact type of all parameters for errors for (int i = 0; i < args.Count; i++) { args[i] = args[i].Restrict(args[i].LimitType); } return MakeError( binder.MakeInvalidParametersError(bt), restrictions.Merge(Restrictions.Combine(args).Merge(restriction)) ); }
private MetaObject TryMakeBindingTarget(MethodInfo[] targets, MetaObject[] args, Expression codeContext, Restrictions restrictions) { MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets); BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args); if (target.Success) { return new MetaObject( target.MakeExpression(new ParameterBinderWithCodeContext(this, codeContext)), restrictions.Merge(Restrictions.Combine(target.RestrictedArguments)) ); } return null; }
/// <summary> /// Helper to convert a null value to nullable of T /// </summary> private static MetaObject MakeNullToNullableOfTTarget(Type toType, Restrictions restrictions) { return new MetaObject( Ast.Call(typeof(ScriptingRuntimeHelpers).GetMethod("CreateInstance").MakeGenericMethod(toType)), restrictions ); }
private MetaObject CallWorker(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<MetaObject> args, CallSignature signature, CallTypes callType, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) { ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder"); ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNullItems(targets, "targets"); ContractUtils.RequiresNotNull(restrictions, "restrictions"); MetaObject[] finalArgs; SymbolId[] argNames; if (callType == CallTypes.ImplicitInstance) { GetArgumentNamesAndTypes(signature, ArrayUtils.RemoveFirst(args), out argNames, out finalArgs); finalArgs = ArrayUtils.Insert(args[0], finalArgs); } else { GetArgumentNamesAndTypes(signature, args, out argNames, out finalArgs); } // attempt to bind to an individual method MethodBinder binder = MethodBinder.MakeBinder( this, name ?? GetTargetName(targets), targets, argNames, minLevel, maxLevel); target = binder.MakeBindingTarget(callType, finalArgs); if (target.Success) { // if we succeed make the target for the rule return new MetaObject( target.MakeExpression(parameterBinder), restrictions.Merge(MakeSplatTests(callType, signature, args).Merge(Restrictions.Combine(target.RestrictedArguments))) ); } // make an error rule return MakeInvalidParametersRule(callType, signature, this, args, restrictions, target); }
/// <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 ); } }
internal ComFallbackMetaObject(Expression expression, Restrictions restrictions, object arg) : base(expression, restrictions, arg) { }
public Meta(Expression/*!*/ expression, Restrictions/*!*/ restrictions, BlockParam/*!*/ value) : base(expression, restrictions, value) { ContractUtils.RequiresNotNull(value, "value"); }
public OperationMetaObject(Expression expression, Restrictions restrictions) : base(expression, restrictions) { }
public RestrictedMetaObject(Expression expression, Restrictions restriction) : base(expression, restriction) { }
public TargetInfo(MetaObject instance, MetaObject[] arguments, Restrictions restrictions, params MethodBase[] targets) { Assert.NotNullItems(targets); Assert.NotNull(restrictions); Instance = instance; Arguments = arguments; Targets = targets; Restrictions = restrictions; }
public RestrictedMetaObject(Expression expression, Restrictions restriction, object value) : base(expression, restriction, value) { }
/// <summary> /// Checks if the conversion can be handled by calling a user-defined conversion method. /// </summary> private MetaObject TryUserDefinedConversion(ConversionResultKind kind, Type toType, Type type, Restrictions restrictions, MetaObject arg) { Type fromType = GetUnderlyingType(type); MetaObject 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 produce the rule for converting T to Nullable of T /// </summary> private static MetaObject MakeTToNullableOfTTarget(Type toType, Type knownType, Restrictions restrictions, MetaObject arg) { // T -> Nullable<T> return new MetaObject( Ast.New( toType.GetConstructor(new Type[] { knownType }), AstUtils.Convert(arg.Expression, knownType) ), restrictions ); }
internal MetaObject Invoke() { _keywordArgNames = GetArgumentNames(); // will not include implicit instance argument (if any) Type[] explicitArgTypes = _args.Map(a => a.LimitType); Type[] marshalArgTypes = _args.Map(a => MarshalType(a)); Expression[] explicitArgExprs = _args.Map(a => a.Expression); _totalExplicitArgs = explicitArgTypes.Length; _varEnumSelector = new VarEnumSelector(marshalArgTypes); // We already tested the instance, so no need to test it again for (int i = 0; i < explicitArgTypes.Length; i++) { _restrictions = _restrictions.Merge(Restrictions.GetTypeRestriction(explicitArgExprs[i], explicitArgTypes[i])); } return new MetaObject( CreateScope(MakeIDispatchInvokeTarget()), Restrictions.Combine(_args).Merge(_restrictions) ); }
private MetaObject MakeDeferred(Restrictions rs, params MetaObject[] args) { var exprs = MetaObject.GetExpressions(args); // TODO: we should really be using the same delegate as the CallSite Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, typeof(object)); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new MetaObject( DynamicExpression.Make( typeof(object), delegateType, this, new ReadOnlyCollection<Expression>(exprs) ), rs ); }
/// <summary> /// Performs binding against a set of overloaded methods using the specified arguments. The arguments are /// consumed as specified by the CallSignature object. /// </summary> /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param> /// <param name="targets">The methods to be called</param> /// <param name="args">The arguments for the call</param> /// <param name="signature">The call signature which specified how the arguments will be consumed</param> /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param> /// <param name="name">The name of the method or null to use the name from targets.</param> /// <returns>A meta object which results from the call.</returns> public MetaObject CallMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<MetaObject> args, CallSignature signature, Restrictions restrictions, string name) { return CallWorker( parameterBinder, targets, args, signature, CallTypes.None, restrictions, NarrowingLevel.None, NarrowingLevel.All, name ); }
/// <summary> /// Creates a target which returns null for a reference type. /// </summary> private static MetaObject MakeNullTarget(Type toType, Restrictions restrictions) { return new MetaObject( Ast.Convert(Ast.Constant(null), toType), restrictions ); }
public Restrictions Merge(Restrictions restrictions) { if (restrictions.IsEmpty) { return this; } else if (IsEmpty) { return restrictions; } else { List<Restriction> res = new List<Restriction>(_restrictions.Length + restrictions._restrictions.Length); AddRestrictions(_restrictions, res); AddRestrictions(restrictions._restrictions, res); return new Restrictions(res.ToArray()); } }
/// <summary> /// Performs binding against a set of overloaded methods using the specified arguments and the specified /// instance argument. The arguments are consumed as specified by the CallSignature object. /// </summary> /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param> /// <param name="targets">The methods to be called</param> /// <param name="args">The arguments for the call</param> /// <param name="instance">The instance which will be provided for dispatching to an instance method.</param> /// <param name="signature">The call signature which specified how the arguments will be consumed</param> /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param> /// <returns>A meta object which results from the call.</returns> public MetaObject CallInstanceMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, MetaObject instance, IList<MetaObject> args, CallSignature signature, Restrictions restrictions) { ContractUtils.RequiresNotNull(instance, "instance"); ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder"); return CallWorker( parameterBinder, targets, ArrayUtils.Insert(instance, args), signature, CallTypes.ImplicitInstance, restrictions, NarrowingLevel.None, NarrowingLevel.All, null ); }
public OperationMetaObject(Expression expression, Restrictions restrictions, object value) : base(expression, restrictions, value) { }
/// <summary> /// Performs binding against a set of overloaded methods using the specified arguments. The arguments are /// consumed as specified by the CallSignature object. /// </summary> /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param> /// <param name="targets">The methods to be called</param> /// <param name="args">The arguments for the call</param> /// <param name="signature">The call signature which specified how the arguments will be consumed</param> /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param> /// <param name="maxLevel">The maximum narrowing level for arguments. The current narrowing level is flowed thorugh to the DefaultBinder.</param> /// <param name="minLevel">The minimum narrowing level for the arguments. The current narrowing level is flowed thorugh to the DefaultBinder.</param> /// <param name="target">The resulting binding target which can be used for producing error information.</param> /// <param name="name">The name of the method or null to use the name from targets.</param> /// <returns>A meta object which results from the call.</returns> public MetaObject CallMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<MetaObject> args, CallSignature signature, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) { return CallWorker( parameterBinder, targets, args, signature, CallTypes.None, restrictions, minLevel, maxLevel, name, out target ); }
public static MetaObject MakeError(ErrorInfo error, Restrictions restrictions) { return new MetaObject(MakeError(error), restrictions); }
/// <summary> /// Performs binding against a set of overloaded methods using the specified arguments and the specified /// instance argument. The arguments are consumed as specified by the CallSignature object. /// </summary> /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param> /// <param name="targets">The methods to be called</param> /// <param name="args">The arguments for the call</param> /// <param name="signature">The call signature which specified how the arguments will be consumed</param> /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param> /// <param name="instance">The instance which will be provided for dispatching to an instance method.</param> /// <param name="maxLevel">The maximum narrowing level for arguments. The current narrowing level is flowed thorugh to the DefaultBinder.</param> /// <param name="minLevel">The minimum narrowing level for the arguments. The current narrowing level is flowed thorugh to the DefaultBinder.</param> /// <param name="target">The resulting binding target which can be used for producing error information.</param> /// <param name="name">The name of the method or null to use the name from targets.</param> /// <returns>A meta object which results from the call.</returns> public MetaObject CallInstanceMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, MetaObject instance, IList<MetaObject> args, CallSignature signature, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) { return CallWorker( parameterBinder, targets, ArrayUtils.Insert(instance, args), signature, CallTypes.ImplicitInstance, restrictions, minLevel, maxLevel, name, out target ); }
internal ComUnwrappedMetaObject(Expression expression, Restrictions restrictions, object value) : base(expression, restrictions, value) { }
private MetaObject CallWorker(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<MetaObject> args, CallSignature signature, CallTypes callType, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name) { BindingTarget dummy; return CallWorker(parameterBinder, targets, args, signature, callType, restrictions, minLevel, maxLevel, name, out dummy); }