Пример #1
0
        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
 }
Пример #4
0
        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
                );
            }
        }
Пример #11
0
 internal ComFallbackMetaObject(Expression expression, Restrictions restrictions, object arg)
     : base(expression, restrictions, arg) {
 }
Пример #12
0
 public Meta(Expression/*!*/ expression, Restrictions/*!*/ restrictions, BlockParam/*!*/ value)
     : base(expression, restrictions, value) {
     ContractUtils.RequiresNotNull(value, "value");
 }
Пример #13
0
 public OperationMetaObject(Expression expression, Restrictions restrictions)
     : base(expression, restrictions) {
 }
Пример #14
0
 public RestrictedMetaObject(Expression expression, Restrictions restriction)
     : base(expression, restriction) {
 }
Пример #15
0
            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;
            }
Пример #16
0
 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
     );
 }
Пример #19
0
        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)
            );
        }
Пример #20
0
        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
     );
 }
Пример #23
0
        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
            );
        }
Пример #25
0
 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
     );
 }
Пример #27
0
 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
     );
 }
Пример #29
0
 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);
 }