Represents the dynamic binding and a binding logic of an object participating in the dynamic binding.
示例#1
0
 public override Meta BindInvoke(InvokeBinder binder, Meta[] args)
 {
     return new Meta(
         Et.Call(
             EtUtils.Cast<IFunction>(
                 this.Expression
             ),
             IFunctionMethods.MiCall,
             EtUtils.Cast<IObj>(
                 args[0].Expression
             ),
             AstUtils.NewArrayHelper(
                 typeof(object),
                 DynamicUtils.GetExpressions(
                     ArrayUtils.RemoveFirst(args)
                 )
             )
         ),
         RestrictUtils.BuildCallRestrictions(
             this,
             args,
             RestrictFlag.Type
         )
     );
 }
示例#2
0
        public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
        {
            ComMethodDesc method;
            var target = _callable.DispatchComObject;
            var name = _callable.MemberName;

            bool holdsNull = value.Value == null && value.HasValue;
            if (target.TryGetPropertySetter(name, out method, value.LimitType, holdsNull) ||
                target.TryGetPropertySetterExplicit(name, out method, value.LimitType, holdsNull))
            {
                List<ParameterExpression> temps = new List<ParameterExpression>();
                List<Expression> initTemps = new List<Expression>();

                bool[] isByRef = ComBinderHelpers.ProcessArgumentsForCom(method, ref indexes, temps, initTemps);
                isByRef = isByRef.AddLast(false);

                // Convert the value to the target type
                DynamicMetaObject updatedValue = new DynamicMetaObject(value.CastOrConvertMethodArgument(
                                value.LimitType,
                                name,
                                "SetIndex",
                                temps,
                                initTemps), value.Restrictions);

                var result = BindComInvoke(method, indexes.AddLast(updatedValue), binder.CallInfo, isByRef, temps, initTemps);

                // Make sure to return the value; some languages need it.
                return new DynamicMetaObject(
                    Expression.Block(result.Expression, Expression.Convert(value.Expression, typeof(object))),
                    result.Restrictions
                );
            }

            return base.BindSetIndex(binder, indexes, value);
        }
示例#3
0
 /// <summary>
 /// Performs the binding of the dynamic set member operation if the target dynamic object
 ///  cannot bind.
 /// </summary>
 /// <param name="target">The target of the dynamic set member operation.</param>
 /// <param name="value">The value to set to the member.</param>
 /// <param name="errorSuggestion">The binding result to use if binding fails, or null.
 /// </param>
 /// <returns>
 /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> representing the result of the
 /// binding.
 /// </returns>
 public override DynamicMetaObject FallbackSetMember(
     DynamicMetaObject target,
     DynamicMetaObject value,
     DynamicMetaObject errorSuggestion)
 {
     return null;
 }
示例#4
0
        public override DYN.DynamicMetaObject FallbackGetMember(DYN.DynamicMetaObject target, DYN.DynamicMetaObject errorSuggestion)
        {
            DYN.BindingRestrictions restriction =
                DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType);

            string exceptionString = String.Format("GetMemberBinder: cannot bind member '{0}' on object '{1}'",
                                                   this.Name, target.Value.ToString());

            DLR.Expression throwBlock =
                DLR.Expression.Throw(
                    DLR.Expression.New(
                        typeof(Error.Value).GetConstructor(new Type[] { typeof(string) }),
                        DLR.Expression.Constant(exceptionString)
                        ),
                    typeof(Error)
                    );

            DYN.DynamicMetaObject dynobj =
                new DYN.DynamicMetaObject(
                    throwBlock,
                    restriction
                    );

            return(dynobj);
        }
示例#5
0
        internal ComInvokeBinder(
                CallInfo callInfo, 
                DynamicMetaObject[] args,
                bool[] isByRef,
                BindingRestrictions restrictions, 
                Expression method, 
                Expression dispatch, 
                ComMethodDesc methodDesc
                )
        {
            Debug.Assert(callInfo != null, "arguments");
            Debug.Assert(args != null, "args");
            Debug.Assert(isByRef != null, "isByRef");
            Debug.Assert(method != null, "method");
            Debug.Assert(dispatch != null, "dispatch");

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(ComMethodDesc), method.Type), "method");
            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(IDispatch), dispatch.Type), "dispatch");

            _method = method;
            _dispatch = dispatch;
            _methodDesc = methodDesc;

            _callInfo = callInfo;
            _args = args;
            _isByRef = isByRef;
            _restrictions = restrictions;

            // Set Instance to some value so that CallBinderHelper has the right number of parameters to work with
            _instance = dispatch;
        }
示例#6
0
        private DynamicMetaObject[] GetArguments(DynamicMetaObject[] args, IList<DynamicMetaObject> results, int metaBinderIndex) {
            BinderMappingInfo indices = _metaBinders[metaBinderIndex];

            DynamicMetaObject[] res = new DynamicMetaObject[indices.MappingInfo.Count];
            for (int i = 0; i < res.Length; i++) {
                ParameterMappingInfo mappingInfo = indices.MappingInfo[i];

                if (mappingInfo.IsAction) {
                    // input is the result of a previous bind
                    res[i] = results[mappingInfo.ActionIndex];
                } else if (mappingInfo.IsParameter) {
                    // input is one of the original arguments
                    res[i] = args[mappingInfo.ParameterIndex];
                } else {
                    // input is a constant
                    res[i] = new DynamicMetaObject(
                        mappingInfo.Constant,
                        BindingRestrictions.Empty,
                        mappingInfo.Constant.Value
                    );
                }
            }

            return res;
        }
