public DynamicMetaObject Create(CallSignature signature, ParameterBinderWithCodeContext parameterBinder, DynamicMetaObject target, DynamicMetaObject[] args) {
            Type t = GetTargetType(target.Value);

            if (t != null) {

                if (typeof(Delegate).IsAssignableFrom(t) && args.Length == 1) {
                    MethodInfo dc = GetDelegateCtor(t);

                    // BinderOps.CreateDelegate<T>(CodeContext context, object callable);
                    return new DynamicMetaObject(
                        Ast.Call(null, dc, parameterBinder.ContextExpression, args[0].Expression),
                        target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value))
                    );
                }

                return CallMethod(parameterBinder, CompilerHelpers.GetConstructors(t, PrivateBinding), args, signature);
            }

            return null;
        }
        private DynamicMetaObject/*!*/ MakeSelfCall(DynamicMetaObjectBinder/*!*/ call, Expression/*!*/ codeContext, DynamicMetaObject/*!*/[]/*!*/ args) {
            BindingRestrictions selfRestrict = Restrictions.Merge(
                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(
                    Expression,
                    typeof(BuiltinFunction)
                )
            ).Merge(
                BindingRestrictions.GetExpressionRestriction(
                    Value.MakeBoundFunctionTest(
                        AstUtils.Convert(Expression, typeof(BuiltinFunction))
                    )
                )
            );

            Expression instance = Ast.Property(
                AstUtils.Convert(
                    Expression,
                    typeof(BuiltinFunction)
                ),
                typeof(BuiltinFunction).GetProperty("__self__")
            );

              DynamicMetaObject self = GetInstance(instance, CompilerHelpers.GetType(Value.__self__));
                return Value.MakeBuiltinFunctionCall(
                call,
                codeContext,
                this,
                ArrayUtils.Insert(self, args),
                true,   // has self
                selfRestrict,
                (newArgs) => {
                    CallSignature signature = BindingHelpers.GetCallSignature(call);
                    DynamicMetaObject res;
                    BinderState state = BinderState.GetBinderState(call);
                    BindingTarget target;
                    var mc = new ParameterBinderWithCodeContext(state.Binder, codeContext);
                    if (Value.IsReversedOperator) {
                        res = state.Binder.CallMethod(
                            mc,
                            Value.Targets,
                            newArgs,
                            GetReversedSignature(signature),
                            self.Restrictions,
                            NarrowingLevel.None,
                            Value.IsBinaryOperator ?
                                PythonNarrowing.BinaryOperator :
                                NarrowingLevel.All,
                            Value.Name,
                            out target
                        );
                    } else {
                        res = state.Binder.CallInstanceMethod(
                            mc,
                            Value.Targets,
                            self,
                            args,
                            signature,
                            self.Restrictions,
                            NarrowingLevel.None,
                            Value.IsBinaryOperator ?
                                PythonNarrowing.BinaryOperator :
                                NarrowingLevel.All,
                            Value.Name,
                            out target
                        );
                    }

                    return new BuiltinFunction.BindingResult(target, res);
                }
            );
        }
            public override DynamicMetaObject/*!*/ GetExpression(DefaultBinder/*!*/ binder) {
                var mc = new ParameterBinderWithCodeContext(binder, CodeContext);

                CallSignature sig = Arguments.Signature.InsertArgument(new Argument(ArgumentType.Simple));
                return binder.CallMethod(
                    mc,
                    _ctor.Targets,
                    ArrayUtils.Insert(Arguments.Self, Arguments.Arguments),
                    sig,
                    _creating.Name
                );
            }
            public override DynamicMetaObject/*!*/ GetExpression(DefaultBinder/*!*/ binder) {
                var mc = new ParameterBinderWithCodeContext(binder, CodeContext);

                if (_creating.IsSystemType) {
                    return binder.CallMethod(
                        mc,
                        _creating.UnderlyingSystemType.GetConstructors(),
                        Arguments.Arguments,
                        Arguments.Signature,
                        Arguments.Self.Restrictions,
                        _creating.Name
                    );
                }

                return binder.CallMethod(
                    mc,
                    _creating.UnderlyingSystemType.GetConstructors(),
                    ArrayUtils.Insert(Arguments.Self, Arguments.Arguments),
                    GetDynamicNewSignature(),
                    Arguments.Self.Restrictions,
                    _creating.Name
                );
            }
            public override DynamicMetaObject/*!*/ GetExpression(DefaultBinder/*!*/ binder) {
                var mc = new ParameterBinderWithCodeContext(binder, CodeContext);
                
                if (_creating.IsSystemType) {
                    return binder.CallMethod(
                        mc,
                        _creating.UnderlyingSystemType.GetConstructors(),
                        new DynamicMetaObject[0],
                        new CallSignature(0),
                        BindingRestrictions.Empty,
                        _creating.Name
                    );
                }

                return binder.CallMethod(
                    mc,
                    _creating.UnderlyingSystemType.GetConstructors(),
                    new DynamicMetaObject[] { Arguments.Self },
                    new CallSignature(1),
                    BindingRestrictions.Empty,                    
                    _creating.Name
                );
            }
 internal DynamicMetaObject/*!*/ InvokeFallback(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, CallSignature sig) {
     var parameterBinder = new ParameterBinderWithCodeContext(Binder.Binder, Expression.Constant(_state.Context));
     return PythonProtocol.Call(this, target, args) ??
        Binder.Binder.Create(sig, parameterBinder, target, args) ??
        Binder.Binder.Call(sig, parameterBinder, target, args);
 }
