Ejemplo n.º 1
0
 public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                Expression.Constant("FallbackSetMember"),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                ));
 }
Ejemplo n.º 2
0
        public DynamicMetaObject MakeCallExpression(OverloadResolverFactory resolverFactory, MethodInfo method, params DynamicMetaObject[] parameters)
        {
            OverloadResolver resolver;

            if (method.IsStatic)
            {
                resolver = resolverFactory.CreateOverloadResolver(parameters, new CallSignature(parameters.Length), CallTypes.None);
            }
            else
            {
                resolver = resolverFactory.CreateOverloadResolver(parameters, new CallSignature(parameters.Length - 1), CallTypes.ImplicitInstance);
            }
            BindingTarget target = resolver.ResolveOverload(method.Name, new MethodBase[] { method }, NarrowingLevel.None, NarrowingLevel.All);

            if (!target.Success)
            {
                BindingRestrictions restrictions = BindingRestrictions.Combine(parameters);
                foreach (DynamicMetaObject mo in parameters)
                {
                    restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(mo.Expression, mo.GetLimitType()));
                }
                return(DefaultBinder.MakeError(
                           resolver.MakeInvalidParametersError(target),
                           restrictions,
                           typeof(object)
                           ));
            }

            return(new DynamicMetaObject(target.MakeExpression(), target.RestrictedArguments.GetAllRestrictions()));
        }
Ejemplo n.º 3
0
        private DynamicMetaObject MakeArrayIndexRule(OverloadResolverFactory factory, IndexType oper, DynamicMetaObject[] args)
        {
            if (CanConvertFrom(GetArgType(args, 1), typeof(int), false, NarrowingLevel.All))
            {
                BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));

                if (oper == IndexType.Get)
                {
                    return(new DynamicMetaObject(
                               Expression.ArrayAccess(
                                   args[0].Expression,
                                   ConvertIfNeeded(factory, args[1].Expression, typeof(int))
                                   ),
                               restrictions
                               ));
                }

                return(new DynamicMetaObject(
                           Expression.Assign(
                               Expression.ArrayAccess(
                                   args[0].Expression,
                                   ConvertIfNeeded(factory, args[1].Expression, typeof(int))
                                   ),
                               ConvertIfNeeded(factory, args[2].Expression, args[0].GetLimitType().GetElementType())
                               ),
                           restrictions.Merge(args[1].Restrictions)
                           ));
            }

            return(null);
        }
Ejemplo n.º 4
0
 public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                Expression.Constant(_result, ReturnType),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                ));
 }
        public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value == null)
            {
                return(errorSuggestion ??
                       new DynamicMetaObject(
                           Expression.Throw(
                               Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                              Expression.Constant(String.Format("Cannot call {0} method named {1} on nil", _isStatic ? "static" : "instance", this.Name))),
                               typeof(object)),
                           BindingRestrictions.GetInstanceRestriction(target.Expression, null)));
            }



            Type typeToUse = _isStatic && target.Value is Type ? (Type)target.Value : target.LimitType;


            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length + (_isStatic ? 0 : 1));

            if (!_isStatic)
            {
                argsPlus.Add(target);
            }
            foreach (DynamicMetaObject arg in args)
            {
                argsPlus.Add(arg);
            }

            OverloadResolverFactory factory = _context.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), _isStatic ? CallTypes.None : CallTypes.ImplicitInstance);

            BindingFlags       flags   = BindingFlags.InvokeMethod | BindingFlags.Public | (_isStatic ? BindingFlags.Static : BindingFlags.Instance);
            IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetMethods(flags).Where <MethodBase>(x => x.Name == Name && x.GetParameters().Length == args.Length));

            if (methods.Count > 0)
            {
                BindingTarget     bt;
                DynamicMetaObject dmo = _context.Binder.CallMethod(
                    res,
                    methods,
                    target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args))),
                    Name,
                    NarrowingLevel.None,
                    NarrowingLevel.All,
                    out bt);
                dmo = DynUtils.MaybeBoxReturnValue(dmo);

                //; Console.WriteLine(dmo.Expression.DebugView);
                return(dmo);
            }

            return(errorSuggestion ??
                   new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                          Expression.Constant(String.Format("No matching member {0} taking {1} args for {2}", this.Name, args.Length, typeToUse.Name))),
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args)))));
        }
Ejemplo n.º 6
0
        private static DynamicMetaObject MakeCallSignatureResult(MethodBase[] methods, DynamicMetaObject target)
        {
            List <string> arrres = new List <string>();

            if (methods != null)
            {
                foreach (MethodBase mb in methods)
                {
                    StringBuilder res   = new StringBuilder();
                    string        comma = "";
                    foreach (ParameterInfo param in mb.GetParameters())
                    {
                        res.Append(comma);
                        res.Append(param.ParameterType.Name);
                        res.Append(" ");
                        res.Append(param.Name);
                        comma = ", ";
                    }
                    arrres.Add(res.ToString());
                }
            }

            return(new DynamicMetaObject(
                       AstUtils.Constant(arrres.ToArray()),
                       BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target.Expression, target.GetLimitType()).Merge(target.Restrictions)
                       ));
        }