示例#7
0
        public static bool TryBindGetMember(GetMemberBinder binder, DynamicMetaObject instance, out DynamicMetaObject result, bool delayInvocation) {
            ContractUtils.RequiresNotNull(binder, "binder");
            ContractUtils.RequiresNotNull(instance, "instance");

            if (TryGetMetaObject(ref instance)) {
                //
                // Demand Full Trust to proceed with the binding.
                //

                new PermissionSet(PermissionState.Unrestricted).Demand();

                var comGetMember = new ComGetMemberBinder(binder, delayInvocation);
                result = instance.BindGetMember(comGetMember);
                if (result.Expression.Type.IsValueType) {
                    result = new DynamicMetaObject(
                        Expression.Convert(result.Expression, typeof(object)),
                        result.Restrictions
                    );
                }
                return true;
            } else {
                result = null;
                return false;
            }
        }
 /// <summary>
 /// The method takes a DynamicMetaObject, and returns an instance restriction for testing null if the object
 /// holds a null value, otherwise returns a type restriction.
 /// </summary>
 internal static BindingRestrictions GetTypeRestriction(DynamicMetaObject obj) {
     if (obj.Value == null && obj.HasValue) {
         return BindingRestrictions.GetInstanceRestriction(obj.Expression, null);
     } else {
         return BindingRestrictions.GetTypeRestriction(obj.Expression, obj.LimitType);
     }
 }
        /// <summary>
        /// Performs the binding of the dynamic operation.
        /// </summary>
        /// <param name="target">The target of the dynamic operation.</param>
        /// <param name="args">An array of arguments of the dynamic operation.</param>
        /// <returns>The System.Dynamic.DynamicMetaObject representing the result of the binding.</returns>
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            #if DEBUG
            if ((args == null) || (args.Length != 2))
                throw new InvalidOperationException("The DoesNotUnderstandCallSiteBinder is special case and always requires 2 method arguments.");
            #endif
            // Look-up the #_doesNotUnderstand:arguments: method.
            BindingRestrictions restrictions;
            SmalltalkClass receiverClass;
            Expression expression;
            MethodLookupHelper.GetMethodInformation(this.Runtime,
                this.Runtime.GetSymbol("_doesNotUnderstand:arguments:"),
                null,
                target.Value,
                target,
                args,
                out receiverClass,
                out restrictions,
                out expression);

            // Every class is supposed to implement the #_doesNotUnderstand:arguments:, if not, throw a runtime exception
            if (expression == null)
                throw new RuntimeCodeGenerationException(RuntimeCodeGenerationErrors.DoesNotUnderstandMissing);

            // Perform a standard cal to the #_doesNotUnderstand:arguments:
            return new DynamicMetaObject(expression, target.Restrictions.Merge(restrictions));
        }
        /// <summary>
        /// Creates the MetaObject for indexing directly into arrays or indexing into objects which have
        /// default members.  Returns null if we're not an indexing operation.
        /// </summary>
        public DynamicMetaObject SetIndex(OverloadResolverFactory resolverFactory, DynamicMetaObject[] args) {
            if (args[0].LimitType.IsArray) {
                return MakeArrayIndexRule(resolverFactory, IndexType.Set, args);
            }

            return MakeMethodIndexRule(IndexType.Set, resolverFactory, args);
        }
示例#11
0
		public RuntimeValueExpression (DynamicMetaObject obj, bool typed)
		{
			this.obj = obj;
			this.typed = typed;
			this.type = obj.RuntimeType;
			this.eclass = ExprClass.Value;
		}
        public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
        {
            var constructors = ReflType.GetConstructors();
            var ctors = constructors.Where(c => c.GetParameters().Length == args.Length);
            var res = new List<ConstructorInfo>();

            foreach (var c in ctors)
            {
                if (RuntimeHelpers.ParametersMatchArguments(c.GetParameters(), args))
                {
                    res.Add(c);
                }
            }
            if (res.Count == 0)
            {
                // Binders won't know what to do with TypeModels, so pass the
                // RuntimeType they represent.  The binder might not be Sympl's.
                return binder.FallbackCreateInstance(
                    RuntimeHelpers.GetRuntimeTypeMoFromModel(this),
                    args);
            }
            // For create instance of a TypeModel, we can create a instance
            // restriction on the MO, hence the true arg.
            var restrictions = RuntimeHelpers.GetTargetArgsRestrictions(this, args, true);
            var ctorArgs = RuntimeHelpers.ConvertArguments(args, res[0].GetParameters());
            return new DynamicMetaObject(
                // Creating an object, so don't need EnsureObjectResult.
                Expression.New(res[0], ctorArgs),
                restrictions);
        }
示例#13
0
        /// <summary>
        /// Performs the binding of the dynamic delete index operation.
        /// </summary>
        /// <param name="target">The target of the dynamic delete index operation.</param>
        /// <param name="args">An array of arguments of the dynamic delete index operation.</param>
        /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNull(target, nameof(target));
            ContractUtils.RequiresNotNullItems(args, nameof(args));

            return target.BindDeleteIndex(this, args);
        }
示例#14
0
 // negative start reserves as many slots at the beginning of the new array:
 internal static object/*!*/[]/*!*/ ToValues(DynamicMetaObject/*!*/[]/*!*/ args, int start) {
     var result = new object[args.Length - start];
     for (int i = Math.Max(0, -start); i < result.Length; i++) {
         result[i] = args[start + i].Value;
     }
     return result;
 }
        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;
        }
        public void BindBinaryOperationInvalidTest()
        {
            DynamicMetaObject target;

            DynamicMetaObject argPrimitive = new DynamicMetaObject(Expression.Constant(10), BindingRestrictions.Empty);
            DynamicMetaObject argNonPrimitive = new DynamicMetaObject(Expression.Constant(AnyInstance.AnyJsonObject), BindingRestrictions.Empty);

            foreach (JsonValue value in AnyInstance.AnyJsonValueArray)
            {
                target = GetJsonValueDynamicMetaObject(value);

                TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.UnsupportedOperations, false);
            }

            foreach (JsonValue value in AnyInstance.AnyJsonValueArray)
            {
                target = GetJsonValueDynamicMetaObject(value);

                if (value is JsonPrimitive)
                {
                    //// not supported on operand of type JsonValue if it isn't a primitive and not comparing JsonValue types.
                    TestBinaryOperationBinder.TestMetaObject(target, argNonPrimitive, TestBinaryOperationBinder.NumberOperations, false);
                    TestBinaryOperationBinder.TestMetaObject(target, argNonPrimitive, TestBinaryOperationBinder.BoolOperations, false);
                }
                else
                {
                    //// When value is non-primitive, it must be a compare operation and (the other operand must be null or a JsonValue)
                    TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.NumberOperations, false);
                    TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.BoolOperations, false);
                }
            }
        }
示例#17
0
 // negative start reserves as many slots at the beginning of the new array:
 internal static Expression/*!*/[]/*!*/ ToExpressions(DynamicMetaObject/*!*/[]/*!*/ args, int start) {
     var result = new Expression[args.Length - start];
     for (int i = Math.Max(0, -start); i < result.Length; i++) {
         result[i] = args[start + i].Expression;
     }
     return result;
 }