Beispiel #7
0
        /// <summary>
        /// Trys to geta MethodBinder associated the slot for the specified type.
        /// 
        /// If a method is found the binder is set and true is returned.
        /// If nothing is found binder is null and true is returned.
        /// If something other than a method is found false is returned.
        /// 
        /// TODO: Remove rop
        /// </summary>
        internal static bool TryGetBinder(BinderState/*!*/ state, DynamicMetaObject/*!*/[]/*!*/ types, SymbolId op, SymbolId rop, out SlotOrFunction/*!*/ res, out PythonType declaringType) {
            declaringType = null;

            DynamicMetaObject xType = types[0];
            BuiltinFunction xBf;
            if (!BindingHelpers.TryGetStaticFunction(state, op, xType, out xBf)) {
                res = SlotOrFunction.Empty;
                return false;
            }

            xBf = CheckAlwaysNotImplemented(xBf);

            BindingTarget bt;
            DynamicMetaObject binder;
            DynamicMetaObject yType = null;
            BuiltinFunction yBf = null;

            if (types.Length > 1) {
                yType = types[1];
                if (!BindingHelpers.IsSubclassOf(xType, yType) && !BindingHelpers.TryGetStaticFunction(state, rop, yType, out yBf)) {
                    res = SlotOrFunction.Empty;
                    return false;
                }

                yBf = CheckAlwaysNotImplemented(yBf);
            }

            if (yBf == xBf) {
                yBf = null;
            } else if (yBf != null && BindingHelpers.IsSubclassOf(yType, xType)) {
                xBf = null;
            }

            var mc = new ParameterBinderWithCodeContext(state.Binder, AstUtils.Constant(state.Context));

            if (xBf == null) {
                if (yBf == null) {
                    binder = null;
                    bt = null;
                } else {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType);
                    binder = state.Binder.CallMethod(
                        mc,
                        yBf.Targets,
                        types,
                        new CallSignature(types.Length),
                        BindingRestrictions.Empty,
                        PythonNarrowing.None,
                        PythonNarrowing.BinaryOperator,
                        out bt
                    );
                }
            } else {
                if (yBf == null) {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType);
                    binder = state.Binder.CallMethod(
                        mc,
                        xBf.Targets,
                        types,
                        new CallSignature(types.Length),
                        BindingRestrictions.Empty,
                        PythonNarrowing.None,
                        PythonNarrowing.BinaryOperator,
                        out bt
                    );
                } else {
                    List<MethodBase> targets = new List<MethodBase>();
                    targets.AddRange(xBf.Targets);
                    foreach (MethodBase mb in yBf.Targets) {
                        if (!ContainsMethodSignature(targets, mb)) targets.Add(mb);
                    }

                    binder = state.Binder.CallMethod(
                        mc,
                        targets.ToArray(),
                        types,
                        new CallSignature(types.Length),
                        BindingRestrictions.Empty,
                        PythonNarrowing.None,
                        PythonNarrowing.BinaryOperator,
                        out bt
                    );

                    foreach (MethodBase mb in yBf.Targets) {
                        if (bt.Method == mb) {
                            declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType);
                            break;
                        }
                    }

                    if (declaringType == null) {
                        declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType);
                    }
                }
            }

            if (binder != null) {
                res = new SlotOrFunction(bt, binder);
            } else {
                res = SlotOrFunction.Empty;
            }

            Debug.Assert(res != null);
            return true;
        }