Ejemplo n.º 7
0
 public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                Expression.Constant("FallbackInvoke"),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                ));
 }
Ejemplo n.º 8
0
        private static DynamicMetaObject TryPrimitiveCompare(OperatorInfo info, DynamicMetaObject[] args)
        {
            if (args[0].GetLimitType().GetNonNullableType() == args[1].GetLimitType().GetNonNullableType() &&
                args[0].GetLimitType().IsNumeric())
            {
                Expression arg0 = args[0].Expression;
                Expression arg1 = args[1].Expression;

                // TODO: Nullable<PrimitveType> Support
                Expression expr;
                switch (info.Operator)
                {
                case ExpressionType.Equal: expr = Expression.Equal(arg0, arg1); break;

                case ExpressionType.NotEqual: expr = Expression.NotEqual(arg0, arg1); break;

                case ExpressionType.GreaterThan: expr = Expression.GreaterThan(arg0, arg1); break;

                case ExpressionType.LessThan: expr = Expression.LessThan(arg0, arg1); break;

                case ExpressionType.GreaterThanOrEqual: expr = Expression.GreaterThanOrEqual(arg0, arg1); break;

                case ExpressionType.LessThanOrEqual: expr = Expression.LessThanOrEqual(arg0, arg1); break;

                default: throw new InvalidOperationException();
                }

                return(new DynamicMetaObject(
                           expr,
                           BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg0, args[0].GetLimitType()).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg1, args[0].GetLimitType())).Merge(BindingRestrictions.Combine(args))
                           ));
            }

            return(null);
        }
        public DynamicMetaObject ConvertTo(Type toType, ConversionResultKind kind, DynamicMetaObject arg, OverloadResolverFactory resolverFactory, DynamicMetaObject errorSuggestion)
        {
            ContractUtils.RequiresNotNull(toType, nameof(toType));
            ContractUtils.RequiresNotNull(arg, nameof(arg));

            // 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);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Transforms an invoke member into a Python GetMember/Invoke.  The caller should
        /// verify that the given attribute is not resolved against a normal .NET class
        /// before calling this.  If it is a normal .NET member then a fallback InvokeMember
        /// is preferred.
        /// </summary>
        internal static DynamicMetaObject /*!*/ GenericInvokeMember(InvokeMemberBinder /*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            if (target.NeedsDeferral())
            {
                return(action.Defer(args));
            }

            return(AddDynamicTestAndDefer(action,
                                          action.FallbackInvoke(
                                              new DynamicMetaObject(
                                                  Binders.Get(
                                                      PythonContext.GetCodeContext(action),
                                                      PythonContext.GetPythonContext(action),
                                                      typeof(object),
                                                      action.Name,
                                                      target.Expression
                                                      ),
                                                  BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                                                  ),
                                              args,
                                              null
                                              ),
                                          args,
                                          valInfo
                                          ));
        }
 private BindingRestrictions EnumRestrictions()
 {
     return(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(
                Expression, typeof(ComTypeEnumDesc)
                ).Merge(
                // ((ComTypeEnumDesc)<arg>).TypeLib.Guid == <guid>
                BindingRestrictions.GetExpressionRestriction(
                    Expression.Equal(
                        Expression.Property(
                            Expression.Property(
                                AstUtils.Convert(Expression, typeof(ComTypeEnumDesc)),
                                typeof(ComTypeDesc).GetProperty("TypeLib")),
                            typeof(ComTypeLibDesc).GetProperty("Guid")),
                        AstUtils.Constant(_desc.TypeLib.Guid)
                        )
                    )
                ).Merge(
                BindingRestrictions.GetExpressionRestriction(
                    Expression.Equal(
                        Expression.Property(
                            AstUtils.Convert(Expression, typeof(ComTypeEnumDesc)),
                            typeof(ComTypeEnumDesc).GetProperty("TypeName")
                            ),
                        AstUtils.Constant(_desc.TypeName)
                        )
                    )
                ));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Creates a nested dynamic site which uses the unpacked arguments.
        /// </summary>
        internal DynamicMetaObject InvokeForeignObject(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            // need to unpack any dict / list arguments...
            CallInfo            callInfo;
            List <Expression>   metaArgs;
            Expression          test;
            BindingRestrictions restrictions;

            TranslateArguments(target, args, out callInfo, out metaArgs, out test, out restrictions);

            Debug.Assert(metaArgs.Count > 0);

            return(BindingHelpers.AddDynamicTestAndDefer(
                       this,
                       new DynamicMetaObject(
                           DynamicExpression.Dynamic(
                               _context.CompatInvoke(callInfo),
                               typeof(object),
                               metaArgs.ToArray()
                               ),
                           restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target.Expression, target.GetLimitType()))
                           ),
                       args,
                       new ValidationInfo(test)
                       ));
        }
        public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value == null)
            {
                return(errorSuggestion ??
                       new DynamicMetaObject(
                           Expression.Throw(
                               Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                              Expression.Constant(String.Format("Cannot call {0} field/property/member name {1} on nil", _isStatic ? "static" : "instance", this.Name))),
                               typeof(object)),
                           BindingRestrictions.GetInstanceRestriction(target.Expression, null)));
            }

            Expression instanceExpr = _isStatic ? null : Expression.Convert(target.Expression, target.LimitType);
            Type       typeToUse    = _isStatic && target.Value is Type ? (Type)target.Value : target.LimitType;

            BindingRestrictions restrictions = target.Restrictions.Merge(BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));
            BindingFlags        flags        = BindingFlags.Public;

            if (_isStatic)
            {
                flags |= BindingFlags.Static;
            }
            else
            {
                flags |= BindingFlags.Instance;
            }

            FieldInfo finfo = typeToUse.GetField(Name, flags);

            if (finfo != null)
            {
                return(DynUtils.MaybeBoxReturnValue(new DynamicMetaObject(Expression.Field(instanceExpr, finfo), restrictions)));
            }

            PropertyInfo pinfo = typeToUse.GetProperty(Name, flags);

            if (pinfo != null)
            {
                return(DynUtils.MaybeBoxReturnValue(new DynamicMetaObject(Expression.Property(instanceExpr, pinfo), restrictions)));
            }

            MethodInfo minfo = typeToUse.GetMethod(Name, flags, Type.DefaultBinder, Type.EmptyTypes, new ParameterModifier[0]);

            if (minfo != null)
            {
                return(DynUtils.MaybeBoxReturnValue(new DynamicMetaObject(Expression.Call(instanceExpr, minfo), restrictions)));
            }

            return(errorSuggestion ??
                   new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                          Expression.Constant(String.Format("Cannot find {0} field/property/member name {1}", _isStatic ? "static" : "instance", this.Name))),
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target))));
        }
Ejemplo n.º 14
0
        public static SlotOrFunction /*!*/ GetSlotOrFunction(PythonContext /*!*/ state, string op, params DynamicMetaObject[] types)
        {
            PythonTypeSlot slot;
            SlotOrFunction res;

            if (TryGetBinder(state, types, op, null, out res))
            {
                if (res != SlotOrFunction.Empty)
                {
                    return(res);
                }
            }
            else if (MetaUserObject.GetPythonType(types[0]).TryResolveSlot(state.SharedContext, op, out slot))
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "slotVal");

                Expression[] args = new Expression[types.Length - 1];
                for (int i = 1; i < types.Length; i++)
                {
                    args[i - 1] = types[i].Expression;
                }
                return(new SlotOrFunction(
                           new DynamicMetaObject(
                               Ast.Block(
                                   new ParameterExpression[] { tmp },
                                   MetaPythonObject.MakeTryGetTypeMember(
                                       state,
                                       slot,
                                       tmp,
                                       types[0].Expression,
                                       Ast.Call(
                                           typeof(DynamicHelpers).GetMethod("GetPythonType"),
                                           types[0].Expression
                                           )
                                       ),
                                   DynamicExpression.Dynamic(
                                       state.Invoke(
                                           new CallSignature(args.Length)
                                           ),
                                       typeof(object),
                                       ArrayUtils.Insert <Expression>(
                                           AstUtils.Constant(state.SharedContext),
                                           tmp,
                                           args
                                           )
                                       )
                                   ),
                               BindingRestrictions.Combine(types).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(types[0].Expression, types[0].GetLimitType()))
                               ),
                           slot
                           ));
            }

            return(SlotOrFunction.Empty);
        }