示例#18
0
 internal static bool CanIndexFromEndWithNegativeIndex(DynamicMetaObject target)
 {
     Type limitType = target.LimitType;
     return (((limitType.IsArray || limitType.Equals(typeof(string))) || limitType.Equals(typeof(StringBuilder))) || (typeof(IList).IsAssignableFrom(limitType) || (typeof(OrderedDictionary).IsAssignableFrom(limitType) || (from i in limitType.GetInterfaces()
         where i.IsGenericType && i.GetGenericTypeDefinition().Equals(typeof(IList<>))
         select i).Any<Type>())));
 }
示例#19
0
        public override MemberTracker BindToInstance(DynamicMetaObject instance) {
            if (IsStatic) {
                return this;
            }

            return new BoundMemberTracker(this, instance);
        }
示例#20
0
        /// <summary>
        /// Performs the binding of the dynamic set member operation.
        /// </summary>
        /// <param name="target">The target of the dynamic set member operation.</param>
        /// <param name="args">An array of arguments of the dynamic set member operation.</param>
        /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) {
            ContractUtils.RequiresNotNull(target, "target");
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.Requires(args.Length == 1);

            return target.BindSetMember(this, args[0]);
        }
示例#21
0
 // instance method call:
 public PythonOverloadResolver(PythonBinder binder, DynamicMetaObject instance, IList<DynamicMetaObject> args, CallSignature signature,
     Expression codeContext)
     : base(binder, instance, args, signature)
 {
     Assert.NotNull(codeContext);
     _context = codeContext;
 }
示例#22
0
        /// <summary>
        /// Performs the binding of the dynamic get member operation.
        /// </summary>
        /// <param name="target">The target of the dynamic get member operation.</param>
        /// <param name="args">An array of arguments of the dynamic get member operation.</param>
        /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public sealed override DynamicMetaObject Bind(DynamicMetaObject target, params DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNull(target, "target");
            ContractUtils.Requires(args == null || args.Length == 0, "args");

            return target.BindGetMember(this);
        }
示例#23
0
        public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            const string errorMsg = "{0}を符号反転出来ません。";

            if (target.Value == null) {
                var msg = String.Format(errorMsg, ConstantNames.NullText);
                var ctorInfo = typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) });
                var expr = Expression.Throw(Expression.New(ctorInfo, Expression.Constant(errorMsg)), this.ReturnType);
                var rest = BindingRestrictions.GetExpressionRestriction(BinderHelper.IsNull(target.Expression));
                return new DynamicMetaObject(expr, rest);
            }
            try {
                var expr = BinderHelper.Wrap(Expression.Negate(Expression.Convert(target.Expression, target.LimitType)), this.ReturnType);
                var rest = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType);
                return new DynamicMetaObject(expr, rest);
            }
            catch (InvalidOperationException) {
                var msgExpr = ExpressionHelper.BetaReduction<string, object, string>(
                    (format, obj) => String.Format(format, obj),
                    Expression.Constant(errorMsg), target.Expression);
                var ctorInfo = typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) });
                var expr = Expression.Throw(Expression.New(ctorInfo, msgExpr), this.ReturnType);
                var rest = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType);
                return new DynamicMetaObject(expr, rest);
            }
        }
 public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
 {
     switch (Operation)
     {
     case ExpressionType.Or:
     case ExpressionType.OrAssign:
     case ExpressionType.ExclusiveOr:
     case ExpressionType.ExclusiveOrAssign:
     case ExpressionType.And:
     case ExpressionType.AndAssign:
         return BindBitOp(target, arg, errorSuggestion);
     case ExpressionType.Add:
     case ExpressionType.AddAssign:
     case ExpressionType.Subtract:
     case ExpressionType.SubtractAssign:
     case ExpressionType.Multiply:
     case ExpressionType.MultiplyAssign:
     case ExpressionType.Divide:
     case ExpressionType.DivideAssign:
     case ExpressionType.LeftShift:
     case ExpressionType.LeftShiftAssign:
     case ExpressionType.RightShift:
     case ExpressionType.RightShiftAssign:
         return BindArithOp(target, arg, errorSuggestion);
     default:
         throw new System.Exception("Unhandled operation value");
     }
 }
        public override DynamicMetaObject FallbackGetMember(DynamicMetaObject targetMO, DynamicMetaObject errorSuggestion)
        {
            // Defer if any object has no value so that we evaulate their
            // Expressions and nest a CallSite for the InvokeMember.
            if (!targetMO.HasValue)
                return Defer(targetMO);

            // Find our own binding.
            MemberInfo[] members = targetMO.LimitType.GetMember(Name, DefaultBindingFlags);
            if (members.Length == 1)
            {
                return new DynamicMetaObject(
                    RuntimeHelpers.EnsureObjectResult(
                        Expression.MakeMemberAccess(
                            Expression.Convert(targetMO.Expression,
                                               members[0].DeclaringType),
                            members[0])),
                    // Don't need restriction test for name since this
                    // rule is only used where binder is used, which is
                    // only used in sites with this binder.Name.
                    BindingRestrictions.GetTypeRestriction(targetMO.Expression,
                                                           targetMO.LimitType));
            }

            return errorSuggestion ??
                   RuntimeHelpers.CreateBindingThrow(
                       targetMO, null,
                       BindingRestrictions.GetTypeRestriction(targetMO.Expression, targetMO.LimitType),
                       typeof(MissingMemberException),
                       "cannot bind member, " + Name + ", on object " + targetMO.Value);
        }
示例#26
0
        internal static DynamicMetaObject Call(DynamicMetaObjectBinder call, DynamicMetaObject target, DynamicMetaObject[] args)
        {
            Assert.NotNull(call, args);
            Assert.NotNullItems(args);

            if (target.NeedsDeferral())
                return call.Defer(ArrayUtils.Insert(target, args));

            foreach (var mo in args)
            {
                if (mo.NeedsDeferral())
                {
                    RestrictTypes(args);

                    return call.Defer(
                        ArrayUtils.Insert(target, args)
                    );
                }
            }

            DynamicMetaObject self = target.Restrict(target.GetLimitType());

            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target);
            TotemType tt = DynamicHelpers.GetTotemType(target.Value);
            TotemContext toContext = GetTotemContext(call);

            throw new NotImplementedException();
        }