Ejemplo n.º 15
0
 private DynamicMetaObject GetForeignObject(DynamicMetaObject self)
 {
     return(new DynamicMetaObject(
                Expression.Dynamic(
                    _context.CompatGetMember(Name, IsNoThrow),
                    typeof(object),
                    self.Expression
                    ),
                self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType()))
                ));
 }
Ejemplo n.º 16
0
 public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                Expression.Call(
                    typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }),
                    Expression.Constant("FallbackInvoke"),
                    target.Expression
                    ),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                ));
 }
Ejemplo n.º 17
0
 public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
 {
     return(new DynamicMetaObject(
                Expression.Call(
                    typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object), typeof(object) }),
                    Expression.Constant("FallbackSetIndex:"),
                    indexes[0].Expression,
                    value.Expression
                    ),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                ));
 }
Ejemplo n.º 18
0
 private DynamicMetaObject MakeCannotCallRule(DynamicMetaObject self, Type type) {
     return MakeError(
         ErrorInfo.FromException(
             Expression.New(
                 typeof(ArgumentTypeException).GetConstructor(new Type[] { typeof(string) }),
                 AstUtils.Constant(GetTypeName(type) + " is not callable")
             )
         ),
         self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, type)),
         typeof(object)
     );
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Builds the restrictions for calling with a splatted argument array.  Ensures that the
        /// argument is still an ICollection of object and that it has the same number of arguments.
        /// </summary>
        private static BindingRestrictions MakeParamsTest(DynamicMetaObject splattee, bool testTypes)
        {
            IList <object> list = splattee.Value as IList <object>;

            if (list == null)
            {
                if (splattee.Value == null)
                {
                    return(BindingRestrictions.GetExpressionRestriction(Ast.Equal(splattee.Expression, AstUtils.Constant(null))));
                }
                else
                {
                    return(BindingRestrictions.GetTypeRestriction(splattee.Expression, splattee.Value.GetType()));
                }
            }

            BindingRestrictions res = BindingRestrictions.GetExpressionRestriction(
                Ast.AndAlso(
                    Ast.TypeIs(splattee.Expression, typeof(IList <object>)),
                    Ast.Equal(
                        Ast.Property(
                            Ast.Convert(splattee.Expression, typeof(IList <object>)),
                            typeof(ICollection <object>).GetDeclaredProperty("Count")
                            ),
                        AstUtils.Constant(list.Count)
                        )
                    )
                );

            if (testTypes)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    res = res.Merge(
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(
                            Ast.Call(
                                AstUtils.Convert(
                                    splattee.Expression,
                                    typeof(IList <object>)
                                    ),
                                typeof(IList <object>).GetMethod("get_Item"),
                                AstUtils.Constant(i)
                                ),
                            CompilerHelpers.GetType(list[i])
                            )
                        );
                }
            }

            return(res);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Produces a rule for comparing a value to null - supports comparing object references and nullable types.
        /// </summary>
        private static DynamicMetaObject TryNullComparisonRule(DynamicMetaObject[] args)
        {
            Type otherType = args[1].GetLimitType();

            BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));

            if (args[0].GetLimitType() == typeof(DynamicNull))
            {
                if (!otherType.IsValueType)
                {
                    return(new DynamicMetaObject(
                               Expression.Equal(args[0].Expression, AstUtils.Constant(null)),
                               restrictions
                               ));
                }

                if (otherType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(new DynamicMetaObject(
                               Expression.Property(args[0].Expression, otherType.GetDeclaredProperty("HasValue")),
                               restrictions
                               ));
                }
            }
            else if (otherType == typeof(DynamicNull))
            {
                if (!args[0].GetLimitType().IsValueType)
                {
                    return(new DynamicMetaObject(
                               Expression.Equal(args[0].Expression, AstUtils.Constant(null)),
                               restrictions
                               ));
                }

                if (args[0].GetLimitType().GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(new DynamicMetaObject(
                               Expression.Property(args[0].Expression, otherType.GetDeclaredProperty("HasValue")),
                               restrictions
                               ));
                }
            }
            return(null);
        }
Ejemplo n.º 21
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            Expression[] exprs = new Expression[args.Length + 1];
            exprs[0] = Expression.Constant("FallbackInvoke");
            for (int i = 0; i < args.Length; i++)
            {
                exprs[i + 1] = args[i].Expression;
            }

            return(new DynamicMetaObject(
                       Expression.Call(
                           typeof(String).GetMethod("Concat", new Type[] { typeof(object[]) }),
                           Expression.NewArrayInit(
                               typeof(object),
                               exprs
                               )
                           ),
                       BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                       ));
        }
Ejemplo n.º 22
0
        public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            var newTarget = new DynamicMetaObject(Expression.Convert(target.Expression, target.LimitType), BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType), target.Value);
            var exp       = TryConvertExpression(newTarget.Expression, Type, null);

            if (exp == null)
            {
                exp = Expression.Throw(Expression.Constant(new InvalidCastException()), Type);
            }
            if (ReturnType != Type)
            {
                exp = Expression.Convert(exp, ReturnType);
            }
            var ret = _context.Binder.ConvertTo(
                Type,
                Explicit ? Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast : Microsoft.Scripting.Actions.ConversionResultKind.ImplicitCast,
                newTarget,
                new TjsOverloadResolverFactory(_context.Binder),
                new DynamicMetaObject(exp, BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target))
                );

            return(ret);
        }