示例#27
0
        public DynamicMetaObject Create(CallSignature signature, DynamicMetaObject target, DynamicMetaObject[] args, Expression contextExpression) {

            Type t = GetTargetType(target.Value);

            if (t != null) {

                if (typeof(Delegate).IsAssignableFrom(t) && args.Length == 1) {
                    // PythonOps.GetDelegate(CodeContext context, object callable, Type t);
                    return new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("GetDelegate"),
                            contextExpression,
                            AstUtils.Convert(args[0].Expression, typeof(object)),
                            Expression.Constant(t)
                        ),
                        target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value))
                    );
                }

                return CallMethod(
                    new PythonOverloadResolver(
                        this,
                        args,
                        signature,
                        contextExpression
                    ),
                    CompilerHelpers.GetConstructors(t, PrivateBinding),
                    target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value))
                );
            }

            return null;
        }
		public CSharpBinder (DynamicMetaObjectBinder binder, Compiler.Expression expr, DynamicMetaObject errorSuggestion)
		{
			this.binder = binder;
			this.expr = expr;
			this.restrictions = BindingRestrictions.Empty;
			this.errorSuggestion = errorSuggestion;
		}
示例#29
0
        internal static DynamicMetaObject ConvertToString(DynamicMetaObjectBinder conversion, DynamicMetaObject self)
        {
            Assert.NotNull(conversion, self);

            TotemType ltype = MetaTotemObject.GetTotemType(self);
            var matches = ltype.GetOperatorFunctions(TotemOperationKind.ToString).ToList();

            var overloadResolver = GetTotemContext(conversion).SharedOverloadResolverFactory.CreateOverloadResolver(new[] { self }, new CallSignature(1), CallTypes.None);
            var ret = overloadResolver.ResolveOverload("ToString", ArrayUtils.ToArray(matches, m => CreateOverloadInfo(m)), NarrowingLevel.None, NarrowingLevel.All);

            if (!ret.Success)
            {
                return new DynamicMetaObject(
                    Expression.Throw(
                        Expression.Call(
                            AstMethods.TypeError,
                            Utils.Constant("No toString found on type {1}."),
                            Expression.NewArrayInit(
                                typeof(string),
                                Expression.Constant(ltype.Name)
                            )
                        )
                    ),
                    BindingRestrictions.Combine(new[] { self })
                );
            }
            return new DynamicMetaObject(ret.MakeExpression(), ret.RestrictedArguments.GetAllRestrictions());
        }
 public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] packedIndexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
 {
     if (IDOUtils.NeedsDeferral(target, packedIndexes, value))
     {
         Array.Resize<DynamicMetaObject>(ref packedIndexes, packedIndexes.Length + 1);
         packedIndexes[packedIndexes.Length - 1] = value;
         return this.Defer(target, packedIndexes);
     }
     string[] argNames = null;
     Expression[] args = null;
     object[] argValues = null;
     IDOUtils.UnpackArguments(packedIndexes, this.CallInfo, ref args, ref argNames, ref argValues);
     object[] array = new object[argValues.Length + 1];
     argValues.CopyTo(array, 0);
     array[argValues.Length] = value.Value;
     if ((errorSuggestion != null) && !NewLateBinding.CanIndexSetComplex(target.Value, array, argNames, this._optimisticSet, this._rValueBase))
     {
         return errorSuggestion;
     }
     Expression expression2 = IDOUtils.ConvertToObject(value.Expression);
     Expression[] expressionArray2 = new Expression[args.Length + 1];
     args.CopyTo(expressionArray2, 0);
     expressionArray2[args.Length] = expression2;
     return new DynamicMetaObject(Expression.Block(Expression.Call(typeof(NewLateBinding).GetMethod("FallbackIndexSetComplex"), target.Expression, Expression.NewArrayInit(typeof(object), expressionArray2), Expression.Constant(argNames, typeof(string[])), Expression.Constant(this._optimisticSet), Expression.Constant(this._rValueBase)), expression2), IDOUtils.CreateRestrictions(target, packedIndexes, value));
 }
示例#31
0
        public override Dyn.DynamicMetaObject FallbackConvert(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue)
            {
                return(Defer(target));
            }

            if (target.LimitType.IsSubclassOf(typeof(Any)))
            {
                return(new Dyn.DynamicMetaObject(Expression.Convert(target.Expression, typeof(Any)), target.Restrictions.Merge(Dyn.BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))));
            }

            if (target.Value == null)
            {
                return(new Dyn.DynamicMetaObject(Expression.Constant(Any.None, typeof(Any)), Dyn.BindingRestrictions.GetInstanceRestriction(target.Expression, null)));
            }

            var targetExpression = target.Expression;

            if (targetExpression.Type != target.LimitType)
            {
                targetExpression = Expression.Convert(targetExpression, target.LimitType);
            }

            var restrictions = target.Restrictions
                               .Merge(Dyn.BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));

            var converter = converters[target.LimitType];

            return(new Dyn.DynamicMetaObject(converter(targetExpression), restrictions));
        }
        private DynamicMetaObject MakeDeleteMemberTarget(SetOrDeleteMemberInfo delInfo, DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
            Type type = target.GetLimitType();
            BindingRestrictions restrictions = target.Restrictions;
            DynamicMetaObject self = target;

            if (typeof(TypeTracker).IsAssignableFrom(type)) {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)
                );

                type = ((TypeTracker)target.Value).Type;
                self = null;
            }

            delInfo.Body.Restrictions = restrictions;

            if (self == null || !MakeOperatorDeleteMemberBody(delInfo, self, type, "DeleteMember")) {
                MemberGroup group = GetMember(MemberRequestKind.Delete, type, delInfo.Name);
                if (group.Count != 0) {
                    if (group[0].MemberType == TrackerTypes.Property) {
                        MethodInfo del = ((PropertyTracker)group[0]).GetDeleteMethod(PrivateBinding);
                        if (del != null) {
                            MakePropertyDeleteStatement(delInfo, self, del);
                            return delInfo.Body.GetMetaObject(target);
                        }
                    }

                    delInfo.Body.FinishCondition(errorSuggestion ?? MakeError(MakeUndeletableMemberError(GetDeclaringMemberType(group), delInfo.Name), typeof(void)));
                } else {
                    delInfo.Body.FinishCondition(errorSuggestion ?? MakeError(MakeMissingMemberErrorForDelete(type, self, delInfo.Name), typeof(void)));
                }
            }

            return delInfo.Body.GetMetaObject(target);
        }
示例#33
0
        public override Dyn.DynamicMetaObject FallbackUnaryOperation(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue)
            {
                return(Defer(target));
            }

            throw new NotImplementedException();
        }
示例#34
0
        public override DYN.DynamicMetaObject FallbackGetIndex(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] indexes, DYN.DynamicMetaObject errorSuggestion)
        {
            DLR.Expression          expression;
            DYN.BindingRestrictions restriction;

            if (indexes.Length == 1 && indexes[0].HasValue && indexes[0].Value == null)
            {
                restriction = DYN.BindingRestrictions.GetExpressionRestriction(
                    DLR.Expression.Equal(indexes[0].Expression, DLR.Expression.Constant(null))
                    );

                expression = target.Expression;
            }
            else
            {
                restriction = DYN.BindingRestrictions.GetTypeRestriction(
                    indexes[0].Expression, typeof(List <Types.AType>)
                    );

                var indexer = DLR.Expression.Convert(indexes[0].Expression, typeof(List <Types.AType>));

                var rankCheck = DLR.Expression.IfThen(
                    DLR.Expression.LessThan(
                        DLR.Expression.Property(target.Expression, "Rank"),
                        DLR.Expression.Property(indexer, "Count")
                        ),
                    DLR.Expression.Throw(
                        DLR.Expression.New(typeof(Error.Rank).GetConstructor(new Type[] { typeof(string) }),
                                           //DLR.Expression.Constant("[]")
                                           // FIXME-LATER: This is just for debug, so remove it later:
                                           DLR.Expression.Call(
                                               DLR.Expression.Property(indexer, "Count"),
                                               typeof(Int32).GetMethod("ToString", new Type[] { })
                                               )
                                           )
                        )
                    );

                expression = DLR.Expression.Block(
                    rankCheck,
                    DLR.Expression.MakeIndex(
                        DLR.Expression.Convert(target.Expression, typeof(Types.AType)),
                        GetIndexBinder.AArrayIndexerProperty,
                        new DLR.Expression[] { indexer }
                        )
                    );
            }

            DYN.DynamicMetaObject dynobj = new DYN.DynamicMetaObject(
                expression,
                DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType).Merge(restriction)
                );

            return(dynobj);
        }
示例#35
0
        /// <summary>
        /// Prints the list of contexts
        /// </summary>
        /// <param name="scope"></param>
        /// <returns></returns>
        public static AType PrintContexts(DYN.IDynamicMetaObjectProvider scope)
        {
            DYN.DynamicMetaObject storage = scope.GetMetaObject(
                DLR.Expression.Property(
                    DLR.Expression.Convert(DLR.Expression.Constant(scope), typeof(Scope)),
                    "Storage"
                    )
                );

            Console.WriteLine(String.Join(" ", storage.GetDynamicMemberNames()));

            return(Utils.ANull());
        }
示例#36
0
        public override Dyn.DynamicMetaObject FallbackBinaryOperation(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject arg, Dyn.DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || !arg.HasValue)
            {
                return(Defer(target, arg));
            }

            var restrictions = target.Restrictions.Merge(arg.Restrictions)
                               .Merge(Dyn.BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))
                               .Merge(Dyn.BindingRestrictions.GetTypeRestriction(arg.Expression, arg.LimitType));

            throw new NotImplementedException();
        }
            private DynamicMetaObject CallMethod(
                MethodInfo method,
                Expression[] parameters
                )
            {
                var callMethod = new System.Dynamic.DynamicMetaObject(
                    System.Linq.Expressions.Expression.Call(
                        System.Linq.Expressions.Expression.Convert(Expression, LimitType),
                        method,
                        parameters),
                    System.Dynamic.BindingRestrictions.GetTypeRestriction(Expression, LimitType)
                    );

                return(callMethod);
            }
示例#38
0
        public override DYN.DynamicMetaObject FallbackConvert(DYN.DynamicMetaObject target, DYN.DynamicMetaObject errorSuggestion)
        {
            DYN.BindingRestrictions restriction = DYN.BindingRestrictions.GetTypeRestriction(
                target.Expression, target.RuntimeType
                );

            // Found an AType, simply return the expression
            // We check if it implements the AType interface
            if (target.RuntimeType.GetInterface("AType") != null)
            {
                DYN.DynamicMetaObject result = new DYN.DynamicMetaObject(
                    DLR.Expression.Convert(target.Expression, typeof(AType)),
                    restriction
                    );

                return(result);
            }
            else if (target.RuntimeType.Name == "Int32")
            {
                DYN.DynamicMetaObject result = new DYN.DynamicMetaObject(
                    // Create a new AInteger from the input value (need to convert to int first)
                    DLR.Expression.Call(
                        typeof(AInteger).GetMethod("Create", new Type[] { typeof(int) }),
                        DLR.Expression.Convert(target.Expression, typeof(int))
                        ),
                    restriction
                    );

                // .New AplusCore.Types.AInteger((System.Int32)$$arg0)
                return(result);
            }
            else if (target.RuntimeType.Name == "String")
            {
                DYN.DynamicMetaObject result = new DYN.DynamicMetaObject(
                    DLR.Expression.Convert(target.Expression, typeof(AType),
                                           typeof(Helpers).GetMethod("BuildString")
                                           ),
                    restriction
                    );

                return(result);
            }

            // TODO::
            throw new NotImplementedException();
        }
        /// <summary>
        /// Performs the binding of the dynamic set member operation.
        /// </summary>
        /// <param name="binder">An instance of the <see cref="T:System.Dynamic.SetMemberBinder" /> that represents the details of the dynamic operation.</param>
        /// <param name="value">The <see cref="T:System.Dynamic.DynamicMetaObject" /> representing the value for the set member operation.</param>
        /// <returns>The new <see cref="T:System.Dynamic.DynamicMetaObject" /> representing the result of the binding.</returns>
        public override System.Dynamic.DynamicMetaObject BindSetMember(System.Dynamic.SetMemberBinder binder, System.Dynamic.DynamicMetaObject value)
        {
            var parameters = new System.Linq.Expressions.Expression[]
            {
                System.Linq.Expressions.Expression.Constant(binder.Name),
                value.Expression,
            };

            var callMethod = CallMethod(setValueMethod, parameters);

            return(callMethod);
        }