Ejemplo n.º 23
0
        private static DynamicMetaObject TryMakeDefaultUnaryRule(OperatorInfo info, DynamicMetaObject[] args)
        {
            if (args.Length == 1)
            {
                BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));
                switch (info.Operator)
                {
                case ExpressionType.IsTrue:
                    if (args[0].GetLimitType() == typeof(bool))
                    {
                        return(args[0]);
                    }
                    break;

                case ExpressionType.Negate:
                    if (args[0].GetLimitType().IsArithmetic())
                    {
                        return(new DynamicMetaObject(
                                   Expression.Negate(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;

                case ExpressionType.Not:
                    if (args[0].GetLimitType().IsIntegerOrBool())
                    {
                        return(new DynamicMetaObject(
                                   Expression.Not(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;
                }
            }
            return(null);
        }
Ejemplo n.º 24
0
        public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            var restrictions = target.Restrictions.Merge(
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target));

            //target = target.Restrict(target.RuntimeType);
            //args = args.Select(o => o.Restrict(o.RuntimeType)).ToArray();

            MethodBase targetMethod;

            switch (Name)
            {
            case "SelectMany":
                targetMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(
                    o => o.Name == Name).Skip(3).First().MakeGenericMethod(
                    typeof(object), typeof(object), typeof(object));
                break;

            default:
                targetMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(
                    o => o.Name == Name).First().MakeGenericMethod(
                    typeof(object), typeof(object));
                break;
            }

            foreach (var o in args)
            {
                restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(o));
            }

            return(_binder.CallMethod(
                       new DefaultOverloadResolver(_binder, target, args.ToList(), new CallSignature(args.Length)),
                       new[] { targetMethod },
                       restrictions,
                       Name));
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Translates our CallSignature into a DLR Argument list and gives the simple MetaObject's which are extracted
        /// from the tuple or dictionary parameters being splatted.
        /// </summary>
        private void TranslateArguments(DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args, out CallInfo /*!*/ callInfo, out List <Expression /*!*/> /*!*/ metaArgs, out Expression test, out BindingRestrictions restrictions)
        {
            Argument[] argInfo = _signature.GetArgumentInfos();

            List <string> namedArgNames = new List <string>();

            metaArgs = new List <Expression>();
            metaArgs.Add(target.Expression);
            Expression splatArgTest   = null;
            Expression splatKwArgTest = null;

            restrictions = BindingRestrictions.Empty;

            for (int i = 0; i < argInfo.Length; i++)
            {
                Argument ai = argInfo[i];

                switch (ai.Kind)
                {
                case ArgumentType.Dictionary:
                    PythonDictionary iac      = (PythonDictionary)args[i].Value;
                    List <string>    argNames = new List <string>();

                    foreach (KeyValuePair <object, object> kvp in iac)
                    {
                        string key = (string)kvp.Key;
                        namedArgNames.Add(key);
                        argNames.Add(key);

                        metaArgs.Add(
                            Expression.Call(
                                AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)),
                                typeof(PythonDictionary).GetMethod("get_Item", new[] { typeof(object) }),
                                AstUtils.Constant(key)
                                )
                            );
                    }

                    restrictions   = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType()));
                    splatKwArgTest = Expression.Call(
                        typeof(PythonOps).GetMethod(nameof(PythonOps.CheckDictionaryMembers)),
                        AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)),
                        AstUtils.Constant(argNames.ToArray())
                        );
                    break;

                case ArgumentType.List:
                    IList <object> splattedArgs = (IList <object>)args[i].Value;
                    splatArgTest = Expression.Equal(
                        Expression.Property(AstUtils.Convert(args[i].Expression, args[i].GetLimitType()), typeof(ICollection <object>).GetProperty("Count")),
                        AstUtils.Constant(splattedArgs.Count)
                        );

                    for (int splattedArg = 0; splattedArg < splattedArgs.Count; splattedArg++)
                    {
                        metaArgs.Add(
                            Expression.Call(
                                AstUtils.Convert(args[i].Expression, typeof(IList <object>)),
                                typeof(IList <object>).GetMethod("get_Item"),
                                AstUtils.Constant(splattedArg)
                                )
                            );
                    }

                    restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType()));
                    break;

                case ArgumentType.Named:
                    namedArgNames.Add(ai.Name);
                    metaArgs.Add(args[i].Expression);
                    break;

                case ArgumentType.Simple:
                    metaArgs.Add(args[i].Expression);
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            callInfo = new CallInfo(metaArgs.Count - 1, namedArgNames.ToArray());

            test = splatArgTest;
            if (splatKwArgTest != null)
            {
                test = test != null?Expression.AndAlso(test, splatKwArgTest) : splatKwArgTest;
            }
        }