示例#40
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="target">The <see cref="CallbackItem"/> to use.</param>
        /// <param name="args"></param>
        /// <remarks>
        /// Order of items in the <see cref="args"/> array:
        /// <list type="number">
        ///  <item><see cref="Aplus"/></item>
        ///  <item>New value for the global variable</item>
        /// </list>
        /// </remarks>
        /// <returns></returns>
        public override DYN.DynamicMetaObject Bind(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNull(target, "target");
            ContractUtils.RequiresNotNullItems(args, "args");

            if (target.HasValue && target.Value is CallbackItem)
            {
                CallbackItem callbackItem      = (CallbackItem)target.Value;
                AFunc        callbackAFunction = (AFunc)callbackItem.CallbackFunction.Data;

                DLR.Expression callbackItemExpression = DLR.Expression.Convert(
                    target.Expression, typeof(CallbackItem)
                    );


                DYN.BindingRestrictions baseRestriction = DYN.BindingRestrictions.GetTypeRestriction(
                    target.Expression, target.LimitType
                    );

                DLR.Expression callbackAFunctionExpression = DLR.Expression.Convert(
                    DLR.Expression.Convert(target.Expression, typeof(CallbackItem))
                    .Property("CallbackFunction").Property("Data"),
                    typeof(AFunc)
                    );

                DYN.BindingRestrictions valenceRestriction =
                    DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.Equal(
                            callbackAFunctionExpression.Property("Valence"),
                            DLR.Expression.Constant(callbackAFunction.Valence)
                            )
                        );

                // TODO: refactor the argument generation, something similar is in the InvokeBinder

                IEnumerable <DLR.Expression> callbackBaseArguments = new DLR.Expression[] {
                    callbackItemExpression.Property("StaticData"),             // static data
                    DLR.Expression.Convert(args[1].Expression, typeof(AType)), // new value
                    DLR.Expression.Convert(args[2].Expression, typeof(AType)), // index/set of indices
                    DLR.Expression.Convert(args[3].Expression, typeof(AType)), // path (left argument of pick)
                    callbackItemExpression.Property("Context"),                // context of the global variable
                    callbackItemExpression.Property("UnqualifiedName")         // name of the global variable
                }.Where((item, i) => i < callbackAFunction.Valence - 1).Reverse();
                List <DLR.Expression> callbackArguments = new List <DLR.Expression>();

                // Aplus
                callbackArguments.Add(DLR.Expression.Convert(args[0].Expression, args[0].RuntimeType));
                callbackArguments.AddRange(callbackBaseArguments);


                Type[] callTypes = new Type[callbackAFunction.Valence + 1];
                callTypes[0] = typeof(Aplus);

                for (int i = 1; i < callbackAFunction.Valence; i++)
                {
                    callTypes[i] = typeof(AType);
                }

                // return type
                callTypes[callbackAFunction.Valence] = typeof(AType);


                DLR.Expression codeBlock = DLR.Expression.Invoke(
                    DLR.Expression.Convert(
                        callbackAFunctionExpression.Property("Method"),
                        DLR.Expression.GetFuncType(callTypes)
                        ),
                    callbackArguments
                    );

                DYN.DynamicMetaObject dynobj =
                    new DYN.DynamicMetaObject(codeBlock, baseRestriction.Merge(valenceRestriction));

                return(dynobj);
            }

            // Throw a non-function error
            return(new DYN.DynamicMetaObject(
                       DLR.Expression.Throw(
                           DLR.Expression.New(
                               typeof(Error.NonFunction).GetConstructor(new Type[] { typeof(string) }),
                               DLR.Expression.Call(
                                   target.Expression,
                                   typeof(object).GetMethod("ToString")
                                   )
                               ),
                           typeof(Error.NonFunction)
                           ),
                       DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType)
                       ));
        }
示例#41
0
        public override DYN.DynamicMetaObject FallbackInvoke(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] args, DYN.DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value is AReference &&
                ((AReference)target.Value).Data is AFunc)
            {
                DLR.Expression dataExpression =
                    DLR.Expression.PropertyOrField(
                        DLR.Expression.Convert(target.Expression, typeof(AType)),
                        "Data"
                        );

                DYN.BindingRestrictions baseRestriction = DYN.BindingRestrictions.GetTypeRestriction(
                    target.Expression, target.LimitType
                    );

                DYN.BindingRestrictions builtinRestriction;
                DYN.BindingRestrictions restriction;

                DLR.Expression targetExpression = DLR.Expression.Convert(dataExpression, typeof(AFunc));

                // Func<..> types (argument types + return type)
                Type[] callTypes;

                // Convert every function parameters to AType
                DLR.Expression[] callArguments;

                DLR.Expression codeBlock = null;

                if (((AFunc)((AReference)target.Value).Data).IsBuiltin)
                {
                    switch (this.CallInfo.ArgumentCount)
                    {
                    case 2:
                        callTypes     = new Type[args.Length + 2];
                        callArguments = new DLR.Expression[args.Length + 1];
                        BuildArguments(args, callTypes, callArguments);
                        // Add the missing infos:
                        callTypes[2]     = typeof(AType);
                        callArguments[2] = DLR.Expression.Constant(null, typeof(AType));
                        // Build the codeblock for the method invoke
                        codeBlock = BuildInvoke(targetExpression, callTypes, callArguments);
                        break;

                    case 3:
                        callTypes     = new Type[args.Length + 1];
                        callArguments = new DLR.Expression[args.Length];
                        BuildArguments(args, callTypes, callArguments);
                        // Build the codeblock for the method invoke
                        codeBlock = BuildInvoke(targetExpression, callTypes, callArguments);
                        break;

                    default:
                        // Every other case is invalid...
                        codeBlock = DLR.Expression.Block(
                            DLR.Expression.Throw(
                                DLR.Expression.New(
                                    typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                    DLR.Expression.Property(targetExpression, "Name")
                                    )
                                ),
                            DLR.Expression.Default(typeof(AType))
                            );
                        break;
                    }

                    builtinRestriction = DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.IsTrue(DLR.Expression.Property(targetExpression, "IsBuiltin"))
                        );
                }
                else
                {
                    callTypes     = new Type[args.Length + 1];
                    callArguments = new DLR.Expression[args.Length];

                    BuildArguments(args, callTypes, callArguments);

                    codeBlock = DLR.Expression.Block(
                        // Check if the function we are calling have the correct valence
                        DLR.Expression.IfThen(
                            DLR.Expression.NotEqual(
                                DLR.Expression.Property(targetExpression, "Valence"),
                                DLR.Expression.Constant(this.CallInfo.ArgumentCount)
                                ),
                            // Function's valence is incorrect throw error
                            DLR.Expression.Throw(
                                DLR.Expression.New(
                                    typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                    DLR.Expression.Property(targetExpression, "Name")
                                    )
                                )
                            ),
                        // Function's valence is OK
                        // Call the function
                        BuildInvoke(targetExpression, callTypes, callArguments)
                        );

                    builtinRestriction = DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.IsFalse(DLR.Expression.Property(targetExpression, "IsBuiltin"))
                        );
                }

                restriction = baseRestriction.Merge(builtinRestriction);

                DYN.DynamicMetaObject dynobj = new DYN.DynamicMetaObject(codeBlock, restriction);

                return(dynobj);
            }

            // Throw a non-function error
            return(new DYN.DynamicMetaObject(
                       DLR.Expression.Throw(
                           DLR.Expression.New(
                               typeof(Error.NonFunction).GetConstructor(new Type[] { typeof(string) }),
                               DLR.Expression.Call(
                                   target.Expression,
                                   typeof(object).GetMethod("ToString")
                                   )
                               ),
                           typeof(Error.NonFunction)
                           ),
                       DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType)
                       ));
        }
示例#42
0
 public override DYN.DynamicMetaObject FallbackSetMember(DYN.DynamicMetaObject target, DYN.DynamicMetaObject value, DYN.DynamicMetaObject errorSuggestion)
 {
     // NOTE: silently ignore everything for now...
     return(null); // TODO: fix this!
 }
示例#43
0
 public override Dyn.DynamicMetaObject FallbackGetIndex(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject[] indexes, Dyn.DynamicMetaObject errorSuggestion)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// When overridden in the derived class, performs the binding of the dynamic get index operation if the target dynamic object cannot bind.
 /// </summary>
 /// <param name="target">The target of the dynamic get index operation.</param>
 /// <param name="indexes">The arguments of the dynamic get index operation.</param>
 /// <param name="errorSuggestion">The binding result to use if binding fails, or null.</param>
 /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
 public abstract DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion);
示例#45
0
 public override Dyn.DynamicMetaObject FallbackSetMember(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject value, Dyn.DynamicMetaObject errorSuggestion)
 {
     throw new NotImplementedException();
 }
示例#46
0
        public override DYN.DynamicMetaObject FallbackSetIndex(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] indexes, DYN.DynamicMetaObject value, DYN.DynamicMetaObject errorSuggestion)
        {
            DLR.Expression          expression;
            DYN.BindingRestrictions restriction;

            // TODO: Fix this: add restirction to AType interface
            //// check if the target implements the AType interface
            //if (target.RuntimeType.GetInterface("AType") == null)
            //{
            //    dynobj = new DYN.DynamicMetaObject(
            //        DLR.Expression.Block(
            //            DLR.Expression.Throw(
            //                DLR.Expression.New(
            //                    typeof(Error.Mismatch).GetConstructor(new Type[] { typeof(string) }),
            //                    DLR.Expression.Constant(
            //                        String.Format("No indexing defined on '{0}'", target.RuntimeType.ToString())
            //                    )
            //                )
            //            ),
            //            value.Expression
            //        ),
            //        restriction
            //    );

            //    return dynobj;
            //}

            if (indexes.Length == 1 && indexes[0].HasValue && indexes[0].Value == null)
            {
                restriction = DYN.BindingRestrictions.GetExpressionRestriction(
                    DLR.Expression.Equal(indexes[0].Expression, DLR.Expression.Constant(null))
                    );

                BindingFlags searchFlags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;

                expression = DLR.Expression.Block(
                    DLR.Expression.Call(
                        null,
                        typeof(Utils).GetMethod("PerformAssign", searchFlags),
                        DLR.Expression.Convert(target.Expression, typeof(AType)),
                        DLR.Expression.Convert(value.Expression, typeof(AType))
                        ),
                    value.Expression
                    );
            }
            else
            {
                // $target[$indexes] = $value;
                restriction = DYN.BindingRestrictions.GetTypeRestriction(
                    indexes[0].Expression, typeof(List <Types.AType>)
                    );

                var indexer = DLR.Expression.Convert(indexes[0].Expression, typeof(List <Types.AType>));

                var rankCheck = DLR.Expression.IfThen(
                    DLR.Expression.LessThan(
                        DLR.Expression.Property(target.Expression, "Rank"),
                        DLR.Expression.Property(indexer, "Count")
                        ),
                    DLR.Expression.Throw(
                        DLR.Expression.New(typeof(Error.Rank).GetConstructor(new Type[] { typeof(string) }),
                                           //DLR.Expression.Constant("[]")
                                           // FIXME-LATER: This is just for debug, so remove it later:
                                           DLR.Expression.Call(
                                               DLR.Expression.Property(indexer, "Count"),
                                               typeof(Int32).GetMethod("ToString", new Type[] { })
                                               )
                                           )
                        )
                    );

                expression = DLR.Expression.Block(
                    typeof(Types.AType),
                    rankCheck,
                    DLR.Expression.Assign(
                        DLR.Expression.MakeIndex(
                            DLR.Expression.Convert(Tools.CloneMemoryMappedFile(target.Expression), typeof(Types.AType)),
                            SetIndexBinder.AArrayIndexerProperty,
                            new DLR.Expression[] { indexer }
                            ),
                        value.Expression
                        ),
                    value.Expression
                    );
            }

            DYN.DynamicMetaObject dynobj = new DYN.DynamicMetaObject(
                expression,
                DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType).Merge(restriction)
                );

            return(dynobj);
        }
示例#47
0
 public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
 {
     return(default(DynamicMetaObject));
 }
示例#48
0
 public DynamicMetaObject FallbackGetMember(DynamicMetaObject target)
 {
     return(default(DynamicMetaObject));
 }
 public DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args)
 {
     return(this.FallbackInvokeMember(target, args, null));
 }
示例#50
0
 public abstract DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion);
 public abstract DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion);
 public abstract DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion);
示例#53
0
 public override Dyn.DynamicMetaObject FallbackInvoke(Dyn.DynamicMetaObject target, Dyn.DynamicMetaObject[] args, Dyn.DynamicMetaObject errorSuggestion)
 {
     throw new NotImplementedException();
 }
 public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
 {
     ContractUtils.RequiresNotNull(target, "target");
     ContractUtils.RequiresNotNullItems <DynamicMetaObject>(args, "args");
     return(target.BindInvokeMember(this, args));
 }
 public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args);
 public DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg)
 {
     return(this.FallbackBinaryOperation(target, arg, null));
 }