Ejemplo n.º 26
0
        private DynamicMetaObject /*!*/ MakeSelfCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            BindingRestrictions selfRestrict = Restrictions.Merge(
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(
                    Expression,
                    LimitType
                    )
                ).Merge(
                BindingRestrictions.GetExpressionRestriction(
                    Value.MakeBoundFunctionTest(
                        AstUtils.Convert(Expression, typeof(BuiltinFunction))
                        )
                    )
                );

            Expression instance = Ast.Call(
                typeof(PythonOps).GetMethod("GetBuiltinFunctionSelf"),
                AstUtils.Convert(
                    Expression,
                    typeof(BuiltinFunction)
                    )
                );

            DynamicMetaObject self = GetInstance(instance, CompilerHelpers.GetType(Value.BindingSelf));

            return(Value.MakeBuiltinFunctionCall(
                       call,
                       codeContext,
                       this,
                       ArrayUtils.Insert(self, args),
                       true, // has self
                       selfRestrict,
                       (newArgs) => {
                CallSignature signature = BindingHelpers.GetCallSignature(call);
                DynamicMetaObject res;
                PythonContext state = PythonContext.GetPythonContext(call);
                BindingTarget target;
                PythonOverloadResolver resolver;
                if (Value.IsReversedOperator)
                {
                    resolver = new PythonOverloadResolver(
                        state.Binder,
                        newArgs,
                        GetReversedSignature(signature),
                        codeContext
                        );
                }
                else
                {
                    resolver = new PythonOverloadResolver(
                        state.Binder,
                        self,
                        args,
                        signature,
                        codeContext
                        );
                }

                res = state.Binder.CallMethod(
                    resolver,
                    Value.Targets,
                    self.Restrictions,
                    Value.Name,
                    NarrowingLevel.None,
                    Value.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All,
                    out target
                    );

                return BindingHelpers.CheckLightThrow(call, res, target);
            }
                       ));
        }
Ejemplo n.º 27
0
        internal DynamicMetaObject FallbackConvert(Type returnType, DynamicMetaObject self, DynamicMetaObject errorSuggestion)
        {
            Type type             = Type;
            DynamicMetaObject res = null;

            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
                res = MakeToBoolConversion(self);
                break;

            case TypeCode.Char:
                res = TryToCharConversion(self);
                break;

            case TypeCode.String:
                if (self.GetLimitType() == typeof(Bytes) && !_context.PythonOptions.Python30)
                {
                    res = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("MakeString"),
                            AstUtils.Convert(self.Expression, typeof(IList <byte>))
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(Bytes))
                        );
                }
                break;

            case TypeCode.Object:
                // !!! Deferral?
                if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1)
                {
                    res = MakeToArrayConversion(self, type);
                }
                else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value)))
                {
                    Type genTo = type.GetGenericTypeDefinition();

                    // Interface conversion helpers...
                    if (genTo == typeof(IList <>))
                    {
                        if (self.LimitType == typeof(string))
                        {
                            res = new DynamicMetaObject(
                                Ast.Call(
                                    typeof(PythonOps).GetMethod("MakeByteArray"),
                                    AstUtils.Convert(self.Expression, typeof(string))
                                    ),
                                BindingRestrictions.GetTypeRestriction(
                                    self.Expression,
                                    typeof(string)
                                    )
                                );
                        }
                        else
                        {
                            res = TryToGenericInterfaceConversion(self, type, typeof(IList <object>), typeof(ListGenericWrapper <>));
                        }
                    }
                    else if (genTo == typeof(IDictionary <,>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>));
                    }
                    else if (genTo == typeof(IEnumerable <>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>));
                    }
                }
                else if (type == typeof(IEnumerable))
                {
                    if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) && IsIndexless(self))
                    {
                        res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
                    }
                }
                else if (type == typeof(IEnumerator))
                {
                    if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &&
                        !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &&
                        IsIndexless(self))
                    {
                        res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
                    }
                }
                break;
            }

            if (type.IsEnum && Enum.GetUnderlyingType(type) == self.GetLimitType())
            {
                // numeric type to enum, this is ok if the value is zero
                object value = Activator.CreateInstance(type);

                return(new DynamicMetaObject(
                           Ast.Condition(
                               Ast.Equal(
                                   AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)),
                                   AstUtils.Constant(Activator.CreateInstance(self.GetLimitType()))
                                   ),
                               AstUtils.Constant(value),
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("TypeErrorForBadEnumConversion").MakeGenericMethod(type),
                                   AstUtils.Convert(self.Expression, typeof(object))
                                   )
                               ),
                           self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())),
                           value
                           ));
            }

            return(res ?? EnsureReturnType(returnType, Context.Binder.ConvertTo(Type, ResultKind, self, _context.SharedOverloadResolverFactory, errorSuggestion)));
        }
Ejemplo n.º 28
0
        internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name)
        {
            if (hasSelf)
            {
                args = ArrayUtils.RemoveFirst(args);
            }

            CallSignature sig = BindingHelpers.GetCallSignature(call);

            if (sig.HasDictionaryArgument())
            {
                int index = sig.IndexOf(ArgumentType.Dictionary);

                DynamicMetaObject dict = args[index];

                if (!(dict.Value is IDictionary) && dict.Value != null)
                {
                    // The DefaultBinder only handles types that implement IDictionary.  Here we have an
                    // arbitrary user-defined mapping type.  We'll convert it into a PythonDictionary
                    // and then have an embedded dynamic site pass that dictionary through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)),
                            codeContext,
                            args[index].Expression,
                            AstUtils.Constant(name)
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()),
                        PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name)
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()))
                               ));
                }
            }

            if (sig.HasListArgument())
            {
                int index             = sig.IndexOf(ArgumentType.List);
                DynamicMetaObject str = args[index];

                // TODO: ANything w/ __iter__ that's not an IList<object>
                if (!(str.Value is IList <object>) && str.Value is IEnumerable)
                {
                    // The DefaultBinder only handles types that implement IList<object>.  Here we have a
                    // string.  We'll convert it into a tuple
                    // and then have an embedded dynamic site pass that tuple through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)),
                            Expression.Convert(args[index].Expression, typeof(object))
                            ),
                        BindingRestrictions.Empty
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               function.Restrictions.Merge(
                                   BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType()))
                                   )
                               ));
                }
            }
            return(null);
        }