示例#57
0
 /// <summary>
 ///     Performs the binding of the dynamic create operation if the target dynamic object cannot bind.
 /// </summary>
 /// <param name="target">The target of the dynamic create operation.</param>
 /// <param name="args">The arguments of the dynamic create operation.</param>
 /// <returns>The <see cref="DynamicMetaObject" /> representing the result of the binding.</returns>
 public DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args)
 {
     return(FallbackCreateInstance(target, args, null));
 }
        public sealed override Expression Bind(object[] args, ReadOnlyCollection <ParameterExpression> parameters, LabelTarget returnLabel)
        {
            Type returnType;

            ContractUtils.RequiresNotNull(args, "args");
            ContractUtils.RequiresNotNull(parameters, "parameters");
            ContractUtils.RequiresNotNull(returnLabel, "returnLabel");
            if (args.Length == 0)
            {
                throw Error.OutOfRange("args.Length", 1);
            }
            if (parameters.Count == 0)
            {
                throw Error.OutOfRange("parameters.Count", 1);
            }
            if (args.Length != parameters.Count)
            {
                throw new ArgumentOutOfRangeException("args");
            }
            if (this.IsStandardBinder)
            {
                returnType = this.ReturnType;
                if ((returnLabel.Type != typeof(void)) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, returnType))
                {
                    throw Error.BinderNotCompatibleWithCallSite(returnType, this, returnLabel.Type);
                }
            }
            else
            {
                returnType = returnLabel.Type;
            }
            DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]);

            DynamicMetaObject[] objArray = CreateArgumentMetaObjects(args, parameters);
            DynamicMetaObject   obj3     = this.Bind(target, objArray);

            if (obj3 == null)
            {
                throw Error.BindingCannotBeNull();
            }
            Expression          expression   = obj3.Expression;
            BindingRestrictions restrictions = obj3.Restrictions;

            if ((returnType != typeof(void)) && !TypeUtils.AreReferenceAssignable(returnType, expression.Type))
            {
                if (target.Value is IDynamicMetaObjectProvider)
                {
                    throw Error.DynamicObjectResultNotAssignable(expression.Type, target.Value.GetType(), this, returnType);
                }
                throw Error.DynamicBinderResultNotAssignable(expression.Type, this, returnType);
            }
            if ((this.IsStandardBinder && (args[0] is IDynamicMetaObjectProvider)) && (restrictions == BindingRestrictions.Empty))
            {
                throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this);
            }
            restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters);
            if (expression.NodeType != ExpressionType.Goto)
            {
                expression = Expression.Return(returnLabel, expression);
            }
            if (restrictions != BindingRestrictions.Empty)
            {
                expression = Expression.IfThen(restrictions.ToExpression(), expression);
            }
            return(expression);
        }
示例#59
0
        /// <summary>
        /// Performs the runtime binding of the dynamic operation on a set of arguments.
        /// </summary>
        /// <param name="args">An array of arguments to the dynamic operation.</param>
        /// <param name="parameters">The array of <see cref="ParameterExpression"/> instances that represent the parameters of the call site in the binding process.</param>
        /// <param name="returnLabel">A LabelTarget used to return the result of the dynamic binding.</param>
        /// <returns>
        /// An Expression that performs tests on the dynamic operation arguments, and
        /// performs the dynamic operation if the tests are valid. If the tests fail on
        /// subsequent occurrences of the dynamic operation, Bind will be called again
        /// to produce a new <see cref="Expression"/> for the new argument types.
        /// </returns>
        public sealed override Expression Bind(object[] args, ReadOnlyCollection <ParameterExpression> parameters, LabelTarget returnLabel)
        {
            ContractUtils.RequiresNotNull(args, "args");
            ContractUtils.RequiresNotNull(parameters, "parameters");
            ContractUtils.RequiresNotNull(returnLabel, "returnLabel");
            if (args.Length == 0)
            {
                throw Error.OutOfRange("args.Length", 1);
            }
            if (parameters.Count == 0)
            {
                throw Error.OutOfRange("parameters.Count", 1);
            }
            if (args.Length != parameters.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(args));
            }

            // Ensure that the binder's ReturnType matches CallSite's return
            // type. We do this so meta objects and language binders can
            // compose trees together without needing to insert converts.
            Type expectedResult;

            if (IsStandardBinder)
            {
                expectedResult = ReturnType;

                if (returnLabel.Type != typeof(void) &&
                    !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult))
                {
                    throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type);
                }
            }
            else
            {
                // Even for non-standard binders, we have to at least make sure
                // it works with the CallSite's type to build the return.
                expectedResult = returnLabel.Type;
            }

            DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]);

            DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters);

            DynamicMetaObject binding = Bind(target, metaArgs);

            if (binding == null)
            {
                throw Error.BindingCannotBeNull();
            }

            Expression          body         = binding.Expression;
            BindingRestrictions restrictions = binding.Restrictions;

            // Ensure the result matches the expected result type.
            if (expectedResult != typeof(void) &&
                !TypeUtils.AreReferenceAssignable(expectedResult, body.Type))
            {
                //
                // Blame the last person that handled the result: assume it's
                // the dynamic object (if any), otherwise blame the language.
                //
                if (target.Value is IDynamicMetaObjectProvider)
                {
                    throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult);
                }
                else
                {
                    throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult);
                }
            }

            // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding.
            // it makes sense to restrict on the target's type in such cases.
            // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant.
            if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null)
            {
                if (restrictions == BindingRestrictions.Empty)
                {
                    throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this);
                }
            }

            // Add the return
            if (body.NodeType != ExpressionType.Goto)
            {
                body = Expression.Return(returnLabel, body);
            }

            // Finally, add restrictions
            if (restrictions != BindingRestrictions.Empty)
            {
                body = Expression.IfThen(restrictions.ToExpression(), body);
            }

            return(body);
        }
示例#60
0
 /// <summary>
 ///     When overridden in the derived class, performs the binding of the dynamic create operation if the target dynamic
 ///     object cannot bind.
 /// </summary>
 /// <param name="target">The target of the dynamic create operation.</param>
 /// <param name="args">The arguments of the dynamic create operation.</param>
 /// <param name="errorSuggestion">The binding result to use if binding fails, or null.</param>
 /// <returns>The <see cref="DynamicMetaObject" /> representing the result of the binding.</returns>
 public abstract DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject?errorSuggestion);