Ejemplo n.º 29
0
        private DynamicMetaObject /*!*/ GetInstance(Expression /*!*/ instance, Type /*!*/ testType)
        {
            Assert.NotNull(instance, testType);
            object instanceValue = Value.BindingSelf;

            BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(instance, testType);

            // cast the instance to the correct type
            if (CompilerHelpers.IsStrongBox(instanceValue))
            {
                instance      = ReadStrongBoxValue(instance);
                instanceValue = ((IStrongBox)instanceValue).Value;
            }
            else if (!testType.IsEnum)
            {
                // We need to deal w/ wierd types like MarshalByRefObject.
                // We could have an MBRO whos DeclaringType is completely different.
                // Therefore we special case it here and cast to the declaring type

                Type selfType = CompilerHelpers.GetType(Value.BindingSelf);
                selfType = CompilerHelpers.GetVisibleType(selfType);

                if (selfType == typeof(object) && Value.DeclaringType.IsInterface)
                {
                    selfType = Value.DeclaringType;

                    Type genericTypeDefinition = null;
                    if (Value.DeclaringType.IsGenericType &&
                        Value.DeclaringType.FullName == null &&
                        Value.DeclaringType.ContainsGenericParameters &&
                        !Value.DeclaringType.IsGenericTypeDefinition)
                    {
                        // from MSDN: If the current type contains generic type parameters that have not been replaced by
                        // specific types (that is, the ContainsGenericParameters property returns true), but the type
                        // is not a generic type definition (that is, the IsGenericTypeDefinition property returns false),
                        // this property returns Nothing. For example, consider the classes Base and Derived in the following code.

                        // if this type is completely generic (no type arguments specified) then we'll go ahead and get the
                        // generic type definition for the this parameter - that'll let us successfully type infer on it later.
                        var  genericArgs     = Value.DeclaringType.GetGenericArguments();
                        bool hasOnlyGenerics = genericArgs.Length > 0;
                        foreach (var genericParam in genericArgs)
                        {
                            if (!genericParam.IsGenericParameter)
                            {
                                hasOnlyGenerics = false;
                                break;
                            }
                        }
                        if (hasOnlyGenerics)
                        {
                            genericTypeDefinition = Value.DeclaringType.GetGenericTypeDefinition();
                        }
                    }
                    else if (Value.DeclaringType.IsGenericTypeDefinition)
                    {
                        genericTypeDefinition = Value.DeclaringType;
                    }

                    if (genericTypeDefinition != null)
                    {
                        // we're a generic interface method on a non-public type.
                        // We need to see if we can match any types implemented on
                        // the concrete selfType.
                        var interfaces = CompilerHelpers.GetType(Value.BindingSelf).GetInterfaces();
                        foreach (var iface in interfaces)
                        {
                            if (iface.IsGenericType && iface.GetGenericTypeDefinition() == genericTypeDefinition)
                            {
                                selfType = iface;
                                break;
                            }
                        }
                    }
                }

                if (Value.DeclaringType.IsInterface && selfType.IsValueType)
                {
                    // explicit interface implementation dispatch on a value type, don't
                    // unbox the value type before the dispatch.
                    instance = AstUtils.Convert(instance, Value.DeclaringType);
                }
                else if (selfType.IsValueType)
                {
                    // We might be calling a a mutating method (like
                    // Rectangle.Intersect). If so, we want it to mutate
                    // the boxed value directly
                    instance = Ast.Unbox(instance, selfType);
                }
                else
                {
#if SILVERLIGHT
                    instance = AstUtils.Convert(instance, selfType);
#else
                    Type convType = selfType == typeof(MarshalByRefObject) ? CompilerHelpers.GetVisibleType(Value.DeclaringType) : selfType;

                    instance = AstUtils.Convert(instance, convType);
#endif
                }
            }
            else
            {
                // we don't want to cast the enum to its real type, it will unbox it
                // and turn it into its underlying type.  We presumably want to call
                // a method on the Enum class though - so we cast to Enum instead.
                instance = AstUtils.Convert(instance, typeof(Enum));
            }
            return(new DynamicMetaObject(
                       instance,
                       restrictions,
                       instanceValue
                       ));
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Creating a Python type involves calling __new__ and __init__.  We resolve them
        /// and generate calls to either the builtin funcions directly or embed sites which
        /// call the slots at runtime.
        /// </summary>
        private DynamicMetaObject /*!*/ MakePythonTypeCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            ValidationInfo valInfo = MakeVersionCheck();

            DynamicMetaObject self = new RestrictedMetaObject(
                AstUtils.Convert(Expression, LimitType),
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(Expression, LimitType),
                Value
                );
            CallSignature  sig = BindingHelpers.GetCallSignature(call);
            ArgumentValues ai  = new ArgumentValues(sig, self, args);
            NewAdapter     newAdapter;
            InitAdapter    initAdapter;

            if (TooManyArgsForDefaultNew(call, args))
            {
                return(MakeIncorrectArgumentsForCallError(call, ai, valInfo));
            }
            else if (Value.UnderlyingSystemType.IsGenericTypeDefinition)
            {
                return(MakeGenericTypeDefinitionError(call, ai, valInfo));
            }
            else if (Value.HasAbstractMethods(PythonContext.GetPythonContext(call).SharedContext))
            {
                return(MakeAbstractInstantiationError(call, ai, valInfo));
            }

            DynamicMetaObject translated = BuiltinFunction.TranslateArguments(call, codeContext, self, args, false, Value.Name);

            if (translated != null)
            {
                return(translated);
            }

            GetAdapters(ai, call, codeContext, out newAdapter, out initAdapter);
            PythonContext state = PythonContext.GetPythonContext(call);

            // get the expression for calling __new__
            DynamicMetaObject createExpr = newAdapter.GetExpression(state.Binder);

            if (createExpr.Expression.Type == typeof(void))
            {
                return(BindingHelpers.AddDynamicTestAndDefer(
                           call,
                           createExpr,
                           args,
                           valInfo
                           ));
            }

            Expression          res;
            BindingRestrictions additionalRestrictions = BindingRestrictions.Empty;

            if (!Value.IsSystemType && (!(newAdapter is DefaultNewAdapter) || HasFinalizer(call)))
            {
                // we need to dynamically check the return value to see if it's a subtype of
                // the type that we are calling.  If it is then we need to call __init__/__del__
                // for the actual returned type.
                res = Expression.Dynamic(
                    Value.GetLateBoundInitBinder(sig),
                    typeof(object),
                    ArrayUtils.Insert(
                        codeContext,
                        Expression.Convert(createExpr.Expression, typeof(object)),
                        DynamicUtils.GetExpressions(args)
                        )
                    );
                additionalRestrictions = createExpr.Restrictions;
            }
            else
            {
                // just call the __init__ method, built-in types currently have
                // no wacky return values which don't return the derived type.

                // then get the statement for calling __init__
                ParameterExpression allocatedInst = Ast.Variable(createExpr.GetLimitType(), "newInst");
                Expression          tmpRead       = allocatedInst;
                DynamicMetaObject   initCall      = initAdapter.MakeInitCall(
                    state.Binder,
                    new RestrictedMetaObject(
                        AstUtils.Convert(allocatedInst, Value.UnderlyingSystemType),
                        createExpr.Restrictions
                        )
                    );

                List <Expression> body = new List <Expression>();
                Debug.Assert(!HasFinalizer(call));

                // add the call to init if we need to
                if (initCall.Expression != tmpRead)
                {
                    // init can fail but if __new__ returns a different type
                    // no exception is raised.
                    DynamicMetaObject initStmt = initCall;

                    if (body.Count == 0)
                    {
                        body.Add(
                            Ast.Assign(allocatedInst, createExpr.Expression)
                            );
                    }

                    if (!Value.UnderlyingSystemType.IsAssignableFrom(createExpr.Expression.Type))
                    {
                        // return type of object, we need to check the return type before calling __init__.
                        body.Add(
                            AstUtils.IfThen(
                                Ast.TypeIs(allocatedInst, Value.UnderlyingSystemType),
                                initStmt.Expression
                                )
                            );
                    }
                    else
                    {
                        // just call the __init__ method, no type check necessary (TODO: need null check?)
                        body.Add(initStmt.Expression);
                    }
                }

                // and build the target from everything we have
                if (body.Count == 0)
                {
                    res = createExpr.Expression;
                }
                else
                {
                    body.Add(allocatedInst);
                    res = Ast.Block(body);
                }
                res = Ast.Block(new ParameterExpression[] { allocatedInst }, res);

                additionalRestrictions = initCall.Restrictions;
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       call,
                       new DynamicMetaObject(
                           res,
                           self.Restrictions.Merge(additionalRestrictions)
                           ),
                       ArrayUtils.Insert(this, args),
                       valInfo
                       ));
        }